From c26778f2d4a95cd2d6d5bb7854904724b649115d Mon Sep 17 00:00:00 2001 From: Edasgh Date: Thu, 7 Nov 2024 22:57:52 +0530 Subject: [PATCH 1/5] "git log error occurred" --- .github/CODEOWNERS | 1 - .github/ISSUE_TEMPLATE/bug.yml | 98 - .github/ISSUE_TEMPLATE/config.yml | 10 - .github/ISSUE_TEMPLATE/custom.yml | 70 - .github/ISSUE_TEMPLATE/documentation.yml | 44 - .github/ISSUE_TEMPLATE/feature.yml | 80 - .github/ISSUE_TEMPLATE/idea.yml | 46 - .github/PULL_REQUEST_TEMPLATE.md | 22 - .github/release-drafter.yml | 19 - .github/workflows/add-contributor.yml | 28 - .github/workflows/autolabel.yml | 38 - .github/workflows/codeql.yml | 81 - .github/workflows/dependency-review.yml | 20 - .github/workflows/deploy.yml | 52 - .github/workflows/issue_close_open.yml | 28 - .github/workflows/lighthouse-report.yml | 68 - .github/workflows/lighthouserc.json | 20 - .github/workflows/pr_merge.yaml | 34 - .github/workflows/pr_raise.yml | 39 - .github/workflows/pr_validation.yml | 91 - .github/workflows/release.yml | 55 - .github/workflows/stale.yml | 23 - .github/workflows/test-deploy.yml | 27 - .gitignore | 20 - CODE_OF_CONDUCT.md | 128 - CONTRIBUTING.md | 153 - LICENSE | 21 - README.md | 1448 - SECURITY.md | 21 - admin/scripts/formatLighthouseReport.js | 88 - admin/scripts/package.json | 13 - babel.config.js | 3 - blog/20-most-important-coding-pattern.md | 423 - blog/Common-Recursion-Patterns.md | 71 - blog/Exploring-Graph-Algorithms.md | 184 - ...tting-started-with-array-data-structure.md | 166 - blog/Kadanes-algorithm.md | 110 - blog/Recursion-vs-Iteration.md | 53 - blog/Understanding-Graph-Representation.md | 214 - ...very-useful-data-structure-linked-lists.md | 98 - blog/a-very-useful-data-structure-string.md | 66 - blog/authors.yml | 114 - ...ry-A-Guide-to-Time-and-Space-Complexity.md | 59 - ...rs-your-path-to-dsa-success-starts-here.md | 58 - blog/mastering-recursion.md | 134 - ...y-to-understanding-algorithm-efficiency.md | 59 - blog/optimizing-recursive-functions.md | 45 - blog/practical-applications-of-recursion.md | 53 - blog/understanding-big-o-notation.md | 51 - blog/understanding-time-space-complexity.md | 80 - docs/Approximation Algorithm/Approximation.md | 164 - docs/Circular_array/Application.md | 208 - docs/Circular_array/Introduction.md | 267 - .../Add_two_number_as_LL.md | 241 - ...inked List with Random and Next Pointer.md | 328 - .../Contains_duplicate.md | 100 - .../Convert Date to Binary.md | 59 - .../Cousins in Binary Tree.md | 193 - .../Delete middle node.md | 300 - .../Delete_occurences_of_key.md | 263 - .../Loop in linked list.md | 265 - .../Merge Two Sorted Arrays.md | 158 - .../Merge_K_Sorted_Arrays.md | 100 - .../DSA-Problem-Solution/Palindrome-number.md | 69 - ...regate even and odd nodes in LinkedList.md | 262 - .../Size_of_largest_BST_in_binary_tree.md | 103 - .../Sliding Window Maximum.md | 86 - docs/DSA-Problem-Solution/Symmetric Tree.md | 158 - .../flattening-a-linked-list.md | 189 - docs/DSA-Problem-Solution/house-robber.md | 63 - ...t_substring_without_repeated_characters.md | 54 - docs/DSA-Problem-Solution/merge_intervals.md | 56 - .../odd-even-linked-list.md | 63 - .../palindrome_linked_list.md | 65 - .../partition_equal_subset_sum.md | 63 - .../removing-stars-from-string.md | 51 - docs/DSA-Problem-Solution/reverse-bits.md | 91 - .../reverse-linked-list.md | 119 - docs/DSA-Problem-Solution/two_sum.md | 45 - docs/Depth_first_traversal.md | 101 - docs/Divide and Conquer/Maximum-minimum.md | 125 - .../Strassen's-Matrix-Mutiplication.md | 111 - docs/Fenwick Tree /FenwickTree.md | 111 - docs/Hashing/CollisionHandling.md | 124 - docs/Hashing/OperationInsertion.md | 43 - docs/Hashing/OperationSearch.md | 62 - docs/Hashing/OperationUpdate.md | 62 - docs/Hashing/Tigerhashing.md | 38 - docs/Hashing/_category_.json | 8 - docs/Hashing/deletion-in-hash-table.md | 190 - docs/Hashing/hashsets.md | 322 - docs/Hashing/imp-of-hashing.md | 65 - docs/Hashing/what-is-hashing.md | 364 - docs/Jump Search/Jump Search.md | 77 - docs/KMP searching pattern/_category_.json | 8 - docs/KMP searching pattern/readme.md | 354 - docs/Number theory/GCD.md | 212 - docs/Number theory/LCM.md | 224 - docs/Number theory/sieve-of-eratosthenes.md | 216 - .../4-pillars-of-oops.md | 355 - .../ApplicationofOOPS.md | 156 - .../Polymorphism.md | 625 - .../_category_.json | 8 - .../abstraction.md | 399 - docs/Object Oriented Programming/car.png | Bin 27324 -> 0 bytes .../classes-and-objects.md | 116 - .../constructors-destructors.md | 184 - .../interfaces-vs-abstract-classes.md | 163 - .../intro-to-oops.md | 48 - docs/Object Oriented Programming/intro.png | Bin 174906 -> 0 bytes .../real-world-examples.md | 299 - .../typesOfInheritance.md | 118 - docs/Queue/Blocked-queue.png | Bin 21608 -> 0 bytes docs/Queue/Circular-queue.png | Bin 6430 -> 0 bytes docs/Queue/Priority-queue.png | Bin 83594 -> 0 bytes docs/Queue/Problem-Practice.md | 63 - docs/Queue/Two-Stack-Queue.md | 203 - docs/Queue/_category_.json | 8 - docs/Queue/blocked-queue.md | 343 - docs/Queue/check-palindrome-using-dequeue.md | 82 - docs/Queue/circular-queue.md | 397 - docs/Queue/concurrent-queue.md | 103 - docs/Queue/design-circular-Dueque.md | 143 - docs/Queue/design-circular-Queue.md | 113 - docs/Queue/double-ended-queue.md | 387 - docs/Queue/doubleendedqueue.png | Bin 15194 -> 0 bytes docs/Queue/priority-queue.md | 343 - docs/Queue/priority_queue_questions.md | 225 - .../Randomized-Quicksort.md | 104 - docs/Recursion-depths/Recursion.md | 71 - docs/Recursion-depths/advanced-topics.md | 130 - docs/Recursion-depths/basic-concepts.md | 47 - .../Recursion-depths/handling-depth-errors.md | 60 - .../performance-consideration.md | 21 - docs/Recursion/Ackerman.md | 181 - .../Count-all-subsequences-with-sum-K.md | 55 - docs/Recursion/GrayCodeGeneration.md | 95 - docs/Recursion/Josephus-Queries.md | 177 - docs/Recursion/Knight's_Tour_Problem.md | 192 - .../Letter-Combinations-of-a-Phone-number.md | 72 - docs/Recursion/N Queen 2.png | Bin 70847 -> 0 bytes docs/Recursion/N Qween 1.png | Bin 69756 -> 0 bytes docs/Recursion/Reversing_String.md | 82 - docs/Recursion/SmawkAlgorithm.md | 214 - docs/Recursion/Sodoko.md | 91 - docs/Recursion/StonePaperScissor.md | 188 - docs/Recursion/TowersOfHanoi.md | 64 - docs/Recursion/Unwinding_in_recursion.md | 140 - docs/Recursion/VoseAlias.md | 252 - docs/Recursion/WaterJug.md | 227 - docs/Recursion/_category_.json | 8 - docs/Recursion/catalannumber.md | 95 - docs/Recursion/fibonacci.md | 124 - docs/Recursion/generate-parantheses.md | 68 - docs/Recursion/josephus.md | 48 - docs/Recursion/look-and-say.md | 95 - docs/Recursion/n-queen.md | 92 - docs/Recursion/recursion.md | 106 - docs/Recursion/ulamsequence.md | 120 - docs/Segment-Trees/Dynamic Segment Trees.md | 169 - docs/Segment-Trees/Practice Porblem.md | 68 - .../Segment Trees Introduction.md | 157 - docs/Segment-Trees/Segment-Tree-img.png | Bin 191675 -> 0 bytes .../IntroductionToSlidingWindow.jpg | Bin 50651 -> 0 bytes docs/Sliding-Window/Problem-Practice.md | 42 - docs/Sliding-Window/_category_.json | 8 - docs/Sliding-Window/character-replacement.md | 120 - .../introduction-to-sliding-window.md | 164 - ...longest-repeating-character-replacement.md | 155 - ...t-substring-with-K-different-characters.md | 185 - .../maximum-sum-subarray-size-K.md | 162 - .../minimize-maximum-of-two-arrays.md | 204 - docs/Stack/Balanced-Parenthesis.md | 106 - docs/Stack/Balanced-parentheses-checker.md | 103 - docs/Stack/Conversion.md | 328 - docs/Stack/Evaluation.md | 91 - docs/Stack/Introduction_to_Stack.png | Bin 50019 -> 0 bytes docs/Stack/Min-Stack.md | 186 - docs/Stack/MonotonicStack.md | 97 - docs/Stack/Next Greater Element (NGE).md | 90 - docs/Stack/Problem-Practice.md | 62 - docs/Stack/Reverse-Stack.md | 123 - docs/Stack/Stack-permutation.md | 133 - docs/Stack/Stock-span.md | 117 - docs/Stack/String_Reversal.md | 71 - docs/Stack/Trapping Rain Water Problem.md | 70 - docs/Stack/_category_.json | 8 - docs/Stack/introduction-to-stack.md | 311 - docs/Stack/stack.md | 134 - .../STL-algorithms.md | 190 - .../STL-containers.md | 258 - .../STL-iterators.md | 104 - docs/Standard Template Library/STL-theory.md | 121 - docs/Strings/Problem-Practice.md | 40 - docs/Tarjan's Algorithm/Tarjan.md | 159 - docs/Tarjan's Algorithm/algorithm.png | Bin 105711 -> 0 bytes docs/Task Scheduling/Task-schedule.md | 133 - docs/Task Scheduling/_category_.json | 8 - docs/Trees/AVL Tree.md | 98 - docs/Trees/B-Trees.md | 268 - docs/Trees/Expression-tree.md | 133 - docs/Trees/Heap-tree.md | 127 - docs/Trees/Practice Problems.md | 48 - docs/Trees/Sum-tree.md | 100 - docs/Trees/Trees Practice Problems.md | 48 - docs/Trees/Types of Trees.md | 43 - docs/Trees/balanced-tree.md | 183 - docs/Trees/binary-search-tree.md | 155 - docs/Trees/binary-tree.md | 121 - docs/Trees/k-d tree algorithm.md | 193 - docs/Trees/tree-data-structure.md | 172 - docs/Tries/Problem-Practice.md | 22 - docs/Tries/Tries and its Implementation.md | 174 - docs/Tries/tries-examples.md | 207 - docs/Tries/tries-theory.md | 138 - docs/advance-data-structure/_category_.json | 8 - docs/advance-data-structure/disjoint-set.md | 165 - docs/advance-data-structure/fenwick-tree.md | 134 - docs/advance-data-structure/segment-tree.md | 224 - .../ edmonds-karp-algorithm.md | 203 - docs/algorithms/Application-of-Recursion.md | 56 - docs/algorithms/Application-of-linked-list.md | 58 - .../bentley-ottmann-algo.md | 186 - .../algorithms/CNN-deep-learning-algorithm.md | 91 - .../Dijkstra\342\200\231s Algorithm.md" | 143 - .../DutchNationalFlag.md | 98 - .../_category_.json | 8 - .../Encryption algorithms/Caesar Cipher.md | 83 - .../advanced_encryption_standard.md | 98 - .../asymmetric_encryption.md | 78 - .../blockchain_encryption.md | 99 - .../elliptic_curve_cryptography.md | 83 - .../Encryption algorithms/hashing.md | 87 - .../homomorphic-encryption.md | 142 - .../post-quantum-encryption.md | 100 - .../steganography-algo.md | 107 - .../symmetric_encryption.md | 81 - .../Gale-Shapley-Algorithm/GaleShapley.md | 177 - docs/algorithms/Hashing-algorithm.md | 70 - .../N-Queens-Dynamic-programming-algorithm.md | 83 - .../EarliestDeadlineFirst.md | 126 - .../FirstComeFirstServed.md | 134 - .../LeastRecentlyUsed.md | 100 - .../PriorityScheduling.md | 132 - .../Scheduling Algorithms/RoundRobin.md | 141 - .../ShortestJobRemainingFirst.md | 157 - .../Scheduling Algorithms/SweepLine.md | 96 - .../Scheduling Algorithms/_category_.json | 8 - .../least-recently-used.md | 173 - .../multilevel-queue-scheduling.md | 188 - .../priority-scheduling.md | 189 - .../Searching Algorithms/A*-Search.md | 103 - .../Searching Algorithms/AO*-Search.md | 82 - .../Searching Algorithms/Best-First-Search.md | 115 - .../Searching Algorithms/BinarySearch.md | 248 - .../Boyer-Moore-Search.md | 79 - .../Breadth-First-Search-(BFS)-Algo.md | 141 - .../Searching Algorithms/ComparisonSearch.md | 218 - .../Depth-First-Search-(DFS)-Algo.md | 143 - .../Searching Algorithms/DigitalSearch.md | 235 - .../Searching Algorithms/ExponentialSerach.md | 112 - .../Searching Algorithms/FibbonaciSearch.md | 198 - .../Searching Algorithms/HashingSearch.md | 161 - .../Interpolation-search-algorithm.md | 120 - .../InterpolationSearch.md | 193 - .../Searching Algorithms/JumpSearch.md | 106 - .../Searching Algorithms/LinearSearch.md | 226 - .../Meta-binary-search.md | 292 - .../Rabin-Karp-Algorithm.md | 131 - .../Searching Algorithms/SentinelSearch.md | 124 - .../Searching Algorithms/Sublist-Search.md | 78 - .../Searching Algorithms/TernarySearch.md | 121 - .../Uniform-Cost-Search.md | 85 - .../IntroductionToTwoPointers.png | Bin 357058 -> 0 bytes docs/algorithms/Two-Pointers/Max_Distance.md | 82 - .../Two-Pointers/Problem-Practice.md | 35 - docs/algorithms/Two-Pointers/_category_.json | 8 - .../Two-Pointers/imp-of-two-pointers.md | 66 - .../introduction-to-two-pointers.md | 91 - .../Yolo-Object-detection-ML-Algorithm.md | 87 - docs/algorithms/_category_.json | 8 - .../Bron-Kerbosch-Algorithm.md | 163 - .../backtracking-algorithms/_category_.json | 8 - .../backtracking-questions.md | 478 - .../hamilton-path-cyle.md | 122 - .../imp-of-backtracking.md | 22 - .../backtracking-algorithms/m-coloring.md | 184 - .../what-is-backtracking.md | 299 - .../greedy-algorithms/Fractional_Knapsack.md | 104 - .../greedy-algorithms/Huffman-coding.md | 139 - .../Job-sequencing-problem.md | 130 - ...rim\342\200\231s-Minimum-Spanning-Tree.md" | 149 - .../greedy-algorithms/Problem-Practice.md | 94 - .../greedy-algorithms/_category_.json | 8 - .../greedy-algorithms/activity-selection.md | 104 - .../commonly-asked-greedy-questions.md | 164 - .../greedy-algorithms/fractional-knapsack.md | 179 - .../greedy-algorithms/greedy-theory.md | 62 - .../kadane-algorithm/_category_.json | 8 - .../kadane-algorithm/kadane-algo.md | 86 - .../mathematics-algorithms/_category_.json | 8 - .../discrete-logarithm.md | 136 - .../euclidean-algorithm.md | 102 - .../fermat-little-theorem.md | 173 - .../mathematics-algorithms/gcd-lcm.md | 128 - .../imp-of-mathematics.md | 57 - .../modular-arithmetic.md | 149 - .../sieve-of-eratosthenes.md | 148 - .../sweep-line-algorithm.md | 265 - .../what-is-mathematical-algorithms.md | 168 - .../memoisation-algorithms/_category_.json | 8 - .../imp-of-memoisation.md | 76 - .../what-is-memoisation.md | 201 - .../modular-exponentiation-algorithm.md | 82 - .../moore-voting-algo.md | 117 - .../recursive-algorithms/DirectRecursion.md | 168 - .../recursive-algorithms/IndirectRecursion.md | 184 - .../recursive-algorithms/_category_.json | 8 - .../recursive-algorithms/mutual-recursion.md | 164 - .../non-tail-recursion.md | 134 - .../recursive-algorithms/tail-recursion.md | 127 - .../recursive-algorithms/tree-recursion.md | 154 - .../sorting-algorithms/BitonicSort.md | 75 - .../algorithms/sorting-algorithms/BogoSort.md | 99 - .../sorting-algorithms/BubbleSort.md | 129 - .../sorting-algorithms/BucketSort.md | 95 - .../sorting-algorithms/CocktailShakerSort.md | 98 - .../algorithms/sorting-algorithms/CombSort.md | 107 - .../sorting-algorithms/CountingSort.md | 106 - .../sorting-algorithms/CycleSort.md | 131 - .../sorting-algorithms/Dutch-flag-algo.md | 113 - .../sorting-algorithms/GnomeSort.md | 75 - .../algorithms/sorting-algorithms/HeapSort.md | 112 - .../sorting-algorithms/InsertionSort.md | 127 - .../algorithms/sorting-algorithms/JumpSort.md | 80 - .../sorting-algorithms/MergeSort.md | 199 - .../sorting-algorithms/Odd-Even-Sort.md | 89 - .../sorting-algorithms/OddEvenSort.md | 99 - .../Pancake-sorting-algorithm.md | 83 - .../sorting-algorithms/Pigeonhole.md | 91 - .../sorting-algorithms/QuickSort.md | 161 - .../sorting-algorithms/RadixSort.md | 120 - .../sorting-algorithms/SelectionSort.md | 136 - .../sorting-algorithms/ShellSort.md | 102 - .../sorting-algorithms/StoogeSort.md | 67 - docs/algorithms/sorting-algorithms/TimSort.md | 158 - .../Topological-sorting-algorithm.md | 94 - .../algorithms/sorting-algorithms/TreeSort.md | 106 - .../sorting-algorithms/_category_.json | 8 - .../sorting-algorithms/odd-even-sorting.md | 117 - .../parity-partition-sort.md | 65 - .../sorting-algorithms/strand-sort.md | 375 - .../string-algorithm/Boyer-moore-algorithm.md | 107 - .../string-algorithm/Naive-search.md | 145 - .../string-algorithm/Suffix-Tree-Algorithm.md | 108 - .../string-algorithm/Z-Algorithm.md | 171 - .../aho-corasick-algorithm.md | 259 - .../string-algorithm/kmp-algorithm.md | 328 - .../string-algorithm/rabin-karp-algorithm.md | 140 - .../Naive-String-Matching-Algorithm.md | 72 - .../string-algorithms/_category_.json | 8 - .../apostolico-giancarlo-algorithm.md | 100 - .../berry-ravindran-algorithm.md | 276 - .../string-algorithms/bitap-algorithm.md | 108 - .../string-algorithms/bndm-algorithm.md | 108 - .../boyer-moore-algorithm.md | 290 - .../string-algorithms/colussi-algorithm.md | 357 - .../commentz-walter-algorithm.md | 121 - .../crochemores-algorithm.md | 284 - .../finite-state-automation-algorithm.md | 148 - .../string-algorithms/kmp-algorithm.md | 400 - .../string-algorithms/lcs-algorithm.md | 330 - .../levenshtein-distance-algorithm.md | 372 - .../string-algorithms/manacher-algorithm.md | 283 - .../needleman-wunsch-algorithm.md | 319 - .../not-so-naive-algorithm.md | 317 - .../optimal-mismatch-algorithm.md | 337 - .../quick-search-algorithm.md | 313 - .../string-algorithms/rabin-karp-algorithm.md | 276 - .../reverse-factor-algorithm.md | 345 - .../string-algorithms/shift-or-algorithm.md | 100 - .../string-algorithms/simon-algorithm.md | 302 - .../smith-waterman-algorithm.md | 322 - .../suffix-array-algorithm.md | 349 - .../string-algorithms/sunday-algorithm.md | 245 - .../turbo-boyer-moore-algorithm.md | 313 - .../two-way-string-matching-algorithm.md | 242 - .../string-algorithms/ukkonens-algorithm.md | 266 - .../zhu-takaoka-algorithm.md | 293 - docs/b-tree/B-Tree-1.md | 437 - docs/b-tree/B-Tree-2.md | 542 - docs/b-tree/B-Tree-3.md | 864 - docs/b-tree/B-tree Practice Problems.md | 100 - docs/b-tree/image/BTree2Ins.png | Bin 3721 -> 0 bytes docs/b-tree/image/BTreeIns3.png | Bin 10480 -> 0 bytes docs/b-tree/image/BTreeIns4.png | Bin 6671 -> 0 bytes docs/b-tree/image/BTreeIns6.png | Bin 6722 -> 0 bytes docs/b-tree/image/BTreeSplit-1024x321.jpg | Bin 49605 -> 0 bytes docs/b-tree/image/Btree1.png | Bin 2049 -> 0 bytes docs/b-tree/image/delete.png | Bin 39552 -> 0 bytes docs/b-tree/image/delete2.png | Bin 43420 -> 0 bytes docs/b-tree/image/output253.png | Bin 30584 -> 0 bytes docs/b-tree/image/output254.png | Bin 39848 -> 0 bytes docs/b-tree/image/output255.png | Bin 60571 -> 0 bytes docs/b-tree/image/output256.png | Bin 67408 -> 0 bytes .../N-QueensProblem.md | 149 - .../n-queens_algorithm.md | 119 - docs/balancedBinTree/balancedBinTree.md | 62 - docs/balancedBinTree/balancedBinTreejava.md | 101 - .../balancedBinTreejavaScript.md | 103 - docs/basic-dsa/Method Overriding.md | 80 - docs/basic-dsa/Operator Overloading.md | 96 - docs/basic-dsa/Strings/Advanced-techniques.md | 105 - .../Strings/Highest freqyuency letter.md | 169 - docs/basic-dsa/Strings/Isomorphic strings.md | 198 - docs/basic-dsa/Strings/Reversing a string.md | 152 - docs/basic-dsa/Strings/What_is String.md | 138 - docs/basic-dsa/Strings/kmp-algo.md | 136 - docs/basic-dsa/_category_.json | 8 - docs/basic-dsa/array/2d-arrays.md | 175 - docs/basic-dsa/array/Kadane-Algorithm.md | 154 - .../array/ProudctOfArrayExceptSelf.md | 287 - docs/basic-dsa/array/_category_.json | 8 - docs/basic-dsa/array/arrays-bubblesort-dsa.md | 201 - docs/basic-dsa/array/arrays-dsa.md | 543 - docs/basic-dsa/array/arrays-insertionsort.md | 166 - .../array/arrays-kadanesalgorithm-dsa.md | 66 - docs/basic-dsa/array/arrays-selectionsort.md | 152 - docs/basic-dsa/array/bucket-sort.md | 263 - docs/basic-dsa/array/counting-sort.md | 114 - docs/basic-dsa/array/heap-sort.md | 191 - docs/basic-dsa/array/quick-sort.md | 138 - docs/basic-dsa/array/radix-sort.md | 330 - docs/basic-dsa/matrix-data-structure.md | 80 - docs/basic-dsa/pointer.md | 198 - docs/binary-search-tree/Binary search tree.md | 233 - .../Post_order_traversal.md | 80 - docs/binary-search-tree/Problem-Practice.md | 94 - docs/binary-search-tree/_category_.json | 8 - docs/binary-search-tree/avl-tree.md | 172 - docs/binary-search-tree/delete-BST.md | 200 - .../inorder-predecessor-BST.md | 99 - .../inorder-successor-BST.md | 100 - docs/binary-search-tree/insert-BST.md | 76 - docs/binary-search-tree/red-black-trees.md | 157 - docs/binary-search-tree/search-BST.md | 132 - docs/binary-search/Exponential-Search.md | 72 - docs/binary-search/Iterative_binary_search.md | 134 - .../Painter_Partition_problem.md | 103 - docs/binary-search/Problem-Practice.md | 43 - docs/binary-search/_category_.json | 8 - docs/binary-search/binary-search.md | 100 - .../binary-search_rotated-sorted-array.md | 323 - docs/binary-search/binary.md | 109 - docs/binary-search/binary_search_questions.md | 133 - docs/binary-search/matrix-binary-dsa.md | 127 - docs/binary-search/recursive_binary_search.md | 126 - docs/binary-trees/_category_.json | 8 - docs/binary-trees/basic-operations.md | 230 - docs/binary-trees/binary-tree.md | 154 - docs/binary-trees/expression-tree.md | 136 - docs/binary-trees/maximum-depth.md | 102 - docs/binary-trees/merkle-tree.md | 111 - docs/binary-trees/minimum-depth.md | 97 - docs/binary-trees/practice-problems.md | 45 - docs/binary-trees/splay-trees.md | 155 - docs/bit-manipulation/_category_.json | 8 - .../bit-manipulation-technique.md | 177 - .../bitmanipulation-practice-problem.md | 58 - docs/bit-manipulation/brain-kernighan-algo.md | 76 - docs/bit-manipulation/clear-ith-Bit.md | 56 - docs/challenges solutions/Challenge4.md | 325 - docs/challenges solutions/_category_.json | 8 - docs/challenges solutions/challenge1.md | 320 - docs/challenges solutions/challenge2.md | 324 - docs/challenges solutions/challenge3.md | 342 - docs/combinatorics/Practice-problems.md | 160 - docs/combinatorics/_category_.json | 8 - docs/combinatorics/combinatorics-examples.md | 123 - docs/combinatorics/combinatorics-theory.md | 112 - docs/complexity/_category_.json | 8 - .../complexity/how-to-calculate-complexity.md | 70 - docs/complexity/image-1.png | Bin 12924 -> 0 bytes docs/complexity/image.png | Bin 6623 -> 0 bytes docs/complexity/space-complexity.md | 218 - docs/complexity/time-complexity.md | 314 - docs/complexity/time-space-complexity.md | 57 - docs/content.md | 135 - docs/dsa/_category_.json | 8 - docs/dsa/imp-of-dsa.md | 56 - docs/dsa/roadmap-to-dsa.md | 115 - docs/dsa/types-of-dsa.md | 140 - docs/dsa/what-is-dsa.md | 100 - .../dynamic-programming/Beautiful-Subgrids.md | 232 - .../Matrix-chain-multiplication.md | 64 - docs/dynamic-programming/Multistage-graph.md | 121 - .../Two-City-Scheduling-3D-DP.md | 313 - docs/dynamic-programming/_category_.json | 8 - docs/dynamic-programming/approaches.md | 29 - .../dynamic-programming-optimizations.md | 65 - docs/dynamic-programming/fence-painting.md | 81 - docs/dynamic-programming/house-robber.md | 122 - docs/dynamic-programming/how-to-identify.md | 17 - .../longest-zig-zag-subsequence.md | 104 - .../longest_common_subsequence.md | 128 - .../minimum_flips_to_zero_matrix.md | 61 - .../palindrome_partitioning_IV.md | 74 - .../practice-problems-different-patterns.md | 61 - docs/dynamic-programming/trapped-rainwater.md | 87 - docs/fundamentals/Conditional Statement.md | 156 - docs/fundamentals/Functions/Function Call.md | 69 - .../Functions/Function Closures.md | 91 - .../Functions/Function Composition.md | 102 - .../Functions/Function Currying.md | 77 - .../Functions/Function Declaration.md | 62 - .../Functions/Function Memoization.md | 98 - .../Functions/Function Overloading.md | 87 - .../Functions/Function Parameters.md | 67 - .../Functions/Function Recursion.md | 83 - .../fundamentals/Functions/Function Return.md | 69 - docs/fundamentals/Functions/Function Scope.md | 74 - docs/fundamentals/Loops.md | 215 - docs/game-Theory/gameTheory.md | 75 - docs/game-Theory/gameTheoryExamples.md | 104 - docs/graphs/Adjacency-Matrix.md | 118 - docs/graphs/Disjoint Set Union.md | 169 - docs/graphs/Longest-path-in-DAG.md | 163 - docs/graphs/Page-Rank-Algorithm.md | 107 - docs/graphs/Practice Problems.md | 40 - docs/graphs/_category_.json | 8 - docs/graphs/ant-colony-optimization-tsp.md | 172 - docs/graphs/bfs.md | 133 - docs/graphs/bipartite-graph.md | 139 - docs/graphs/dfs.md | 70 - docs/graphs/dfs_java.md | 80 - docs/graphs/eulerian-graphs.md | 218 - docs/graphs/flood-fill.md | 172 - docs/graphs/floyd-algorithm.md | 65 - docs/graphs/graph-cloning.md | 152 - docs/graphs/graph-coloring.md | 114 - docs/graphs/graph-reversal.md | 113 - docs/graphs/hopcroft-karp-algorithm.md | 159 - docs/graphs/kahn-algo.md | 137 - docs/graphs/kosaraju-algorithm.md | 140 - docs/graphs/kruskal-algorithm.md | 108 - docs/graphs/minimum-cost-spanning-tree.md | 244 - docs/graphs/practice-problems.md | 73 - docs/graphs/prims-algorithm.md | 109 - .../A-star-algorithm.md | 152 - .../Prims-algorithm.md | 148 - .../shortest-path-algorithms/_category_.json | 8 - .../bell-man-ford-algorithm.md | 167 - .../dijkstra-algorithm.md | 136 - .../floyd-warshall-algorithm.md | 117 - docs/graphs/tarjans-algo.md | 165 - docs/graphs/warshall-algo.md | 61 - docs/greedy-algorithms/Graph-Coloring.md | 228 - docs/greedy-algorithms/job-scheduling.md | 137 - docs/hash/Practice Problems.md | 40 - docs/hash/_category_.json | 8 - docs/hash/hash-tables.md | 127 - docs/heap/Kth-largest-using-min_heap.md | 149 - docs/heap/Problem-Practice.md | 31 - docs/heap/_category_.json | 8 - docs/heap/heap-basics.md | 184 - docs/heap/heap-operations.md | 185 - docs/heap/kth-largest.md | 73 - docs/heap/kth-smallest.md | 58 - docs/heap/time-complexity.md | 211 - docs/index.md | 43 - .../knapsack-disaster-relief.md | 154 - docs/languages/C/c-0.md | 74 - docs/languages/C/c-1.md | 152 - docs/languages/C/c-2.md | 186 - docs/languages/C/c-3.md | 194 - docs/languages/C/c-4.md | 229 - docs/languages/SQL/sql-1.md | 72 - docs/languages/SQL/sql-10.md | 121 - docs/languages/SQL/sql-11.md | 134 - docs/languages/SQL/sql-12.md | 169 - docs/languages/SQL/sql-13.md | 140 - docs/languages/SQL/sql-14.md | 169 - docs/languages/SQL/sql-15.md | 104 - docs/languages/SQL/sql-16.md | 96 - docs/languages/SQL/sql-17.md | 84 - docs/languages/SQL/sql-18.md | 70 - docs/languages/SQL/sql-19.md | 61 - docs/languages/SQL/sql-2.md | 66 - docs/languages/SQL/sql-20.md | 54 - docs/languages/SQL/sql-21.md | 56 - docs/languages/SQL/sql-22.md | 65 - docs/languages/SQL/sql-23.md | 61 - docs/languages/SQL/sql-24.md | 147 - docs/languages/SQL/sql-25.md | 87 - docs/languages/SQL/sql-3.md | 92 - docs/languages/SQL/sql-4.md | 89 - docs/languages/SQL/sql-5.md | 106 - docs/languages/SQL/sql-6.md | 96 - docs/languages/SQL/sql-7.md | 89 - docs/languages/SQL/sql-8.md | 102 - docs/languages/SQL/sql-9.md | 114 - docs/languages/_category_.json | 8 - docs/languages/cpp/_category_.json | 8 - docs/languages/cpp/cp-0.md | 74 - docs/languages/cpp/cp-1.md | 125 - docs/languages/cpp/cp-10.md | 269 - docs/languages/cpp/cp-11.md | 253 - docs/languages/cpp/cp-12.md | 186 - docs/languages/cpp/cp-13.md | 331 - docs/languages/cpp/cp-2.md | 160 - docs/languages/cpp/cp-3.md | 145 - docs/languages/cpp/cp-4.md | 228 - docs/languages/cpp/cp-5.md | 180 - docs/languages/cpp/cp-6.md | 336 - docs/languages/cpp/cp-7.md | 188 - docs/languages/cpp/cp-8.md | 446 - docs/languages/cpp/cp-9.md | 213 - docs/languages/csharp/_category_.json | 8 - docs/languages/csharp/csharp-0.md | 72 - docs/languages/csharp/csharp-1.md | 81 - docs/languages/csharp/csharp-2.md | 153 - docs/languages/csharp/csharp-3.md | 163 - docs/languages/csharp/csharp-4.md | 145 - docs/languages/csharp/csharp-5.md | 141 - docs/languages/csharp/csharp-6.md | 151 - docs/languages/csharp/csharp-7.md | 160 - docs/languages/csharp/csharp-8.md | 155 - docs/languages/csharp/csharp-9.md | 178 - docs/languages/java/_category_.json | 8 - docs/languages/java/ex1.md | 106 - docs/languages/java/ex2.md | 200 - docs/languages/java/ex4.md | 225 - docs/languages/java/java-1.md | 142 - docs/languages/java/java-10.md | 110 - docs/languages/java/java-2.md | 148 - docs/languages/java/java-3.md | 133 - docs/languages/java/java-4.md | 199 - docs/languages/java/java-5-1.md | 320 - docs/languages/java/java-6.md | 44 - docs/languages/java/java-7.md | 61 - docs/languages/java/java-8.md | 303 - docs/languages/java/java-9.md | 227 - docs/languages/javascript/_category_.json | 8 - docs/languages/javascript/js-0.md | 117 - docs/languages/javascript/js-1.md | 205 - docs/languages/javascript/js-10.md | 243 - docs/languages/javascript/js-11.md | 82 - docs/languages/javascript/js-12.md | 261 - docs/languages/javascript/js-13.md | 171 - docs/languages/javascript/js-14.md | 195 - docs/languages/javascript/js-15.md | 195 - docs/languages/javascript/js-16.md | 182 - docs/languages/javascript/js-17.md | 233 - docs/languages/javascript/js-2.md | 150 - docs/languages/javascript/js-3.md | 344 - docs/languages/javascript/js-4.md | 87 - docs/languages/javascript/js-5.md | 127 - docs/languages/javascript/js-6.md | 100 - docs/languages/javascript/js-7.md | 141 - docs/languages/javascript/js-8.md | 103 - docs/languages/javascript/js-9.md | 83 - docs/languages/python/_category_.json | 8 - docs/languages/python/py-1.md | 179 - docs/languages/python/py-10.md | 86 - docs/languages/python/py-11.md | 96 - docs/languages/python/py-12.md | 75 - docs/languages/python/py-13.md | 89 - docs/languages/python/py-14.md | 77 - docs/languages/python/py-15.md | 119 - docs/languages/python/py-16.md | 79 - docs/languages/python/py-17.md | 122 - docs/languages/python/py-18.md | 184 - docs/languages/python/py-2.md | 141 - docs/languages/python/py-3.md | 80 - docs/languages/python/py-4.md | 82 - docs/languages/python/py-5.md | 66 - docs/languages/python/py-6.md | 66 - docs/languages/python/py-7.md | 102 - docs/languages/python/py-8.md | 86 - docs/languages/python/py-9.md | 88 - docs/linked-list/CircularDoubly.png | Bin 3213 -> 0 bytes docs/linked-list/CircularLinkedList.png | Bin 230132 -> 0 bytes docs/linked-list/Doubly-linked-list-C.md | 215 - docs/linked-list/DoublyLL.png | Bin 199538 -> 0 bytes docs/linked-list/Hare-Tortoise.md | 174 - .../Intersection_Linked_list_python.md | 97 - docs/linked-list/LinkedList.png | Bin 53702 -> 0 bytes docs/linked-list/Polynomial-Addition.md | 181 - docs/linked-list/Practice-Problems.md | 58 - docs/linked-list/_category_.json | 8 - .../circular-doubly-linked-list.md | 516 - docs/linked-list/doubly-linked-list.md | 410 - docs/linked-list/floyds-cycle-detection.md | 105 - docs/linked-list/gircular-linked-list.md | 640 - docs/linked-list/intersection-linked-lists.md | 168 - .../introduction-to-linked-list.md | 456 - docs/linked-list/linked-list-approaches.md | 113 - docs/linked-list/merge-two-sorted-list.md | 82 - docs/linked-list/range-sum-of-linked-list.md | 78 - .../remove-duplicates-from-sorted-list.md | 120 - docs/machine-learning/AdaBoost.md | 136 - docs/machine-learning/Autoencoders.md | 180 - docs/machine-learning/BeamSearch.md | 128 - .../Convolutional_Neural_Network.md | 176 - .../DBSCAN_Clustering_Algorithm.md | 162 - docs/machine-learning/Extra_Trees.md | 129 - docs/machine-learning/GBM.md | 174 - .../Gaussian_Mixture_Model.md | 154 - .../Generative_Adversarial_Networks.md | 173 - docs/machine-learning/HBOS.md | 95 - docs/machine-learning/Hidden_Markov_Model.md | 142 - .../machine-learning/HierarchialClustering.md | 153 - .../Independent Component Analysis.md | 128 - docs/machine-learning/K-Means_clustering.md | 133 - docs/machine-learning/K-NearestNeighbours.md | 208 - docs/machine-learning/LinearRegression.md | 167 - docs/machine-learning/LogisticRegression.md | 159 - .../Long_Short_Term_Memory.md | 162 - docs/machine-learning/PC_Visualizations.md | 145 - .../Recurrent_Neural_Network.md | 174 - .../Reinforcement_Learning.md | 150 - docs/machine-learning/RidgeRegression.md | 86 - docs/machine-learning/SDG.md | 86 - docs/machine-learning/SVM.md | 167 - .../Singular_Value_Decomposition_Algorithm.md | 129 - .../Statistical_Anomaly_Detection.md | 184 - .../Time_Series_Forecasting_Algo.md | 199 - docs/machine-learning/XGBoost.md | 102 - docs/machine-learning/decisionTree.md | 135 - .../hierarchical-clustering-visualizations.md | 129 - docs/machine-learning/naive-bayes.md | 176 - docs/machine-learning/neuralNetworks.md | 178 - docs/machine-learning/random-forest.md | 131 - docs/machine-learning/regression_algorithm.md | 177 - .../supervised_learning_algo.md | 164 - .../support-vector-machine.md | 126 - .../t-SNE_Dimensionality_Reduction.md | 154 - .../unsupervised_learning_algo.md | 163 - docs/programming-fundamentals/Arrays.md | 147 - docs/programming-fundamentals/Conditionals.md | 146 - .../Data_Structures.md | 155 - docs/programming-fundamentals/Loops.md | 117 - docs/programming-fundamentals/OOPS/oops-01.md | 47 - docs/programming-fundamentals/OOPS/oops-02.md | 161 - docs/programming-fundamentals/OOPS/oops-03.md | 255 - docs/programming-fundamentals/OOPS/oops-04.md | 225 - docs/programming-fundamentals/OOPS/oops-05.md | 486 - docs/programming-fundamentals/OOPS/oops-06.md | 87 - docs/programming-fundamentals/OOPS/oops-07.md | 83 - docs/programming-fundamentals/OOPS/oops-08.md | 79 - docs/programming-fundamentals/Variables.md | 149 - docs/programming-fundamentals/_category_.json | 8 - docs/programming-fundamentals/functions.md | 116 - docs/sortings/Sortings.md | 683 - docusaurus.config.js | 230 - festhack.jpg | Bin 194570 -> 0 bytes girlscript.jpg | Bin 16124 -> 0 bytes java/Armstrong-Number-Checker.md | 61 - java/Arrays/1.Easy/Find missing number.md | 98 - .../Remove Duplicates from Sorted Array.md | 96 - java/Arrays/2.Medium/Kadane's Algorithm.md | 104 - .../2.Medium/Longest Subarray with sum K.md | 122 - .../Arrays/3.Hard/Maximum Product Subarray.md | 85 - java/Arrays/3.Hard/Reverse pairs.md | 139 - java/LCM-GCD-Calculator.md | 72 - java/Palindrome_number.md | 80 - java/Palindrome_string.md | 75 - java/Prime_number_checker.md | 65 - java/Reverse_linked_list.md | 97 - java/Simple-Calculator.md | 83 - java/array-list.md | 94 - java/fast-exponential.md | 53 - java/inheritance.md | 90 - java/isPowerOfTwo.md | 44 - learn.md | 23 - package-lock.json | 34303 ---------------- package.json | 69 - plugins/my-plugin/index.js | 50 - renovate.json | 23 - sidebars.js | 33 - src/components/AdsComponent/Ads.tsx | 40 - src/components/AdsComponent/index.tsx | 40 - src/components/AdsComponent/style.css | 0 src/components/ChallengeCard.tsx | 41 - .../DSA/DP/Parsing A Boolean Expression.md | 106 - .../DSA/arrays/ArrayVisualizations/index.tsx | 107 - .../BubbleSortVisualization.css | 24 - .../arrays/BubbleSortVisualization/index.tsx | 101 - .../arrays/HeapSortVisualization/index.tsx | 141 - .../arrays/HeapSortVisualization/style.css | 53 - .../InsertionSortVisualization/index.tsx | 94 - .../InsertionSortVisualization/style.css | 36 - .../arrays/MergeSortVisualization/index.tsx | 170 - .../arrays/MergeSortVisualization/style.css | 82 - .../arrays/QuickSortVisualization/index.tsx | 119 - .../arrays/QuickSortVisualization/style.css | 36 - .../SelectionSortVisualization.css | 24 - .../SelectionSortVisualization/index.tsx | 102 - .../ShellSortVisualisation/Shellsort.css | 21 - .../arrays/ShellSortVisualisation/index.tsx | 93 - .../graphs/DijkstraVisualizations/index.tsx | 227 - .../FloydWarshallVisualizations/index.tsx | 123 - src/components/GiscusComponent/index.tsx | 35 - src/components/Header.tsx | 30 - src/components/Highlight/index.js | 15 - .../Homepage/CallToActionSection.tsx | 54 - src/components/Homepage/ContributeSection.tsx | 74 - src/components/Homepage/FeaturesSection.tsx | 102 - .../Homepage/GetInvolvedSection.tsx | 120 - src/components/Homepage/HeroSection.tsx | 42 - src/components/Homepage/HowItWorksSection.tsx | 113 - .../Homepage/PopularAlgorithmsSection.tsx | 90 - .../Homepage/TechnologiesSection.tsx | 102 - .../Homepage/UserTestimonialsSection.tsx | 88 - src/components/Homepage/index.tsx | 29 - src/components/QuizCard.tsx | 30 - .../Scroller/BottomToTop/BottomToTop.tsx | 42 - .../Scroller/TopToBottom/TopToBottom.tsx | 53 - src/components/Visualizing/index.tsx | 387 - src/components/chatbot.jsx | 27 - src/css/BottomToTop.module.css | 20 - src/css/TopToBottom.module.css | 20 - src/css/custom.css | 161 - src/css/visualiezer.css | 93 - src/data/challengeData.ts | 25 - src/data/problemData.ts | 3657 -- src/data/quizData.ts | 45 - src/data/testimonialsData.ts | 24 - src/data/topics.ts | 987 - src/pages/License.md | 21 - src/pages/about/index.tsx | 197 - src/pages/blogs/index.tsx | 263 - src/pages/challenges/challenge1.tsx | 303 - src/pages/challenges/challenge2.tsx | 324 - src/pages/challenges/challenge3.tsx | 409 - src/pages/challenges/index.tsx | 35 - src/pages/community/index.tsx | 55 - src/pages/contact/index.tsx | 200 - src/pages/contributors/index.tsx | 155 - src/pages/dsa-interview/index.tsx | 189 - src/pages/dsa-roadmap/index.tsx | 61 - src/pages/faq/index.tsx | 170 - src/pages/index.js | 61 - src/pages/leaderboard/index.tsx | 67 - src/pages/markdown-page.md | 7 - src/pages/practice/index.tsx | 228 - src/pages/quiz-solutions/array.md | 103 - src/pages/quiz-solutions/b-trees.md | 172 - .../quiz-solutions/binary-search-trees.md | 111 - src/pages/quiz-solutions/binary-trees.md | 89 - src/pages/quiz-solutions/index.tsx | 31 - src/pages/quiz-solutions/queues.md | 162 - src/pages/quiz-solutions/red-black-trees.md | 111 - src/pages/quiz-solutions/stack.md | 270 - src/pages/quizes/arrays.tsx | 252 - src/pages/quizes/b-tree.tsx | 203 - src/pages/quizes/binary-search-tree.tsx | 118 - src/pages/quizes/binary-tree.tsx | 188 - src/pages/quizes/index.tsx | 203 - src/pages/quizes/queue.tsx | 228 - src/pages/quizes/queues.tsx | 207 - src/pages/quizes/red-black-tree.tsx | 242 - src/pages/quizes/stack.tsx | 291 - src/pages/resources/index.tsx | 58 - src/pages/roadmap/index.tsx | 121 - src/pages/terms/index.tsx | 146 - src/theme/Admonition/Icon/Danger.js | 10 - src/theme/Admonition/Layout/index.js | 10 - src/theme/CodeBlock/Line/index.js | 34 - src/theme/CodeBlock/Line/styles.module.css | 45 - src/theme/Footer/index.tsx | 216 - src/theme/MDXComponents.js | 44 - src/theme/Mermaid/index.js | 10 - src/theme/ReactLiveScope/components.js | 14 - src/theme/ReactLiveScope/index.js | 18 - src/theme/Root.js | 6 - static/.nojekyll | 0 static/ads.txt | 1 - static/images/avatar-2.jpg | Bin 4728 -> 0 bytes static/images/avatar1.jpg | Bin 145072 -> 0 bytes static/images/avatar2.jpg | Bin 8021 -> 0 bytes static/images/avatar3.jpg | Bin 8518 -> 0 bytes static/images/docusaurus.svg | 1 - static/images/github.svg | 1 - static/images/jsx.svg | 1 - static/images/mission.jpg | Bin 262000 -> 0 bytes static/images/node-js.svg | 1 - static/images/tailwindcss.svg | 1 - static/images/team-member-1.jpg | Bin 22165 -> 0 bytes static/images/team-member-2.jpg | Bin 156262 -> 0 bytes static/images/team-member-3.jpg | Bin 150711 -> 0 bytes static/images/team-member-4.jpg | Bin 150881 -> 0 bytes static/images/team-member-5.jpg | Bin 143432 -> 0 bytes static/images/tsx.svg | 1 - static/img/docusaurus-social-card.jpg | Bin 55746 -> 0 bytes static/img/docusaurus.png | Bin 5142 -> 0 bytes static/img/favicon.ico | Bin 3626 -> 0 bytes static/img/logo.png | Bin 37866 -> 0 bytes static/img/logo.svg | 1 - static/img/undraw_docusaurus_mountain.svg | 1 - static/img/undraw_docusaurus_react.svg | 1 - static/img/undraw_docusaurus_tree.svg | 1 - static/logo/algo-1.png | Bin 20809 -> 0 bytes static/logo/algo-3.png | Bin 8476 -> 0 bytes static/logo/algo-banner.png | Bin 13813 -> 0 bytes static/logo/algo.png | Bin 18475 -> 0 bytes static/logo/dsa.png | Bin 5112 -> 0 bytes static/logo/ft-copy.png | Bin 25882 -> 0 bytes static/logo/logo.png | Bin 241197 -> 0 bytes static/logo/neural.png | Bin 27276 -> 0 bytes tailwind.config.js | 29 - 911 files changed, 152183 deletions(-) delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/ISSUE_TEMPLATE/bug.yml delete mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/custom.yml delete mode 100644 .github/ISSUE_TEMPLATE/documentation.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature.yml delete mode 100644 .github/ISSUE_TEMPLATE/idea.yml delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/release-drafter.yml delete mode 100644 .github/workflows/add-contributor.yml delete mode 100644 .github/workflows/autolabel.yml delete mode 100644 .github/workflows/codeql.yml delete mode 100644 .github/workflows/dependency-review.yml delete mode 100644 .github/workflows/deploy.yml delete mode 100644 .github/workflows/issue_close_open.yml delete mode 100644 .github/workflows/lighthouse-report.yml delete mode 100644 .github/workflows/lighthouserc.json delete mode 100644 .github/workflows/pr_merge.yaml delete mode 100644 .github/workflows/pr_raise.yml delete mode 100644 .github/workflows/pr_validation.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .github/workflows/test-deploy.yml delete mode 100644 .gitignore delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 LICENSE delete mode 100644 README.md delete mode 100644 SECURITY.md delete mode 100644 admin/scripts/formatLighthouseReport.js delete mode 100644 admin/scripts/package.json delete mode 100644 babel.config.js delete mode 100644 blog/20-most-important-coding-pattern.md delete mode 100644 blog/Common-Recursion-Patterns.md delete mode 100644 blog/Exploring-Graph-Algorithms.md delete mode 100644 blog/Getting-started-with-array-data-structure.md delete mode 100644 blog/Kadanes-algorithm.md delete mode 100644 blog/Recursion-vs-Iteration.md delete mode 100644 blog/Understanding-Graph-Representation.md delete mode 100644 blog/a-very-useful-data-structure-linked-lists.md delete mode 100644 blog/a-very-useful-data-structure-string.md delete mode 100644 blog/authors.yml delete mode 100644 blog/balancing-speed-and-memory-A-Guide-to-Time-and-Space-Complexity.md delete mode 100644 blog/language-matters-your-path-to-dsa-success-starts-here.md delete mode 100644 blog/mastering-recursion.md delete mode 100644 blog/omega-notation-the-key-to-understanding-algorithm-efficiency.md delete mode 100644 blog/optimizing-recursive-functions.md delete mode 100644 blog/practical-applications-of-recursion.md delete mode 100644 blog/understanding-big-o-notation.md delete mode 100644 blog/understanding-time-space-complexity.md delete mode 100644 docs/Approximation Algorithm/Approximation.md delete mode 100644 docs/Circular_array/Application.md delete mode 100644 docs/Circular_array/Introduction.md delete mode 100644 docs/DSA-Problem-Solution/Add_two_number_as_LL.md delete mode 100644 docs/DSA-Problem-Solution/Clone Linked List with Random and Next Pointer.md delete mode 100644 docs/DSA-Problem-Solution/Contains_duplicate.md delete mode 100644 docs/DSA-Problem-Solution/Convert Date to Binary.md delete mode 100644 docs/DSA-Problem-Solution/Cousins in Binary Tree.md delete mode 100644 docs/DSA-Problem-Solution/Delete middle node.md delete mode 100644 docs/DSA-Problem-Solution/Delete_occurences_of_key.md delete mode 100644 docs/DSA-Problem-Solution/Loop in linked list.md delete mode 100644 docs/DSA-Problem-Solution/Merge Two Sorted Arrays.md delete mode 100644 docs/DSA-Problem-Solution/Merge_K_Sorted_Arrays.md delete mode 100644 docs/DSA-Problem-Solution/Palindrome-number.md delete mode 100644 docs/DSA-Problem-Solution/Segregate even and odd nodes in LinkedList.md delete mode 100644 docs/DSA-Problem-Solution/Size_of_largest_BST_in_binary_tree.md delete mode 100644 docs/DSA-Problem-Solution/Sliding Window Maximum.md delete mode 100644 docs/DSA-Problem-Solution/Symmetric Tree.md delete mode 100644 docs/DSA-Problem-Solution/flattening-a-linked-list.md delete mode 100644 docs/DSA-Problem-Solution/house-robber.md delete mode 100644 docs/DSA-Problem-Solution/longest_substring_without_repeated_characters.md delete mode 100644 docs/DSA-Problem-Solution/merge_intervals.md delete mode 100644 docs/DSA-Problem-Solution/odd-even-linked-list.md delete mode 100644 docs/DSA-Problem-Solution/palindrome_linked_list.md delete mode 100644 docs/DSA-Problem-Solution/partition_equal_subset_sum.md delete mode 100644 docs/DSA-Problem-Solution/removing-stars-from-string.md delete mode 100644 docs/DSA-Problem-Solution/reverse-bits.md delete mode 100644 docs/DSA-Problem-Solution/reverse-linked-list.md delete mode 100644 docs/DSA-Problem-Solution/two_sum.md delete mode 100644 docs/Depth_first_traversal.md delete mode 100644 docs/Divide and Conquer/Maximum-minimum.md delete mode 100644 docs/Divide and Conquer/Strassen's-Matrix-Mutiplication.md delete mode 100644 docs/Fenwick Tree /FenwickTree.md delete mode 100644 docs/Hashing/CollisionHandling.md delete mode 100644 docs/Hashing/OperationInsertion.md delete mode 100644 docs/Hashing/OperationSearch.md delete mode 100644 docs/Hashing/OperationUpdate.md delete mode 100644 docs/Hashing/Tigerhashing.md delete mode 100644 docs/Hashing/_category_.json delete mode 100644 docs/Hashing/deletion-in-hash-table.md delete mode 100644 docs/Hashing/hashsets.md delete mode 100644 docs/Hashing/imp-of-hashing.md delete mode 100644 docs/Hashing/what-is-hashing.md delete mode 100644 docs/Jump Search/Jump Search.md delete mode 100644 docs/KMP searching pattern/_category_.json delete mode 100644 docs/KMP searching pattern/readme.md delete mode 100644 docs/Number theory/GCD.md delete mode 100644 docs/Number theory/LCM.md delete mode 100644 docs/Number theory/sieve-of-eratosthenes.md delete mode 100644 docs/Object Oriented Programming/4-pillars-of-oops.md delete mode 100644 docs/Object Oriented Programming/ApplicationofOOPS.md delete mode 100644 docs/Object Oriented Programming/Polymorphism.md delete mode 100644 docs/Object Oriented Programming/_category_.json delete mode 100644 docs/Object Oriented Programming/abstraction.md delete mode 100644 docs/Object Oriented Programming/car.png delete mode 100644 docs/Object Oriented Programming/classes-and-objects.md delete mode 100644 docs/Object Oriented Programming/constructors-destructors.md delete mode 100644 docs/Object Oriented Programming/interfaces-vs-abstract-classes.md delete mode 100644 docs/Object Oriented Programming/intro-to-oops.md delete mode 100644 docs/Object Oriented Programming/intro.png delete mode 100644 docs/Object Oriented Programming/real-world-examples.md delete mode 100644 docs/Object Oriented Programming/typesOfInheritance.md delete mode 100644 docs/Queue/Blocked-queue.png delete mode 100644 docs/Queue/Circular-queue.png delete mode 100644 docs/Queue/Priority-queue.png delete mode 100644 docs/Queue/Problem-Practice.md delete mode 100644 docs/Queue/Two-Stack-Queue.md delete mode 100644 docs/Queue/_category_.json delete mode 100644 docs/Queue/blocked-queue.md delete mode 100644 docs/Queue/check-palindrome-using-dequeue.md delete mode 100644 docs/Queue/circular-queue.md delete mode 100644 docs/Queue/concurrent-queue.md delete mode 100644 docs/Queue/design-circular-Dueque.md delete mode 100644 docs/Queue/design-circular-Queue.md delete mode 100644 docs/Queue/double-ended-queue.md delete mode 100644 docs/Queue/doubleendedqueue.png delete mode 100644 docs/Queue/priority-queue.md delete mode 100644 docs/Queue/priority_queue_questions.md delete mode 100644 docs/Randomized Algorithm/Randomized-Quicksort.md delete mode 100644 docs/Recursion-depths/Recursion.md delete mode 100644 docs/Recursion-depths/advanced-topics.md delete mode 100644 docs/Recursion-depths/basic-concepts.md delete mode 100644 docs/Recursion-depths/handling-depth-errors.md delete mode 100644 docs/Recursion-depths/performance-consideration.md delete mode 100644 docs/Recursion/Ackerman.md delete mode 100644 docs/Recursion/Count-all-subsequences-with-sum-K.md delete mode 100644 docs/Recursion/GrayCodeGeneration.md delete mode 100644 docs/Recursion/Josephus-Queries.md delete mode 100644 docs/Recursion/Knight's_Tour_Problem.md delete mode 100644 docs/Recursion/Letter-Combinations-of-a-Phone-number.md delete mode 100644 docs/Recursion/N Queen 2.png delete mode 100644 docs/Recursion/N Qween 1.png delete mode 100644 docs/Recursion/Reversing_String.md delete mode 100644 docs/Recursion/SmawkAlgorithm.md delete mode 100644 docs/Recursion/Sodoko.md delete mode 100644 docs/Recursion/StonePaperScissor.md delete mode 100644 docs/Recursion/TowersOfHanoi.md delete mode 100644 docs/Recursion/Unwinding_in_recursion.md delete mode 100644 docs/Recursion/VoseAlias.md delete mode 100644 docs/Recursion/WaterJug.md delete mode 100644 docs/Recursion/_category_.json delete mode 100644 docs/Recursion/catalannumber.md delete mode 100644 docs/Recursion/fibonacci.md delete mode 100644 docs/Recursion/generate-parantheses.md delete mode 100644 docs/Recursion/josephus.md delete mode 100644 docs/Recursion/look-and-say.md delete mode 100644 docs/Recursion/n-queen.md delete mode 100644 docs/Recursion/recursion.md delete mode 100644 docs/Recursion/ulamsequence.md delete mode 100644 docs/Segment-Trees/Dynamic Segment Trees.md delete mode 100644 docs/Segment-Trees/Practice Porblem.md delete mode 100644 docs/Segment-Trees/Segment Trees Introduction.md delete mode 100644 docs/Segment-Trees/Segment-Tree-img.png delete mode 100644 docs/Sliding-Window/IntroductionToSlidingWindow.jpg delete mode 100644 docs/Sliding-Window/Problem-Practice.md delete mode 100644 docs/Sliding-Window/_category_.json delete mode 100644 docs/Sliding-Window/character-replacement.md delete mode 100644 docs/Sliding-Window/introduction-to-sliding-window.md delete mode 100644 docs/Sliding-Window/longest-repeating-character-replacement.md delete mode 100644 docs/Sliding-Window/longest-substring-with-K-different-characters.md delete mode 100644 docs/Sliding-Window/maximum-sum-subarray-size-K.md delete mode 100644 docs/Sliding-Window/minimize-maximum-of-two-arrays.md delete mode 100644 docs/Stack/Balanced-Parenthesis.md delete mode 100644 docs/Stack/Balanced-parentheses-checker.md delete mode 100644 docs/Stack/Conversion.md delete mode 100644 docs/Stack/Evaluation.md delete mode 100644 docs/Stack/Introduction_to_Stack.png delete mode 100644 docs/Stack/Min-Stack.md delete mode 100644 docs/Stack/MonotonicStack.md delete mode 100644 docs/Stack/Next Greater Element (NGE).md delete mode 100644 docs/Stack/Problem-Practice.md delete mode 100644 docs/Stack/Reverse-Stack.md delete mode 100644 docs/Stack/Stack-permutation.md delete mode 100644 docs/Stack/Stock-span.md delete mode 100644 docs/Stack/String_Reversal.md delete mode 100644 docs/Stack/Trapping Rain Water Problem.md delete mode 100644 docs/Stack/_category_.json delete mode 100644 docs/Stack/introduction-to-stack.md delete mode 100644 docs/Stack/stack.md delete mode 100644 docs/Standard Template Library/STL-algorithms.md delete mode 100644 docs/Standard Template Library/STL-containers.md delete mode 100644 docs/Standard Template Library/STL-iterators.md delete mode 100644 docs/Standard Template Library/STL-theory.md delete mode 100644 docs/Strings/Problem-Practice.md delete mode 100644 docs/Tarjan's Algorithm/Tarjan.md delete mode 100644 docs/Tarjan's Algorithm/algorithm.png delete mode 100644 docs/Task Scheduling/Task-schedule.md delete mode 100644 docs/Task Scheduling/_category_.json delete mode 100644 docs/Trees/AVL Tree.md delete mode 100644 docs/Trees/B-Trees.md delete mode 100644 docs/Trees/Expression-tree.md delete mode 100644 docs/Trees/Heap-tree.md delete mode 100644 docs/Trees/Practice Problems.md delete mode 100644 docs/Trees/Sum-tree.md delete mode 100644 docs/Trees/Trees Practice Problems.md delete mode 100644 docs/Trees/Types of Trees.md delete mode 100644 docs/Trees/balanced-tree.md delete mode 100644 docs/Trees/binary-search-tree.md delete mode 100644 docs/Trees/binary-tree.md delete mode 100644 docs/Trees/k-d tree algorithm.md delete mode 100644 docs/Trees/tree-data-structure.md delete mode 100644 docs/Tries/Problem-Practice.md delete mode 100644 docs/Tries/Tries and its Implementation.md delete mode 100644 docs/Tries/tries-examples.md delete mode 100644 docs/Tries/tries-theory.md delete mode 100644 docs/advance-data-structure/_category_.json delete mode 100644 docs/advance-data-structure/disjoint-set.md delete mode 100644 docs/advance-data-structure/fenwick-tree.md delete mode 100644 docs/advance-data-structure/segment-tree.md delete mode 100644 docs/algorithms/ Edmonds-Karp Algorithm/ edmonds-karp-algorithm.md delete mode 100644 docs/algorithms/Application-of-Recursion.md delete mode 100644 docs/algorithms/Application-of-linked-list.md delete mode 100644 docs/algorithms/Bentley-Ottmann-Algorithm/bentley-ottmann-algo.md delete mode 100644 docs/algorithms/CNN-deep-learning-algorithm.md delete mode 100644 "docs/algorithms/Dijkstra\342\200\231s Algorithm.md" delete mode 100644 docs/algorithms/DutchNationalFlag-algorithm/DutchNationalFlag.md delete mode 100644 docs/algorithms/DutchNationalFlag-algorithm/_category_.json delete mode 100644 docs/algorithms/Encryption algorithms/Caesar Cipher.md delete mode 100644 docs/algorithms/Encryption algorithms/advanced_encryption_standard.md delete mode 100644 docs/algorithms/Encryption algorithms/asymmetric_encryption.md delete mode 100644 docs/algorithms/Encryption algorithms/blockchain_encryption.md delete mode 100644 docs/algorithms/Encryption algorithms/elliptic_curve_cryptography.md delete mode 100644 docs/algorithms/Encryption algorithms/hashing.md delete mode 100644 docs/algorithms/Encryption algorithms/homomorphic-encryption.md delete mode 100644 docs/algorithms/Encryption algorithms/post-quantum-encryption.md delete mode 100644 docs/algorithms/Encryption algorithms/steganography-algo.md delete mode 100644 docs/algorithms/Encryption algorithms/symmetric_encryption.md delete mode 100644 docs/algorithms/Gale-Shapley-Algorithm/GaleShapley.md delete mode 100644 docs/algorithms/Hashing-algorithm.md delete mode 100644 docs/algorithms/N-Queens-Dynamic-programming-algorithm.md delete mode 100644 docs/algorithms/Scheduling Algorithms/EarliestDeadlineFirst.md delete mode 100644 docs/algorithms/Scheduling Algorithms/FirstComeFirstServed.md delete mode 100644 docs/algorithms/Scheduling Algorithms/LeastRecentlyUsed.md delete mode 100644 docs/algorithms/Scheduling Algorithms/PriorityScheduling.md delete mode 100644 docs/algorithms/Scheduling Algorithms/RoundRobin.md delete mode 100644 docs/algorithms/Scheduling Algorithms/ShortestJobRemainingFirst.md delete mode 100644 docs/algorithms/Scheduling Algorithms/SweepLine.md delete mode 100644 docs/algorithms/Scheduling Algorithms/_category_.json delete mode 100644 docs/algorithms/Scheduling Algorithms/least-recently-used.md delete mode 100644 docs/algorithms/Scheduling Algorithms/multilevel-queue-scheduling.md delete mode 100644 docs/algorithms/Scheduling Algorithms/priority-scheduling.md delete mode 100644 docs/algorithms/Searching Algorithms/A*-Search.md delete mode 100644 docs/algorithms/Searching Algorithms/AO*-Search.md delete mode 100644 docs/algorithms/Searching Algorithms/Best-First-Search.md delete mode 100644 docs/algorithms/Searching Algorithms/BinarySearch.md delete mode 100644 docs/algorithms/Searching Algorithms/Boyer-Moore-Search.md delete mode 100644 docs/algorithms/Searching Algorithms/Breadth-First-Search-(BFS)-Algo.md delete mode 100644 docs/algorithms/Searching Algorithms/ComparisonSearch.md delete mode 100644 docs/algorithms/Searching Algorithms/Depth-First-Search-(DFS)-Algo.md delete mode 100644 docs/algorithms/Searching Algorithms/DigitalSearch.md delete mode 100644 docs/algorithms/Searching Algorithms/ExponentialSerach.md delete mode 100644 docs/algorithms/Searching Algorithms/FibbonaciSearch.md delete mode 100644 docs/algorithms/Searching Algorithms/HashingSearch.md delete mode 100644 docs/algorithms/Searching Algorithms/Interpolation-search-algorithm.md delete mode 100644 docs/algorithms/Searching Algorithms/InterpolationSearch.md delete mode 100644 docs/algorithms/Searching Algorithms/JumpSearch.md delete mode 100644 docs/algorithms/Searching Algorithms/LinearSearch.md delete mode 100644 docs/algorithms/Searching Algorithms/Meta-binary-search.md delete mode 100644 docs/algorithms/Searching Algorithms/Rabin-Karp-Algorithm.md delete mode 100644 docs/algorithms/Searching Algorithms/SentinelSearch.md delete mode 100644 docs/algorithms/Searching Algorithms/Sublist-Search.md delete mode 100644 docs/algorithms/Searching Algorithms/TernarySearch.md delete mode 100644 docs/algorithms/Searching Algorithms/Uniform-Cost-Search.md delete mode 100644 docs/algorithms/Two-Pointers/IntroductionToTwoPointers.png delete mode 100644 docs/algorithms/Two-Pointers/Max_Distance.md delete mode 100644 docs/algorithms/Two-Pointers/Problem-Practice.md delete mode 100644 docs/algorithms/Two-Pointers/_category_.json delete mode 100644 docs/algorithms/Two-Pointers/imp-of-two-pointers.md delete mode 100644 docs/algorithms/Two-Pointers/introduction-to-two-pointers.md delete mode 100644 docs/algorithms/Yolo-Object-detection-ML-Algorithm.md delete mode 100644 docs/algorithms/_category_.json delete mode 100644 docs/algorithms/backtracking-algorithms/Bron-Kerbosch-Algorithm.md delete mode 100644 docs/algorithms/backtracking-algorithms/_category_.json delete mode 100644 docs/algorithms/backtracking-algorithms/backtracking-questions.md delete mode 100644 docs/algorithms/backtracking-algorithms/hamilton-path-cyle.md delete mode 100644 docs/algorithms/backtracking-algorithms/imp-of-backtracking.md delete mode 100644 docs/algorithms/backtracking-algorithms/m-coloring.md delete mode 100644 docs/algorithms/backtracking-algorithms/what-is-backtracking.md delete mode 100644 docs/algorithms/greedy-algorithms/Fractional_Knapsack.md delete mode 100644 docs/algorithms/greedy-algorithms/Huffman-coding.md delete mode 100644 docs/algorithms/greedy-algorithms/Job-sequencing-problem.md delete mode 100644 "docs/algorithms/greedy-algorithms/Prim\342\200\231s-Minimum-Spanning-Tree.md" delete mode 100644 docs/algorithms/greedy-algorithms/Problem-Practice.md delete mode 100644 docs/algorithms/greedy-algorithms/_category_.json delete mode 100644 docs/algorithms/greedy-algorithms/activity-selection.md delete mode 100644 docs/algorithms/greedy-algorithms/commonly-asked-greedy-questions.md delete mode 100644 docs/algorithms/greedy-algorithms/fractional-knapsack.md delete mode 100644 docs/algorithms/greedy-algorithms/greedy-theory.md delete mode 100644 docs/algorithms/kadane-algorithm/_category_.json delete mode 100644 docs/algorithms/kadane-algorithm/kadane-algo.md delete mode 100644 docs/algorithms/mathematics-algorithms/_category_.json delete mode 100644 docs/algorithms/mathematics-algorithms/discrete-logarithm.md delete mode 100644 docs/algorithms/mathematics-algorithms/euclidean-algorithm.md delete mode 100644 docs/algorithms/mathematics-algorithms/fermat-little-theorem.md delete mode 100644 docs/algorithms/mathematics-algorithms/gcd-lcm.md delete mode 100644 docs/algorithms/mathematics-algorithms/imp-of-mathematics.md delete mode 100644 docs/algorithms/mathematics-algorithms/modular-arithmetic.md delete mode 100644 docs/algorithms/mathematics-algorithms/sieve-of-eratosthenes.md delete mode 100644 docs/algorithms/mathematics-algorithms/sweep-line-algorithm.md delete mode 100644 docs/algorithms/mathematics-algorithms/what-is-mathematical-algorithms.md delete mode 100644 docs/algorithms/memoisation-algorithms/_category_.json delete mode 100644 docs/algorithms/memoisation-algorithms/imp-of-memoisation.md delete mode 100644 docs/algorithms/memoisation-algorithms/what-is-memoisation.md delete mode 100644 docs/algorithms/modular-exponentiation-algorithm.md delete mode 100644 docs/algorithms/moores-voting-algorithm/moore-voting-algo.md delete mode 100644 docs/algorithms/recursive-algorithms/DirectRecursion.md delete mode 100644 docs/algorithms/recursive-algorithms/IndirectRecursion.md delete mode 100644 docs/algorithms/recursive-algorithms/_category_.json delete mode 100644 docs/algorithms/recursive-algorithms/mutual-recursion.md delete mode 100644 docs/algorithms/recursive-algorithms/non-tail-recursion.md delete mode 100644 docs/algorithms/recursive-algorithms/tail-recursion.md delete mode 100644 docs/algorithms/recursive-algorithms/tree-recursion.md delete mode 100644 docs/algorithms/sorting-algorithms/BitonicSort.md delete mode 100644 docs/algorithms/sorting-algorithms/BogoSort.md delete mode 100644 docs/algorithms/sorting-algorithms/BubbleSort.md delete mode 100644 docs/algorithms/sorting-algorithms/BucketSort.md delete mode 100644 docs/algorithms/sorting-algorithms/CocktailShakerSort.md delete mode 100644 docs/algorithms/sorting-algorithms/CombSort.md delete mode 100644 docs/algorithms/sorting-algorithms/CountingSort.md delete mode 100644 docs/algorithms/sorting-algorithms/CycleSort.md delete mode 100644 docs/algorithms/sorting-algorithms/Dutch-flag-algo.md delete mode 100644 docs/algorithms/sorting-algorithms/GnomeSort.md delete mode 100644 docs/algorithms/sorting-algorithms/HeapSort.md delete mode 100644 docs/algorithms/sorting-algorithms/InsertionSort.md delete mode 100644 docs/algorithms/sorting-algorithms/JumpSort.md delete mode 100644 docs/algorithms/sorting-algorithms/MergeSort.md delete mode 100644 docs/algorithms/sorting-algorithms/Odd-Even-Sort.md delete mode 100644 docs/algorithms/sorting-algorithms/OddEvenSort.md delete mode 100644 docs/algorithms/sorting-algorithms/Pancake-sorting-algorithm.md delete mode 100644 docs/algorithms/sorting-algorithms/Pigeonhole.md delete mode 100644 docs/algorithms/sorting-algorithms/QuickSort.md delete mode 100644 docs/algorithms/sorting-algorithms/RadixSort.md delete mode 100644 docs/algorithms/sorting-algorithms/SelectionSort.md delete mode 100644 docs/algorithms/sorting-algorithms/ShellSort.md delete mode 100644 docs/algorithms/sorting-algorithms/StoogeSort.md delete mode 100644 docs/algorithms/sorting-algorithms/TimSort.md delete mode 100644 docs/algorithms/sorting-algorithms/Topological-sorting-algorithm.md delete mode 100644 docs/algorithms/sorting-algorithms/TreeSort.md delete mode 100644 docs/algorithms/sorting-algorithms/_category_.json delete mode 100644 docs/algorithms/sorting-algorithms/odd-even-sorting.md delete mode 100644 docs/algorithms/sorting-algorithms/parity-partition-sort.md delete mode 100644 docs/algorithms/sorting-algorithms/strand-sort.md delete mode 100644 docs/algorithms/string-algorithm/Boyer-moore-algorithm.md delete mode 100644 docs/algorithms/string-algorithm/Naive-search.md delete mode 100644 docs/algorithms/string-algorithm/Suffix-Tree-Algorithm.md delete mode 100644 docs/algorithms/string-algorithm/Z-Algorithm.md delete mode 100644 docs/algorithms/string-algorithm/aho-corasick-algorithm.md delete mode 100644 docs/algorithms/string-algorithm/kmp-algorithm.md delete mode 100644 docs/algorithms/string-algorithm/rabin-karp-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/Naive-String-Matching-Algorithm.md delete mode 100644 docs/algorithms/string-algorithms/_category_.json delete mode 100644 docs/algorithms/string-algorithms/apostolico-giancarlo-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/berry-ravindran-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/bitap-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/bndm-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/boyer-moore-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/colussi-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/commentz-walter-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/crochemores-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/finite-state-automation-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/kmp-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/lcs-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/levenshtein-distance-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/manacher-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/needleman-wunsch-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/not-so-naive-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/optimal-mismatch-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/quick-search-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/rabin-karp-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/reverse-factor-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/shift-or-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/simon-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/smith-waterman-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/suffix-array-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/sunday-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/turbo-boyer-moore-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/two-way-string-matching-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/ukkonens-algorithm.md delete mode 100644 docs/algorithms/string-algorithms/zhu-takaoka-algorithm.md delete mode 100644 docs/b-tree/B-Tree-1.md delete mode 100644 docs/b-tree/B-Tree-2.md delete mode 100644 docs/b-tree/B-Tree-3.md delete mode 100644 docs/b-tree/B-tree Practice Problems.md delete mode 100644 docs/b-tree/image/BTree2Ins.png delete mode 100644 docs/b-tree/image/BTreeIns3.png delete mode 100644 docs/b-tree/image/BTreeIns4.png delete mode 100644 docs/b-tree/image/BTreeIns6.png delete mode 100644 docs/b-tree/image/BTreeSplit-1024x321.jpg delete mode 100644 docs/b-tree/image/Btree1.png delete mode 100644 docs/b-tree/image/delete.png delete mode 100644 docs/b-tree/image/delete2.png delete mode 100644 docs/b-tree/image/output253.png delete mode 100644 docs/b-tree/image/output254.png delete mode 100644 docs/b-tree/image/output255.png delete mode 100644 docs/b-tree/image/output256.png delete mode 100644 docs/backtracking algorithms/N-QueensProblem.md delete mode 100644 docs/backtracking-algorithms/n-queens_algorithm.md delete mode 100644 docs/balancedBinTree/balancedBinTree.md delete mode 100644 docs/balancedBinTree/balancedBinTreejava.md delete mode 100644 docs/balancedBinTree/balancedBinTreejavaScript.md delete mode 100644 docs/basic-dsa/Method Overriding.md delete mode 100644 docs/basic-dsa/Operator Overloading.md delete mode 100644 docs/basic-dsa/Strings/Advanced-techniques.md delete mode 100644 docs/basic-dsa/Strings/Highest freqyuency letter.md delete mode 100644 docs/basic-dsa/Strings/Isomorphic strings.md delete mode 100644 docs/basic-dsa/Strings/Reversing a string.md delete mode 100644 docs/basic-dsa/Strings/What_is String.md delete mode 100644 docs/basic-dsa/Strings/kmp-algo.md delete mode 100644 docs/basic-dsa/_category_.json delete mode 100644 docs/basic-dsa/array/2d-arrays.md delete mode 100644 docs/basic-dsa/array/Kadane-Algorithm.md delete mode 100644 docs/basic-dsa/array/ProudctOfArrayExceptSelf.md delete mode 100644 docs/basic-dsa/array/_category_.json delete mode 100644 docs/basic-dsa/array/arrays-bubblesort-dsa.md delete mode 100644 docs/basic-dsa/array/arrays-dsa.md delete mode 100644 docs/basic-dsa/array/arrays-insertionsort.md delete mode 100644 docs/basic-dsa/array/arrays-kadanesalgorithm-dsa.md delete mode 100644 docs/basic-dsa/array/arrays-selectionsort.md delete mode 100644 docs/basic-dsa/array/bucket-sort.md delete mode 100644 docs/basic-dsa/array/counting-sort.md delete mode 100644 docs/basic-dsa/array/heap-sort.md delete mode 100644 docs/basic-dsa/array/quick-sort.md delete mode 100644 docs/basic-dsa/array/radix-sort.md delete mode 100644 docs/basic-dsa/matrix-data-structure.md delete mode 100644 docs/basic-dsa/pointer.md delete mode 100644 docs/binary-search-tree/Binary search tree.md delete mode 100644 docs/binary-search-tree/Post_order_traversal.md delete mode 100644 docs/binary-search-tree/Problem-Practice.md delete mode 100644 docs/binary-search-tree/_category_.json delete mode 100644 docs/binary-search-tree/avl-tree.md delete mode 100644 docs/binary-search-tree/delete-BST.md delete mode 100644 docs/binary-search-tree/inorder-predecessor-BST.md delete mode 100644 docs/binary-search-tree/inorder-successor-BST.md delete mode 100644 docs/binary-search-tree/insert-BST.md delete mode 100644 docs/binary-search-tree/red-black-trees.md delete mode 100644 docs/binary-search-tree/search-BST.md delete mode 100644 docs/binary-search/Exponential-Search.md delete mode 100644 docs/binary-search/Iterative_binary_search.md delete mode 100644 docs/binary-search/Painter_Partition_problem.md delete mode 100644 docs/binary-search/Problem-Practice.md delete mode 100644 docs/binary-search/_category_.json delete mode 100644 docs/binary-search/binary-search.md delete mode 100644 docs/binary-search/binary-search_rotated-sorted-array.md delete mode 100644 docs/binary-search/binary.md delete mode 100644 docs/binary-search/binary_search_questions.md delete mode 100644 docs/binary-search/matrix-binary-dsa.md delete mode 100644 docs/binary-search/recursive_binary_search.md delete mode 100644 docs/binary-trees/_category_.json delete mode 100644 docs/binary-trees/basic-operations.md delete mode 100644 docs/binary-trees/binary-tree.md delete mode 100644 docs/binary-trees/expression-tree.md delete mode 100644 docs/binary-trees/maximum-depth.md delete mode 100644 docs/binary-trees/merkle-tree.md delete mode 100644 docs/binary-trees/minimum-depth.md delete mode 100644 docs/binary-trees/practice-problems.md delete mode 100644 docs/binary-trees/splay-trees.md delete mode 100644 docs/bit-manipulation/_category_.json delete mode 100644 docs/bit-manipulation/bit-manipulation-technique.md delete mode 100644 docs/bit-manipulation/bitmanipulation-practice-problem.md delete mode 100644 docs/bit-manipulation/brain-kernighan-algo.md delete mode 100644 docs/bit-manipulation/clear-ith-Bit.md delete mode 100644 docs/challenges solutions/Challenge4.md delete mode 100644 docs/challenges solutions/_category_.json delete mode 100644 docs/challenges solutions/challenge1.md delete mode 100644 docs/challenges solutions/challenge2.md delete mode 100644 docs/challenges solutions/challenge3.md delete mode 100644 docs/combinatorics/Practice-problems.md delete mode 100644 docs/combinatorics/_category_.json delete mode 100644 docs/combinatorics/combinatorics-examples.md delete mode 100644 docs/combinatorics/combinatorics-theory.md delete mode 100644 docs/complexity/_category_.json delete mode 100644 docs/complexity/how-to-calculate-complexity.md delete mode 100644 docs/complexity/image-1.png delete mode 100644 docs/complexity/image.png delete mode 100644 docs/complexity/space-complexity.md delete mode 100644 docs/complexity/time-complexity.md delete mode 100644 docs/complexity/time-space-complexity.md delete mode 100644 docs/content.md delete mode 100644 docs/dsa/_category_.json delete mode 100644 docs/dsa/imp-of-dsa.md delete mode 100644 docs/dsa/roadmap-to-dsa.md delete mode 100644 docs/dsa/types-of-dsa.md delete mode 100644 docs/dsa/what-is-dsa.md delete mode 100644 docs/dynamic-programming/Beautiful-Subgrids.md delete mode 100644 docs/dynamic-programming/Matrix-chain-multiplication.md delete mode 100644 docs/dynamic-programming/Multistage-graph.md delete mode 100644 docs/dynamic-programming/Two-City-Scheduling-3D-DP.md delete mode 100644 docs/dynamic-programming/_category_.json delete mode 100644 docs/dynamic-programming/approaches.md delete mode 100644 docs/dynamic-programming/dynamic-programming-optimizations.md delete mode 100644 docs/dynamic-programming/fence-painting.md delete mode 100644 docs/dynamic-programming/house-robber.md delete mode 100644 docs/dynamic-programming/how-to-identify.md delete mode 100644 docs/dynamic-programming/longest-zig-zag-subsequence.md delete mode 100644 docs/dynamic-programming/longest_common_subsequence.md delete mode 100644 docs/dynamic-programming/minimum_flips_to_zero_matrix.md delete mode 100644 docs/dynamic-programming/palindrome_partitioning_IV.md delete mode 100644 docs/dynamic-programming/practice-problems-different-patterns.md delete mode 100644 docs/dynamic-programming/trapped-rainwater.md delete mode 100644 docs/fundamentals/Conditional Statement.md delete mode 100644 docs/fundamentals/Functions/Function Call.md delete mode 100644 docs/fundamentals/Functions/Function Closures.md delete mode 100644 docs/fundamentals/Functions/Function Composition.md delete mode 100644 docs/fundamentals/Functions/Function Currying.md delete mode 100644 docs/fundamentals/Functions/Function Declaration.md delete mode 100644 docs/fundamentals/Functions/Function Memoization.md delete mode 100644 docs/fundamentals/Functions/Function Overloading.md delete mode 100644 docs/fundamentals/Functions/Function Parameters.md delete mode 100644 docs/fundamentals/Functions/Function Recursion.md delete mode 100644 docs/fundamentals/Functions/Function Return.md delete mode 100644 docs/fundamentals/Functions/Function Scope.md delete mode 100644 docs/fundamentals/Loops.md delete mode 100644 docs/game-Theory/gameTheory.md delete mode 100644 docs/game-Theory/gameTheoryExamples.md delete mode 100644 docs/graphs/Adjacency-Matrix.md delete mode 100644 docs/graphs/Disjoint Set Union.md delete mode 100644 docs/graphs/Longest-path-in-DAG.md delete mode 100644 docs/graphs/Page-Rank-Algorithm.md delete mode 100644 docs/graphs/Practice Problems.md delete mode 100644 docs/graphs/_category_.json delete mode 100644 docs/graphs/ant-colony-optimization-tsp.md delete mode 100644 docs/graphs/bfs.md delete mode 100644 docs/graphs/bipartite-graph.md delete mode 100644 docs/graphs/dfs.md delete mode 100644 docs/graphs/dfs_java.md delete mode 100644 docs/graphs/eulerian-graphs.md delete mode 100644 docs/graphs/flood-fill.md delete mode 100644 docs/graphs/floyd-algorithm.md delete mode 100644 docs/graphs/graph-cloning.md delete mode 100644 docs/graphs/graph-coloring.md delete mode 100644 docs/graphs/graph-reversal.md delete mode 100644 docs/graphs/hopcroft-karp-algorithm.md delete mode 100644 docs/graphs/kahn-algo.md delete mode 100644 docs/graphs/kosaraju-algorithm.md delete mode 100644 docs/graphs/kruskal-algorithm.md delete mode 100644 docs/graphs/minimum-cost-spanning-tree.md delete mode 100644 docs/graphs/practice-problems.md delete mode 100644 docs/graphs/prims-algorithm.md delete mode 100644 docs/graphs/shortest-path-algorithms/A-star-algorithm.md delete mode 100644 docs/graphs/shortest-path-algorithms/Prims-algorithm.md delete mode 100644 docs/graphs/shortest-path-algorithms/_category_.json delete mode 100644 docs/graphs/shortest-path-algorithms/bell-man-ford-algorithm.md delete mode 100644 docs/graphs/shortest-path-algorithms/dijkstra-algorithm.md delete mode 100644 docs/graphs/shortest-path-algorithms/floyd-warshall-algorithm.md delete mode 100644 docs/graphs/tarjans-algo.md delete mode 100644 docs/graphs/warshall-algo.md delete mode 100644 docs/greedy-algorithms/Graph-Coloring.md delete mode 100644 docs/greedy-algorithms/job-scheduling.md delete mode 100644 docs/hash/Practice Problems.md delete mode 100644 docs/hash/_category_.json delete mode 100644 docs/hash/hash-tables.md delete mode 100644 docs/heap/Kth-largest-using-min_heap.md delete mode 100644 docs/heap/Problem-Practice.md delete mode 100644 docs/heap/_category_.json delete mode 100644 docs/heap/heap-basics.md delete mode 100644 docs/heap/heap-operations.md delete mode 100644 docs/heap/kth-largest.md delete mode 100644 docs/heap/kth-smallest.md delete mode 100644 docs/heap/time-complexity.md delete mode 100644 docs/index.md delete mode 100644 docs/knapsack-disaster-relief/knapsack-disaster-relief.md delete mode 100644 docs/languages/C/c-0.md delete mode 100644 docs/languages/C/c-1.md delete mode 100644 docs/languages/C/c-2.md delete mode 100644 docs/languages/C/c-3.md delete mode 100644 docs/languages/C/c-4.md delete mode 100644 docs/languages/SQL/sql-1.md delete mode 100644 docs/languages/SQL/sql-10.md delete mode 100644 docs/languages/SQL/sql-11.md delete mode 100644 docs/languages/SQL/sql-12.md delete mode 100644 docs/languages/SQL/sql-13.md delete mode 100644 docs/languages/SQL/sql-14.md delete mode 100644 docs/languages/SQL/sql-15.md delete mode 100644 docs/languages/SQL/sql-16.md delete mode 100644 docs/languages/SQL/sql-17.md delete mode 100644 docs/languages/SQL/sql-18.md delete mode 100644 docs/languages/SQL/sql-19.md delete mode 100644 docs/languages/SQL/sql-2.md delete mode 100644 docs/languages/SQL/sql-20.md delete mode 100644 docs/languages/SQL/sql-21.md delete mode 100644 docs/languages/SQL/sql-22.md delete mode 100644 docs/languages/SQL/sql-23.md delete mode 100644 docs/languages/SQL/sql-24.md delete mode 100644 docs/languages/SQL/sql-25.md delete mode 100644 docs/languages/SQL/sql-3.md delete mode 100644 docs/languages/SQL/sql-4.md delete mode 100644 docs/languages/SQL/sql-5.md delete mode 100644 docs/languages/SQL/sql-6.md delete mode 100644 docs/languages/SQL/sql-7.md delete mode 100644 docs/languages/SQL/sql-8.md delete mode 100644 docs/languages/SQL/sql-9.md delete mode 100644 docs/languages/_category_.json delete mode 100644 docs/languages/cpp/_category_.json delete mode 100644 docs/languages/cpp/cp-0.md delete mode 100644 docs/languages/cpp/cp-1.md delete mode 100644 docs/languages/cpp/cp-10.md delete mode 100644 docs/languages/cpp/cp-11.md delete mode 100644 docs/languages/cpp/cp-12.md delete mode 100644 docs/languages/cpp/cp-13.md delete mode 100644 docs/languages/cpp/cp-2.md delete mode 100644 docs/languages/cpp/cp-3.md delete mode 100644 docs/languages/cpp/cp-4.md delete mode 100644 docs/languages/cpp/cp-5.md delete mode 100644 docs/languages/cpp/cp-6.md delete mode 100644 docs/languages/cpp/cp-7.md delete mode 100644 docs/languages/cpp/cp-8.md delete mode 100644 docs/languages/cpp/cp-9.md delete mode 100644 docs/languages/csharp/_category_.json delete mode 100644 docs/languages/csharp/csharp-0.md delete mode 100644 docs/languages/csharp/csharp-1.md delete mode 100644 docs/languages/csharp/csharp-2.md delete mode 100644 docs/languages/csharp/csharp-3.md delete mode 100644 docs/languages/csharp/csharp-4.md delete mode 100644 docs/languages/csharp/csharp-5.md delete mode 100644 docs/languages/csharp/csharp-6.md delete mode 100644 docs/languages/csharp/csharp-7.md delete mode 100644 docs/languages/csharp/csharp-8.md delete mode 100644 docs/languages/csharp/csharp-9.md delete mode 100644 docs/languages/java/_category_.json delete mode 100644 docs/languages/java/ex1.md delete mode 100644 docs/languages/java/ex2.md delete mode 100644 docs/languages/java/ex4.md delete mode 100644 docs/languages/java/java-1.md delete mode 100644 docs/languages/java/java-10.md delete mode 100644 docs/languages/java/java-2.md delete mode 100644 docs/languages/java/java-3.md delete mode 100644 docs/languages/java/java-4.md delete mode 100644 docs/languages/java/java-5-1.md delete mode 100644 docs/languages/java/java-6.md delete mode 100644 docs/languages/java/java-7.md delete mode 100644 docs/languages/java/java-8.md delete mode 100644 docs/languages/java/java-9.md delete mode 100644 docs/languages/javascript/_category_.json delete mode 100644 docs/languages/javascript/js-0.md delete mode 100644 docs/languages/javascript/js-1.md delete mode 100644 docs/languages/javascript/js-10.md delete mode 100644 docs/languages/javascript/js-11.md delete mode 100644 docs/languages/javascript/js-12.md delete mode 100644 docs/languages/javascript/js-13.md delete mode 100644 docs/languages/javascript/js-14.md delete mode 100644 docs/languages/javascript/js-15.md delete mode 100644 docs/languages/javascript/js-16.md delete mode 100644 docs/languages/javascript/js-17.md delete mode 100644 docs/languages/javascript/js-2.md delete mode 100644 docs/languages/javascript/js-3.md delete mode 100644 docs/languages/javascript/js-4.md delete mode 100644 docs/languages/javascript/js-5.md delete mode 100644 docs/languages/javascript/js-6.md delete mode 100644 docs/languages/javascript/js-7.md delete mode 100644 docs/languages/javascript/js-8.md delete mode 100644 docs/languages/javascript/js-9.md delete mode 100644 docs/languages/python/_category_.json delete mode 100644 docs/languages/python/py-1.md delete mode 100644 docs/languages/python/py-10.md delete mode 100644 docs/languages/python/py-11.md delete mode 100644 docs/languages/python/py-12.md delete mode 100644 docs/languages/python/py-13.md delete mode 100644 docs/languages/python/py-14.md delete mode 100644 docs/languages/python/py-15.md delete mode 100644 docs/languages/python/py-16.md delete mode 100644 docs/languages/python/py-17.md delete mode 100644 docs/languages/python/py-18.md delete mode 100644 docs/languages/python/py-2.md delete mode 100644 docs/languages/python/py-3.md delete mode 100644 docs/languages/python/py-4.md delete mode 100644 docs/languages/python/py-5.md delete mode 100644 docs/languages/python/py-6.md delete mode 100644 docs/languages/python/py-7.md delete mode 100644 docs/languages/python/py-8.md delete mode 100644 docs/languages/python/py-9.md delete mode 100644 docs/linked-list/CircularDoubly.png delete mode 100644 docs/linked-list/CircularLinkedList.png delete mode 100644 docs/linked-list/Doubly-linked-list-C.md delete mode 100644 docs/linked-list/DoublyLL.png delete mode 100644 docs/linked-list/Hare-Tortoise.md delete mode 100644 docs/linked-list/Intersection_Linked_list_python.md delete mode 100644 docs/linked-list/LinkedList.png delete mode 100644 docs/linked-list/Polynomial-Addition.md delete mode 100644 docs/linked-list/Practice-Problems.md delete mode 100644 docs/linked-list/_category_.json delete mode 100644 docs/linked-list/circular-doubly-linked-list.md delete mode 100644 docs/linked-list/doubly-linked-list.md delete mode 100644 docs/linked-list/floyds-cycle-detection.md delete mode 100644 docs/linked-list/gircular-linked-list.md delete mode 100644 docs/linked-list/intersection-linked-lists.md delete mode 100644 docs/linked-list/introduction-to-linked-list.md delete mode 100644 docs/linked-list/linked-list-approaches.md delete mode 100644 docs/linked-list/merge-two-sorted-list.md delete mode 100644 docs/linked-list/range-sum-of-linked-list.md delete mode 100644 docs/linked-list/remove-duplicates-from-sorted-list.md delete mode 100644 docs/machine-learning/AdaBoost.md delete mode 100644 docs/machine-learning/Autoencoders.md delete mode 100644 docs/machine-learning/BeamSearch.md delete mode 100644 docs/machine-learning/Convolutional_Neural_Network.md delete mode 100644 docs/machine-learning/DBSCAN_Clustering_Algorithm.md delete mode 100644 docs/machine-learning/Extra_Trees.md delete mode 100644 docs/machine-learning/GBM.md delete mode 100644 docs/machine-learning/Gaussian_Mixture_Model.md delete mode 100644 docs/machine-learning/Generative_Adversarial_Networks.md delete mode 100644 docs/machine-learning/HBOS.md delete mode 100644 docs/machine-learning/Hidden_Markov_Model.md delete mode 100644 docs/machine-learning/HierarchialClustering.md delete mode 100644 docs/machine-learning/Independent Component Analysis.md delete mode 100644 docs/machine-learning/K-Means_clustering.md delete mode 100644 docs/machine-learning/K-NearestNeighbours.md delete mode 100644 docs/machine-learning/LinearRegression.md delete mode 100644 docs/machine-learning/LogisticRegression.md delete mode 100644 docs/machine-learning/Long_Short_Term_Memory.md delete mode 100644 docs/machine-learning/PC_Visualizations.md delete mode 100644 docs/machine-learning/Recurrent_Neural_Network.md delete mode 100644 docs/machine-learning/Reinforcement_Learning.md delete mode 100644 docs/machine-learning/RidgeRegression.md delete mode 100644 docs/machine-learning/SDG.md delete mode 100644 docs/machine-learning/SVM.md delete mode 100644 docs/machine-learning/Singular_Value_Decomposition_Algorithm.md delete mode 100644 docs/machine-learning/Statistical_Anomaly_Detection.md delete mode 100644 docs/machine-learning/Time_Series_Forecasting_Algo.md delete mode 100644 docs/machine-learning/XGBoost.md delete mode 100644 docs/machine-learning/decisionTree.md delete mode 100644 docs/machine-learning/hierarchical-clustering-visualizations.md delete mode 100644 docs/machine-learning/naive-bayes.md delete mode 100644 docs/machine-learning/neuralNetworks.md delete mode 100644 docs/machine-learning/random-forest.md delete mode 100644 docs/machine-learning/regression_algorithm.md delete mode 100644 docs/machine-learning/supervised_learning_algo.md delete mode 100644 docs/machine-learning/support-vector-machine.md delete mode 100644 docs/machine-learning/t-SNE_Dimensionality_Reduction.md delete mode 100644 docs/machine-learning/unsupervised_learning_algo.md delete mode 100644 docs/programming-fundamentals/Arrays.md delete mode 100644 docs/programming-fundamentals/Conditionals.md delete mode 100644 docs/programming-fundamentals/Data_Structures.md delete mode 100644 docs/programming-fundamentals/Loops.md delete mode 100644 docs/programming-fundamentals/OOPS/oops-01.md delete mode 100644 docs/programming-fundamentals/OOPS/oops-02.md delete mode 100644 docs/programming-fundamentals/OOPS/oops-03.md delete mode 100644 docs/programming-fundamentals/OOPS/oops-04.md delete mode 100644 docs/programming-fundamentals/OOPS/oops-05.md delete mode 100644 docs/programming-fundamentals/OOPS/oops-06.md delete mode 100644 docs/programming-fundamentals/OOPS/oops-07.md delete mode 100644 docs/programming-fundamentals/OOPS/oops-08.md delete mode 100644 docs/programming-fundamentals/Variables.md delete mode 100644 docs/programming-fundamentals/_category_.json delete mode 100644 docs/programming-fundamentals/functions.md delete mode 100644 docs/sortings/Sortings.md delete mode 100644 docusaurus.config.js delete mode 100644 festhack.jpg delete mode 100644 girlscript.jpg delete mode 100644 java/Armstrong-Number-Checker.md delete mode 100644 java/Arrays/1.Easy/Find missing number.md delete mode 100644 java/Arrays/1.Easy/Remove Duplicates from Sorted Array.md delete mode 100644 java/Arrays/2.Medium/Kadane's Algorithm.md delete mode 100644 java/Arrays/2.Medium/Longest Subarray with sum K.md delete mode 100644 java/Arrays/3.Hard/Maximum Product Subarray.md delete mode 100644 java/Arrays/3.Hard/Reverse pairs.md delete mode 100644 java/LCM-GCD-Calculator.md delete mode 100644 java/Palindrome_number.md delete mode 100644 java/Palindrome_string.md delete mode 100644 java/Prime_number_checker.md delete mode 100644 java/Reverse_linked_list.md delete mode 100644 java/Simple-Calculator.md delete mode 100644 java/array-list.md delete mode 100644 java/fast-exponential.md delete mode 100644 java/inheritance.md delete mode 100644 java/isPowerOfTwo.md delete mode 100644 learn.md delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 plugins/my-plugin/index.js delete mode 100644 renovate.json delete mode 100644 sidebars.js delete mode 100644 src/components/AdsComponent/Ads.tsx delete mode 100644 src/components/AdsComponent/index.tsx delete mode 100644 src/components/AdsComponent/style.css delete mode 100644 src/components/ChallengeCard.tsx delete mode 100644 src/components/DSA/DP/Parsing A Boolean Expression.md delete mode 100644 src/components/DSA/arrays/ArrayVisualizations/index.tsx delete mode 100644 src/components/DSA/arrays/BubbleSortVisualization/BubbleSortVisualization.css delete mode 100644 src/components/DSA/arrays/BubbleSortVisualization/index.tsx delete mode 100644 src/components/DSA/arrays/HeapSortVisualization/index.tsx delete mode 100644 src/components/DSA/arrays/HeapSortVisualization/style.css delete mode 100644 src/components/DSA/arrays/InsertionSortVisualization/index.tsx delete mode 100644 src/components/DSA/arrays/InsertionSortVisualization/style.css delete mode 100644 src/components/DSA/arrays/MergeSortVisualization/index.tsx delete mode 100644 src/components/DSA/arrays/MergeSortVisualization/style.css delete mode 100644 src/components/DSA/arrays/QuickSortVisualization/index.tsx delete mode 100644 src/components/DSA/arrays/QuickSortVisualization/style.css delete mode 100644 src/components/DSA/arrays/SelectionSortVisualization/SelectionSortVisualization.css delete mode 100644 src/components/DSA/arrays/SelectionSortVisualization/index.tsx delete mode 100644 src/components/DSA/arrays/ShellSortVisualisation/Shellsort.css delete mode 100644 src/components/DSA/arrays/ShellSortVisualisation/index.tsx delete mode 100644 src/components/DSA/graphs/DijkstraVisualizations/index.tsx delete mode 100644 src/components/DSA/graphs/FloydWarshallVisualizations/index.tsx delete mode 100644 src/components/GiscusComponent/index.tsx delete mode 100644 src/components/Header.tsx delete mode 100644 src/components/Highlight/index.js delete mode 100644 src/components/Homepage/CallToActionSection.tsx delete mode 100644 src/components/Homepage/ContributeSection.tsx delete mode 100644 src/components/Homepage/FeaturesSection.tsx delete mode 100644 src/components/Homepage/GetInvolvedSection.tsx delete mode 100644 src/components/Homepage/HeroSection.tsx delete mode 100644 src/components/Homepage/HowItWorksSection.tsx delete mode 100644 src/components/Homepage/PopularAlgorithmsSection.tsx delete mode 100644 src/components/Homepage/TechnologiesSection.tsx delete mode 100644 src/components/Homepage/UserTestimonialsSection.tsx delete mode 100644 src/components/Homepage/index.tsx delete mode 100644 src/components/QuizCard.tsx delete mode 100644 src/components/Scroller/BottomToTop/BottomToTop.tsx delete mode 100644 src/components/Scroller/TopToBottom/TopToBottom.tsx delete mode 100644 src/components/Visualizing/index.tsx delete mode 100644 src/components/chatbot.jsx delete mode 100644 src/css/BottomToTop.module.css delete mode 100644 src/css/TopToBottom.module.css delete mode 100644 src/css/custom.css delete mode 100644 src/css/visualiezer.css delete mode 100644 src/data/challengeData.ts delete mode 100644 src/data/problemData.ts delete mode 100644 src/data/quizData.ts delete mode 100644 src/data/testimonialsData.ts delete mode 100644 src/data/topics.ts delete mode 100644 src/pages/License.md delete mode 100644 src/pages/about/index.tsx delete mode 100644 src/pages/blogs/index.tsx delete mode 100644 src/pages/challenges/challenge1.tsx delete mode 100644 src/pages/challenges/challenge2.tsx delete mode 100644 src/pages/challenges/challenge3.tsx delete mode 100644 src/pages/challenges/index.tsx delete mode 100644 src/pages/community/index.tsx delete mode 100644 src/pages/contact/index.tsx delete mode 100644 src/pages/contributors/index.tsx delete mode 100644 src/pages/dsa-interview/index.tsx delete mode 100644 src/pages/dsa-roadmap/index.tsx delete mode 100644 src/pages/faq/index.tsx delete mode 100644 src/pages/index.js delete mode 100644 src/pages/leaderboard/index.tsx delete mode 100644 src/pages/markdown-page.md delete mode 100644 src/pages/practice/index.tsx delete mode 100644 src/pages/quiz-solutions/array.md delete mode 100644 src/pages/quiz-solutions/b-trees.md delete mode 100644 src/pages/quiz-solutions/binary-search-trees.md delete mode 100644 src/pages/quiz-solutions/binary-trees.md delete mode 100644 src/pages/quiz-solutions/index.tsx delete mode 100644 src/pages/quiz-solutions/queues.md delete mode 100644 src/pages/quiz-solutions/red-black-trees.md delete mode 100644 src/pages/quiz-solutions/stack.md delete mode 100644 src/pages/quizes/arrays.tsx delete mode 100644 src/pages/quizes/b-tree.tsx delete mode 100644 src/pages/quizes/binary-search-tree.tsx delete mode 100644 src/pages/quizes/binary-tree.tsx delete mode 100644 src/pages/quizes/index.tsx delete mode 100644 src/pages/quizes/queue.tsx delete mode 100644 src/pages/quizes/queues.tsx delete mode 100644 src/pages/quizes/red-black-tree.tsx delete mode 100644 src/pages/quizes/stack.tsx delete mode 100644 src/pages/resources/index.tsx delete mode 100644 src/pages/roadmap/index.tsx delete mode 100644 src/pages/terms/index.tsx delete mode 100644 src/theme/Admonition/Icon/Danger.js delete mode 100644 src/theme/Admonition/Layout/index.js delete mode 100644 src/theme/CodeBlock/Line/index.js delete mode 100644 src/theme/CodeBlock/Line/styles.module.css delete mode 100644 src/theme/Footer/index.tsx delete mode 100644 src/theme/MDXComponents.js delete mode 100644 src/theme/Mermaid/index.js delete mode 100644 src/theme/ReactLiveScope/components.js delete mode 100644 src/theme/ReactLiveScope/index.js delete mode 100644 src/theme/Root.js delete mode 100644 static/.nojekyll delete mode 100644 static/ads.txt delete mode 100644 static/images/avatar-2.jpg delete mode 100644 static/images/avatar1.jpg delete mode 100644 static/images/avatar2.jpg delete mode 100644 static/images/avatar3.jpg delete mode 100644 static/images/docusaurus.svg delete mode 100644 static/images/github.svg delete mode 100644 static/images/jsx.svg delete mode 100644 static/images/mission.jpg delete mode 100644 static/images/node-js.svg delete mode 100644 static/images/tailwindcss.svg delete mode 100644 static/images/team-member-1.jpg delete mode 100644 static/images/team-member-2.jpg delete mode 100644 static/images/team-member-3.jpg delete mode 100644 static/images/team-member-4.jpg delete mode 100644 static/images/team-member-5.jpg delete mode 100644 static/images/tsx.svg delete mode 100644 static/img/docusaurus-social-card.jpg delete mode 100644 static/img/docusaurus.png delete mode 100644 static/img/favicon.ico delete mode 100644 static/img/logo.png delete mode 100644 static/img/logo.svg delete mode 100644 static/img/undraw_docusaurus_mountain.svg delete mode 100644 static/img/undraw_docusaurus_react.svg delete mode 100644 static/img/undraw_docusaurus_tree.svg delete mode 100644 static/logo/algo-1.png delete mode 100644 static/logo/algo-3.png delete mode 100644 static/logo/algo-banner.png delete mode 100644 static/logo/algo.png delete mode 100644 static/logo/dsa.png delete mode 100644 static/logo/ft-copy.png delete mode 100644 static/logo/logo.png delete mode 100644 static/logo/neural.png delete mode 100644 tailwind.config.js diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 294468723..000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @ajay-dhangar \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml deleted file mode 100644 index 088e2d391..000000000 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: "🐞 Bug Report" -description: "Report a bug or unexpected behavior in Algo." -title: "[Bug]: " -labels: ["bug", "status: needs triage"] -body: - - type: markdown - attributes: - value: | - Thank you for taking the time to report a bug in **Algo**. Please fill out the details below to help us understand and resolve the issue as quickly as possible. - - - type: input - id: bug_summary - attributes: - label: "Bug Summary" - description: "Provide a summary of the bug." - placeholder: "E.g., Array index out-of-bounds error in binary search algorithm" - validations: - required: true - - - type: textarea - id: bug_description - attributes: - label: "Bug Description" - description: "Describe the bug in detail. Include what you expected to happen and what happened." - placeholder: "Provide a detailed description of the bug, including steps to reproduce..." - validations: - required: true - - - type: textarea - id: steps_to_reproduce - attributes: - label: "Steps to Reproduce" - description: "List the steps to reproduce the bug. Provide as much detail as possible." - placeholder: | - 1. Go to '...' - 2. Click on '...' - 3. Scroll down to '...' - 4. See error - validations: - required: true - - - type: textarea - id: expected_behavior - attributes: - label: "Expected Behavior" - description: "Describe what you expected to happen when following the steps above." - placeholder: "Describe the expected behaviour..." - validations: - required: true - - - type: textarea - id: actual_behavior - attributes: - label: "Actual Behavior" - description: "Describe what happened instead." - placeholder: "Describe the actual behaviour..." - - - type: textarea - id: screenshots - attributes: - label: "Screenshots or Logs (Optional)" - description: "If applicable, add screenshots or log files to help explain the problem." - placeholder: "Provide links or attachments..." - - - type: dropdown - id: severity - attributes: - label: "Severity" - description: "How severe is the bug?" - options: - - "Critical - prevents the use of the system" - - "Major - impacts significant functionality" - - "Minor - cosmetic or minor issue" - validations: - required: true - - - type: checkboxes - id: environment - attributes: - label: "Environment" - description: "Check all environments where the bug occurs." - options: - - label: "Local Development" - - label: "Staging" - - label: "Production" - - label: "Other" - - - type: textarea - id: system_information - attributes: - label: "System Information (Optional)" - description: "Provide details about the environment where the bug occurred (e.g., OS, browser, Node.js version)." - placeholder: "OS: Windows 10, Browser: Chrome, Node.js: v14.17.0..." - - - type: markdown - attributes: - value: | - **Thank you for reporting this bug!** We will review your report and get back to you soon. 🐛 diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 948cadf50..000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,10 +0,0 @@ -contact_links: - - name: "🚀 Join the Algo Community" - url: "https://forms.gle/8EpYfRgVmrDxXAio6" - about: > - ✨ If you would like to join the Algo community, please fill out the form to request an invitation. - Provide details about your skills and motivation for joining. We will review your request and - send an invitation if approved. - - name: "👥 Join the Algo Community on LinkedIn" - url: "https://www.linkedin.com/groups/14536479/" - about: "🌐 Join our LinkedIn group to connect with fellow developers, discuss data structures and algorithms, and grow your skills together." diff --git a/.github/ISSUE_TEMPLATE/custom.yml b/.github/ISSUE_TEMPLATE/custom.yml deleted file mode 100644 index 60581b740..000000000 --- a/.github/ISSUE_TEMPLATE/custom.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: "⚙️ Custom Issue" -description: "Submit a custom issue or suggestion for Algo." -title: "[Custom]: " -labels: ["custom", "status: needs triage"] -body: - - type: markdown - attributes: - value: | - Thank you for submitting a custom issue for **Algo**! This template is intended for any requests or suggestions that don't fit into the bug report, feature request, or documentation categories. - - - type: input - id: issue_summary - attributes: - label: "Issue Summary" - description: "Provide a summary of the custom issue." - placeholder: "E.g., Enhancement suggestion for search functionality" - validations: - required: true - - - type: textarea - id: issue_description - attributes: - label: "Issue Description" - description: "Describe the issue or suggestion in detail." - placeholder: "Provide a detailed description of the custom issue, including the context, use case, or scenario in which this issue occurs or would be relevant..." - validations: - required: true - - - type: textarea - id: proposed_solution - attributes: - label: "Proposed Solution (Optional)" - description: "If you have any ideas or suggestions for how to address this issue, describe them here." - placeholder: "Describe your proposed solution or approach..." - - - type: dropdown - id: priority - attributes: - label: "Priority" - description: "How important is this issue to you?" - options: - - "High - Requires urgent attention" - - "Medium - Should be addressed soon" - - "Low - Can be addressed later" - validations: - required: true - - - type: checkboxes - id: category - attributes: - label: "Category" - description: "Select the category that best describes the issue." - options: - - label: "Enhancement" - - label: "Refactor" - - label: "Security" - - label: "Design" - - label: "Other" - - - type: textarea - id: additional_context - attributes: - label: "Additional Context (Optional)" - description: "Add any other context or information that might be relevant to this issue." - placeholder: "Provide any extra details, screenshots, or references that could help with understanding the issue..." - - - type: markdown - attributes: - value: | - **Thank you for your suggestion!** We appreciate your input and will review your custom issue promptly. 📝 diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml deleted file mode 100644 index 3c817619e..000000000 --- a/.github/ISSUE_TEMPLATE/documentation.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: 📚 Documentation -description: Report an issue related to documentation -labels: [documentation, 'docs: algo contributors'] -body: - - type: markdown - attributes: - value: | - This template is strictly used for documentation requests, including: - - - Documenting new topics or features; - - Elaborating on a specific subject in the DSA content; - - Updating or fixing existing content; - - Enhancing code examples or explanations; - - Anything else that involves documentation but does not change the codebase. - - Before submitting an issue, please ensure: - - - You have checked the existing documentation to confirm the information is missing or needs updating. - - For issues caused by incorrect behavior in code, use the "bug" template instead. - - If you are confident that your documentation request meets these criteria, you may also submit a pull request directly. - - - type: checkboxes - attributes: - label: Have you read the Contributing Guidelines on issues? - options: - - label: I have read the [Contributing Guidelines on issues](https://github.com/ajay-dhangar/algo/blob/main/CONTRIBUTING.md). - required: true - - - type: textarea - attributes: - label: Description - description: A clear and concise description of what the documentation issue is. - validations: - required: true - - - type: checkboxes - attributes: - label: Self-service - description: | - If you're willing to work on this documentation request, please check the box below. This indicates to the maintainers that you're already working on it. - If you check the box, please send a pull request within 7 days to avoid reassignment. - options: - - label: I'd be willing to address this documentation request myself. diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml deleted file mode 100644 index fec13c072..000000000 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: "🚀 Feature Request" -description: "Suggest a new feature or enhancement for Algo." -title: "[Feature]: " -labels: ["enhancement", "feature request"] -body: - - type: markdown - attributes: - value: | - Thank you for suggesting a new feature for **Algo**! Please fill out the information below to help us understand your request better. - - - type: input - id: feature_name - attributes: - label: "Feature Name" - description: "Provide a brief name for the feature you're requesting." - placeholder: "E.g., Add binary search algorithm visualization" - validations: - required: true - - - type: textarea - id: feature_description - attributes: - label: "Feature Description" - description: "Provide a detailed description of the feature. Explain what it does, why it's useful, and any additional context." - placeholder: "Explain the feature and its use case..." - validations: - required: true - - - type: textarea - id: motivation - attributes: - label: "Motivation" - description: "Describe why this feature should be added to Algo. How does it benefit users?" - placeholder: "Provide the motivation behind this feature..." - validations: - required: true - - - type: textarea - id: implementation_suggestions - attributes: - label: "Implementation Suggestions (Optional)" - description: "Share any suggestions on how this feature could be implemented. Include any libraries or tools that might help." - placeholder: "Provide implementation suggestions or steps..." - - - type: dropdown - id: feature_type - attributes: - label: "Feature Type" - description: "Select the type of feature request." - options: - - "New Algorithm" - - "Documentation Enhancement" - - "UI/UX Improvement" - - "Performance Optimization" - - "Other" - validations: - required: true - - - type: checkboxes - id: additional_resources - attributes: - label: "Does this feature require additional resources?" - description: "Check all that apply." - options: - - label: "Additional Documentation" - - label: "Third-Party Libraries" - - label: "UI/UX Design" - - label: "Other" - - - type: textarea - id: references - attributes: - label: "References (Optional)" - description: "Provide links to any relevant resources, documentation, or examples that can help understand the feature request." - placeholder: "Add links to relevant references, resources, or documentation..." - - - type: markdown - attributes: - value: | - **Thank you for taking the time to suggest this feature!** Our team will review your request and get back to you soon. 🚀 diff --git a/.github/ISSUE_TEMPLATE/idea.yml b/.github/ISSUE_TEMPLATE/idea.yml deleted file mode 100644 index 86292caa7..000000000 --- a/.github/ISSUE_TEMPLATE/idea.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: "💡 Idea" -description: "Submit an idea for Algo." -title: "[Idea]: " -labels: ["idea", "enhancement"] -body: - - type: markdown - attributes: - value: | - This template is for submitting new ideas or enhancements for Algo. - - - type: input - id: idea_title - attributes: - label: "Idea Title" - description: "Provide a short title for your idea." - placeholder: "E.g., Add a new sorting algorithm visualization" - validations: - required: true - - - type: textarea - id: idea_description - attributes: - label: "Idea Description" - description: "Describe your idea in detail. Explain the problem it solves or the value it adds." - placeholder: "Provide a detailed description of your idea..." - validations: - required: true - - - type: checkboxes - id: benefits - attributes: - label: "Potential Benefits" - description: "What benefits does your idea bring?" - options: - - label: "Improves user experience" - - label: "Enhances learning" - - label: "Adds a new feature" - - label: "Improves code quality" - - label: "Other" - - - type: textarea - id: implementation_suggestions - attributes: - label: "Implementation Suggestions (Optional)" - description: "If you have any suggestions on how to implement your idea, share them here." - placeholder: "Provide your thoughts on implementation..." diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 8b15c7e94..000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,22 +0,0 @@ -## 📥 Pull Request - -### Description -Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. - -Fixes # (issue number) - -### Type of change - -- [ ] Bug fix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] Documentation update - -### Checklist: - -- [ ] My code follows the style guidelines of this project -- [ ] I have performed a self-review of my code -- [ ] I have commented my code, particularly in hard-to-understand areas -- [ ] I have added tests that prove my fix is effective or that my feature works -- [ ] New and existing unit tests pass locally with my changes -- [ ] Any dependent changes have been merged and published in downstream modules diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index f6cafd71d..000000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1,19 +0,0 @@ -name-template: 'v$NEXT_PATCH_VERSION' -tag-template: 'v$NEXT_PATCH_VERSION' -categories: - - title: '🚀 New Features' - labels: - - 'feature' - - title: '🐛 Bug Fixes' - labels: - - 'bug' - - title: '📖 Documentation' - labels: - - 'documentation' - - title: '🛠 Maintenance' - labels: - - 'chore' -change-template: '- $TITLE @$AUTHOR (#$NUMBER)' -template: | - ## What's Changed - $CHANGES diff --git a/.github/workflows/add-contributor.yml b/.github/workflows/add-contributor.yml deleted file mode 100644 index fbd706baa..000000000 --- a/.github/workflows/add-contributor.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Update Contributors in README - -on: - push: - branches: - - main - workflow_dispatch: - -jobs: - update-contributors: - runs-on: ubuntu-latest - name: Automate Contributors Update in README - permissions: - contents: write - pull-requests: write - - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Update Contributors List in README - uses: akhilmhdh/contributors-readme-action@v2.3.10 - with: - commit_message: "update contributors list in README" - committer_username: "ajay-dhangar" - committer_email: "99037494+ajay-dhangar@users.noreply.github.com" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/autolabel.yml b/.github/workflows/autolabel.yml deleted file mode 100644 index 89476652c..000000000 --- a/.github/workflows/autolabel.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Auto Label Issue - -on: - issues: - types: [opened, reopened, edited] - -jobs: - label_issue: - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - name: Label Issue - uses: actions/github-script@v6 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - const issue = context.payload.issue; - const issueBody = issue.body ? issue.body.toLowerCase() : ''; - const issueTitle = issue.title.toLowerCase(); - - // Add gssoc-ext and hacktoberfest labels to all issues - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issue.number, - // labels: ['gssoc-ext', 'hacktoberfest-accepted', 'level1'] - labels: ['in-review'] - }); - - const addLabel = async (label) => { - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issue.number, - labels: [label] - }); - }; diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 82b8083f8..000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,81 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - schedule: - - cron: '17 6 * * 4' - -jobs: - analyze: - name: Analyze - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners - # Consider using larger runners for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} - timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'javascript-typescript' ] - # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] - # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml deleted file mode 100644 index 0d4a01360..000000000 --- a/.github/workflows/dependency-review.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Dependency Review Action -# -# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. -# -# Source repository: https://github.com/actions/dependency-review-action -# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement -name: 'Dependency Review' -on: [pull_request] - -permissions: - contents: read - -jobs: - dependency-review: - runs-on: ubuntu-latest - steps: - - name: 'Checkout Repository' - uses: actions/checkout@v4 - - name: 'Dependency Review' - uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 107a27785..000000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Deploy to GitHub Pages - -on: - push: - branches: - - main - # Review GitHub Actions docs if you want to further define triggers, paths, etc. - # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on - -jobs: - build: - name: Build Algo - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-node@v4 - with: - node-version: 18 - cache: npm - - - name: Install dependencies - run: npm ci - - - name: Build website - run: npm run build - - - name: Upload Build Artifact - uses: actions/upload-pages-artifact@v3 - with: - path: build - - deploy: - name: Deploy to GitHub Pages - needs: build - - # Grant GITHUB_TOKEN the permissions required to make a Pages deployment - permissions: - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source - - # Deploy to the github-pages environment - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - - runs-on: ubuntu-latest - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/issue_close_open.yml b/.github/workflows/issue_close_open.yml deleted file mode 100644 index c6e8f511e..000000000 --- a/.github/workflows/issue_close_open.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Issue Auto Comment - -# Created by @smog-root - -on: - issues: - types: [opened, closed] - -jobs: - comment: - runs-on: ubuntu-latest - steps: - - name: Add a comment when an issue is opened - if: github.event.action == 'opened' - uses: actions-ecosystem/action-create-comment@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - issue_number: ${{ github.event.issue.number }} - body: "👋 Thanks for opening this issue! We appreciate your contribution. Please make sure you’ve provided all the necessary details and screenshots, and don't forget to follow our Guidelines and Code of Conduct. Happy coding! 🚀 -" - - - name: Add a comment when an issue is closed - if: github.event.action == 'closed' - uses: actions-ecosystem/action-create-comment@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - issue_number: ${{ github.event.issue.number }} - body: " ✅ This issue has been successfully closed. Thank you for your contribution and helping us improve the project! If you have any more ideas or run into other issues, feel free to open a new one. Happy coding! 🚀" \ No newline at end of file diff --git a/.github/workflows/lighthouse-report.yml b/.github/workflows/lighthouse-report.yml deleted file mode 100644 index baa94f26f..000000000 --- a/.github/workflows/lighthouse-report.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Lighthouse Report - -on: - pull_request_target: - branches: - - main - - algo-v** - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - lighthouse-report: - permissions: - pull-requests: write # for marocchino/sticky-pull-request-comment - name: Lighthouse Report - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4.2.2 - - - name: Use Node.js - uses: actions/setup-node@v4.1.0 - with: - node-version: 20 - - - name: Install dependencies - run: npm ci - - - name: Build website - run: npm run build - - - name: Audit URLs using Lighthouse - id: lighthouse_audit - uses: treosh/lighthouse-ci-action@12.1.0 - with: - urls: | - http://localhost:3000/algo/ - http://localhost:3000/algo/docs - http://localhost:3000/algo/blog - configPath: ./.github/workflows/lighthouserc.json - uploadArtifacts: true - temporaryPublicStorage: true - - - name: Format lighthouse score - id: format_lighthouse_score - uses: actions/github-script@v7.0.1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const results = ${{ steps.lighthouse_audit.outputs.manifest }} - const links = ${{ steps.lighthouse_audit.outputs.links }} - const createLighthouseReport = (await import(`${process.env.GITHUB_WORKSPACE}/admin/scripts/formatLighthouseReport.js`)).default; - const comment = createLighthouseReport({ results, links }); - core.setOutput("comment", comment); - - - name: Add Lighthouse stats as comment - id: comment_to_pr - uses: marocchino/sticky-pull-request-comment@v2.9.0 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - number: ${{ github.event.pull_request.number }} - header: lighthouse - message: ${{ steps.format_lighthouse_score.outputs.comment }} diff --git a/.github/workflows/lighthouserc.json b/.github/workflows/lighthouserc.json deleted file mode 100644 index d07a9fed5..000000000 --- a/.github/workflows/lighthouserc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "ci": { - "collect": { - "startServerCommand": "npm run serve", - "startServerReadyPattern": "Serving", - "startServerReadyTimeout": 10000, - "numberOfRuns": 1, - "settings": { - "skipAudits": [ - "robots-txt", - "canonical", - "tap-targets", - "is-crawlable", - "works-offline", - "offline-start-url" - ] - } - } - } - } \ No newline at end of file diff --git a/.github/workflows/pr_merge.yaml b/.github/workflows/pr_merge.yaml deleted file mode 100644 index 06156fb8d..000000000 --- a/.github/workflows/pr_merge.yaml +++ /dev/null @@ -1,34 +0,0 @@ -name: Merge Thank You - -# Created by @smog-root - -on: - pull_request_target: - types: [closed] # Trigger when a PR is closed - -permissions: - issues: write - pull-requests: write - -jobs: - post_merge_message: - if: github.event.pull_request.merged == true # Only run if the PR was merged - runs-on: ubuntu-latest - - steps: - - name: Post thank you message - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} # Ensure token is used - script: | - const prNumber = context.payload.pull_request.number; - const owner = context.repo.owner; - const repo = context.repo.repo; - - // Post a thank you message upon PR merge - await github.rest.issues.createComment({ - owner: owner, - repo: repo, - issue_number: prNumber, - body: `🎉🎉 Thank you for your contribution! Your PR #${prNumber} has been merged! 🎉🎉` - }); \ No newline at end of file diff --git a/.github/workflows/pr_raise.yml b/.github/workflows/pr_raise.yml deleted file mode 100644 index 57123f9ac..000000000 --- a/.github/workflows/pr_raise.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Auto Comment on PR - -# Created by @smog-root - -on: - pull_request_target: - types: [opened] - -permissions: - issues: write - pull-requests: write - -jobs: - comment: - runs-on: ubuntu-latest - permissions: - pull-requests: write - steps: - - name: Add Comment to Pull Request - run: | - COMMENT=$(cat < "$ERROR_MESSAGE_FILE" - fi - - # Check for issue reference in the description - ISSUE_PATTERN="(Fixes|Close|Closes|Closed|Fix|Fixed|Resolve|Resolves) #[0-9]+" - if [[ ! "$PR_DESCRIPTION" =~ $ISSUE_PATTERN ]]; then - echo "Invalid or missing issue reference" - PR_VALID="false" - echo '❌ Error: PR must reference an issue with the format Fixes ,Close ,Closes ,Closed ,Fix ,Fixed ,Resolve ,Resolves #Issue_Number' > "$ERROR_MESSAGE_FILE" - fi - - # If both checks pass - if [ "$PR_VALID" == "true" ]; then - echo '✅ Success: PR is valid!' > "$SUCCESS_MESSAGE_FILE" - fi - - # Save the outputs to environment files - echo "PR_VALID=$PR_VALID" >> $GITHUB_ENV - echo "ERROR_MESSAGE=$(cat $ERROR_MESSAGE_FILE)" >> $GITHUB_ENV - echo "SUCCESS_MESSAGE=$(cat $SUCCESS_MESSAGE_FILE)" >> $GITHUB_ENV - - - name: Post comment on PR - uses: actions/github-script@v6 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const prValid = process.env.PR_VALID; - const errorMessage = process.env.ERROR_MESSAGE; - const successMessage = process.env.SUCCESS_MESSAGE; - const prNumber = context.payload.pull_request.number; - - if (prValid === 'false') { - github.rest.issues.createComment({ - issue_number: prNumber, - owner: context.repo.owner, - repo: context.repo.repo, - body: errorMessage - }); - core.setFailed(errorMessage); - } else { - github.rest.issues.createComment({ - issue_number: prNumber, - owner: context.repo.owner, - repo: context.repo.repo, - body: successMessage - }); - } - - - name: Fail if validation failed - if: env.PR_VALID == 'false' - run: exit 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index a76d117c7..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Release - -on: - push: - tags: - - 'v*.*.*' # Trigger the workflow on tags like v1.0.0, v1.1.0, etc. - -jobs: - release: - name: Build and Release Algo Site - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 - - - name: Install dependencies - run: npm install - - - name: Build Algo site - run: npm run build - - - name: Generate Release Notes - id: release_notes - uses: release-drafter/release-drafter@v5 - with: - config-name: '.github/release-drafter.yml' # Requires a Release Drafter config - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - id: create_release - uses: ncipollo/release-action@v1 - with: - tag: ${{ github.ref_name }} # Tag name from the push event - release_name: ${{ github.ref_name }} - body: ${{ steps.release_notes.outputs.body }} - draft: false - prerelease: false - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload Built Site (Optional) - uses: actions/upload-release-asset@v1 - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: build # Directory containing built static site files (Algo build output) - asset_name: algo-site.zip - asset_content_type: application/zip - - # Optionally, you could add additional jobs here to deploy to GitHub Pages if needed diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index a2b14148b..000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: "Mark Stale Issues and PRs" - -on: - schedule: - - cron: "0 0 * * *" - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - name: "Close Stale Issues and PRs" - uses: actions/stale@v8 - with: - days-before-stale: 30 - days-before-close: 7 - stale-issue-message: "This issue has been automatically marked as stale due to inactivity." - close-issue-message: "This issue is now closed due to inactivity." - stale-pr-message: "This pull request has been automatically marked as stale due to inactivity." - close-pr-message: "This pull request is now closed due to inactivity." - exempt-issue-labels: "pinned" - exempt-pr-labels: "pinned" - only-labels: "" - remove-stale-when-updated: true diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml deleted file mode 100644 index a4a7d19c0..000000000 --- a/.github/workflows/test-deploy.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Test deployment - -on: - pull_request: - branches: - - main - # Review GitHub Actions docs if you want to further define triggers, paths, etc. - # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on - -jobs: - test-deploy: - name: Test deployment - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-node@v4 - with: - node-version: 18 - cache: npm - - - name: Install dependencies - run: npm ci - - - name: Test build website - run: npm run build diff --git a/.gitignore b/.gitignore deleted file mode 100644 index b2d6de306..000000000 --- a/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# Dependencies -/node_modules - -# Production -/build - -# Generated files -.docusaurus -.cache-loader - -# Misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 5fe504136..000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,128 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -Email. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index b50371949..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,153 +0,0 @@ -# Contributing to Algo - -Thank you for your interest in contributing to **Algo**! We welcome contributions from everyone, whether you're a beginner or an experienced developer. Contributions can include adding new algorithms, improving documentation, fixing bugs, or enhancing the user experience. This guide will help you get started. - -## Resources for Guidance -Here are some resources that may be helpful as you contribute to Algo: -- [Docusaurus Documentation](https://docusaurus.io/docs/docs-introduction) -- [React.js Documentation](https://react.dev/learn) -- [Markdown Guide](https://www.markdownguide.org/) -- [MDX Documentation](https://mdxjs.com/docs/) -- [Mermaid Documentation](https://mermaid.js.org/) -- [KaTeX Math Rendering Documentation](https://katex.org/docs/supported.html) -- [Math Equations](https://docusaurus.io/docs/markdown-features/math-equations) - -## How to Contribute - -### 1. Fork the Repository ([Video 1](https://www.loom.com/share/4c5f309a28c444caa4e70557669979f6?sid=88202acf-3ab8-4321-bcf2-3ced94215994)) -Start by forking the repository to your GitHub account. This creates a copy of the repository under your account. - -### 2. Clone Your Fork -Clone the repository to your local machine using: - -```bash -$ git clone https://github.com//algo.git -``` - -### 3. Create a New Branch ([Video 2](https://www.loom.com/share/74493008c617419ea1a1f69755124dd8?sid=28379156-ff84-4e57-90a9-234b4ba15160)) -Create a branch for your contribution: - -```bash -$ git checkout -b -``` - -### 4. Make Your Changes ([Video 3](https://www.loom.com/share/ea1a931b8f9a492a8994ca3d006a4526?sid=0b889369-23a4-42c7-a61e-7e7de1474494), [Video 4](https://www.loom.com/share/55b170e45b7d4cbdb4fa443b84d03a3c?sid=7a4c1db8-ae74-4a05-815c-ca6f30f8c5c4)) -Make your changes, which could include: -- Adding new algorithms -- Improving existing documentation -- Creating new documentation pages -- Fixing bugs - -### 5. Writing Documentation for Algo -If your contribution involves documentation, here’s how to write effective content using Docusaurus: - -#### a. Markdown & MDX -- Documentation should be written in Markdown (`.md`) or MDX (`.mdx`), which supports JSX syntax. -- MDX allows you to use React components inside Markdown files. This is helpful for adding interactive elements or custom components. - -#### b. Content Structure - -![image](https://github.com/user-attachments/assets/a3567a71-6ca5-4f78-b736-59f2109440f5) - -Each documentation file should start with a front-matter section for Docusaurus to recognize the page: - -```md ---- -id: -title: -sidebar_label: -sidebar_position: -description: -tags: [, ] ---- -``` -- **id**: A unique identifier for the page. -- **title**: The page title. -- **sidebar_label**: The label displayed in the sidebar. -- **sidebar_position**: Order of the page in the sidebar. -- **description**: A short description of the page content. -- **tags**: Tags for categorizing content. - -#### c. Using Headings -- Use `#` for the main title, `##` for subsections, and `###` for sub-subsections. -- Ensure headings follow a logical order. - -#### d. Adding Code Blocks -- Use fenced code blocks for code snippets: - - ````md - ```python - def binary_search(arr, target): - low, high = 0, len(arr) - 1 - while low <= high: - mid = (low + high) // 2 - if arr[mid] == target: - return mid - elif arr[mid] < target: - low = mid + 1 - else: - high = mid - 1 - return -1 - ``` - ```` - -#### e. Adding Math Formulas -- Use KaTeX for rendering math expressions: - - ```md - $$ E = mc^2 $$ - ``` -- Refer to the [KaTeX documentation](https://katex.org/docs/supported.html) for supported features. - -#### f. Diagrams and Visuals with Mermaid -- Create diagrams using Mermaid syntax: - - ````md - ```mermaid - graph TD; - A-->B; - A-->C; - B-->D; - C-->D; - ``` - ```` - -#### g. Using React Components -- Import React components for interactivity: - - ```jsx - import MyComponent from '@site/src/components/MyComponent'; - - - ``` - -### 6. Commit Your Changes ([Video 5](https://www.loom.com/share/47d2ba8e35fd4382979899fe21c29974?sid=8b5a3af6-5a80-4025-b045-76e64ff9a839)) -Commit your changes with a descriptive message: - -```bash -$ git commit -m "Added algorithm for [algorithm-name]" -``` - -### 7. Push to Your Fork -Push your changes to the forked repository: - -```bash -$ git push origin -``` - -### 8. Create a Pull Request -Go to the original repository and create a Pull Request (PR). Provide a clear description of what was added or changed and why. Reference any related issues in your PR description. - -## Code Style and Quality -- Keep your code clean and readable. -- Follow standard coding conventions for the language used. -- Add comments for complex code to help others understand. - -## Contribution Guidelines -- Make sure your contributions align with the project’s goals and guidelines. -- Keep PRs focused on a single issue; avoid making unrelated changes. -- Respect the repository structure and follow best practices. - ---- - -Thank you for contributing! Let's build Algo together and create an amazing learning platform for mastering Data Structures and Algorithms. ✨ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index fbbae7664..000000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Ajay Dhangar - -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 deleted file mode 100644 index 653dcca76..000000000 --- a/README.md +++ /dev/null @@ -1,1448 +0,0 @@ -# [Algo](https://ajay-dhangar.github.io/algo/) - Open Source Algorithm Repository - -hit counter - -## introduction -Welcome to **Algo**, an open-source project that provides developers with algorithmic solutions and resources. Whether you're a beginner or an experienced coder, you can contribute, learn, and grow with us! 🚀 - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
🌟 Stars🍴 Forks🐛 Issues🔔 Open PRs🔕 Close PRs🛠 Languages🌐 Contributors
StarsForksIssuesOpen Pull RequestsClose Pull RequestsGitHub language countGitHub contributors
-
-
- -## 🚀Featured In - - - - - - - - - - - - - - - - - - - - - - -
Event LogoEvent NameEvent DescriptionStatus
GSSoC 24GSSoC'24 ExtdGSSoC'24 Extd is a one-month open-source Program conducted by the GirlScript Foundation. It is an initiative to introduce more beginners to Open-Source Software Development.Active
Hacktoberfest 2024Hacktoberfest 2024Hacktoberfest is a month-long celebration of open source software run by DigitalOcean, GitHub, and Twilio. It encourages contributions to open source projects and promotes a global community of developers.Excluded
- -
- - -## 🌐 Demo Links - -- [Demo](https://ajay-dhangar.github.io/algo/) - - -## Table of Contents - -- [Algo - Open Source Algorithm Repository](#algo---open-source-algorithm-repository) - - [introduction](#introduction) - - [🚀Featured In](#featured-in) - - [Table of Contents](#table-of-contents) - - [Project Overview](#project-overview) - - [Pick up Topics](#pick-up-topics) - - [Features](#features) - - [Website](#website) - - [Installation](#installation) - - [Local Development](#local-development) - - [Build](#build) - - [Deployment](#deployment) - - [Using SSH:](#using-ssh) - - [Not using SSH:](#not-using-ssh) - - [Contributing](#contributing) - - [Contributors ✨](#contributors-) - - [Stargazers](#stargazers) - - [Forkers](#forkers) - - [Resources for Guidance](#resources-for-guidance) - - -## Project Overview - -Algo provides a collection of well-documented algorithmic solutions written in various programming languages, covering a range of topics like sorting, searching, dynamic programming, and more. - -### Pick up Topics - -- [DSA Roadmap](https://roadmap.sh/datastructures-and-algorithms) - -We aim to: -- Create an extensive library of algorithms in different languages -- Help developers learn algorithmic problem-solving -- Foster open-source contribution and collaboration - -## Features - -- **Multi-language Support**: Algorithms in multiple programming languages -- **Beginner-Friendly**: Well-structured, easy-to-understand explanations -- **Open Source Contributions**: Welcoming developers at all levels to contribute -- **Community Forum**: A new interactive platform where developers can ask questions, share ideas, and collaborate in real-time. This forum will help bridge the gap between beginners and experts, allowing for deeper engagement and problem-solving. - -## Website - -This website is built using [Docusaurus 3](https://docusaurus.io/), a modern static website generator. - -## Installation - -```bash - npm install -``` - -## Local Development - -```bash - npm start -``` - -This command starts a local development server and opens a browser window. Most changes are reflected live without having to restart the server. - -## Build - -```bash - npm run build -``` - -This command generates static content into the `build` directory, which can be served using any static content hosting service. - -## Deployment - -### Using SSH: - -```bash - USE_SSH=true npm run deploy -``` - -### Not using SSH: - -```bash - GIT_USER= npm run deploy -``` - -If you are using GitHub Pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. - -## Contributing - -We welcome contributions from developers of all experience levels. For guidelines, please see the [CONTRIBUTING.md](./CONTRIBUTING.md) file. - -## Contributors ✨ - -Thanks to these amazing people who have contributed to the **Algo** project: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - ajay-dhangar -
- Ajay Dhangar -
-
- - shravya312 -
- Shravya H Jain -
-
- - pavitraag -
- Pavitraa G -
-
- - KapuluruBhuvaneswariVspdbct -
- Bhuvaneswari Kapuluru -
-
- - yashksaini-coder -
- Yash Kumar Saini -
-
- - priyashuu -
- Priya -
-
- - AbhijitMotekar99 -
- Abhijit Motekar -
-
- - mahaveergurjar -
- Mahaveer Gurjar -
-
- - Ankitha2130 -
- Ankitha R -
-
- - inkerton -
- Janvi -
-
- - ananyag309 -
- Ananya Gupta -
-
- - Riyachauhan11 -
- Riya Chauhan -
-
- - haseebzaki-07 -
- Haseeb Zaki -
-
- - T-Rahul-prabhu-38 -
- t rahul prabhu -
-
- - kjl98 -
- Kajal Ahirwar -
-
- - nishant4500 -
- Nishant Dwivedi -
-
- - Gopal0Gupta -
- Gopal Gupta -
-
- - Meetpidev -
- Meet Shah -
-
- - shuvojitss -
- Shuvojit Samanta -
-
- - riyaa060 -
- riyaa060 -
-
- - Mahak-Codes -
- Mahak -
-
- - IkkiOcean -
- Vivek Prakash -
-
- - PradeepFSTdhane123 -
- Pradeep dhane -
-
- - PrAyAg9 -
- Prayag Thakur -
-
- - AE-Hertz -
- Abhinandan -
-
- - Mahateaa -
- Mahathi -
-
- - MithanshuHedau -
- Mithanshu Hedau -
-
- - Shariq2003 -
- Shariq -
-
- - J-B-Mugundh -
- Mugundh J B -
-
- - pratheekv39 -
- V Pratheek -
-
- - monishkumardvs -
- Dvs monish kumar -
-
- - shriyadindi -
- Shriya Dindi -
-
- - aditiverma-21 -
- Aditi Verma -
-
- - Alpha1zln -
- SHREYAS YADUVANSHI -
-
- - Rashigera -
- Rashigera -
-
- - Abhishek2634 -
- Abhishek Farshwal -
-
- - Subashree-selvaraj -
- subashree -
-
- - KashishJuneja101003 -
- Kashish Juneja -
-
- - T-Fathima -
- Tatheer Fathima -
-
- - kRajoria121 -
- Kundan Rajoria -
-
- - Mansi07sharma -
- Mansi07sharma -
-
- - Riddhi12349 -
- riddhi -
-
- - tanishqkolhatkar93 -
- Tanishq Kolhatkar -
-
- - PavanTeja2005 -
- PavanTeja2005 -
-
- - mehul-m-prajapati -
- Mehul Prajapati -
-
- - sarthaxtic -
- sarthaxtic -
-
- - jainaryan04 -
- Aryan Ramesh Jain -
-
- - shimmer12 -
- Srishti Soni -
-
- - Asmi1108 -
- Asmi -
-
- - khurshed07 -
- khurshed Ansari -
-
- - jvkousthub -
- Kousthub J V -
-
- - govindumeesala -
- Meesala Govindu -
-
- - sriraghavi22 -
- sriraghavi22 -
-
- - AKSHITHA-CHILUKA -
- ~Chiluka Akshitha -
-
- - LitZeus -
- Tejas Athalye -
-
- - Siddhart2004 -
- SIDDHARTH A -
-
- - anshika-1102 -
- anshika-1102 -
-
- - Hamza1821 -
- Hamza Mubin -
-
- - AADESHak007 -
- Aadesh_Kumar -
-
- - Saaarthak0102 -
- Sarthak -
-
- - akash70629 -
- Akash Das -
-
- - AdityaJani616 -
- Aditya Jani -
-
- - karthikyandrapu -
- Durga Karthik Yandrapu -
-
- - Bhumika-00 -
- Bhumika Sharma -
-
- - AswaniBolisetti -
- Aswani Bolisetti -
-
- - 4F24L -
- Md Afzal Mir -
-
- - Jivanjamadar -
- Jivan -
-
- - Lighting-pixel -
- Ayan -
-
- - Shantnu-singh -
- shantnu -
-
- - KunikaMakker -
- Kunika Makker -
-
- - samar12-rad -
- Samarth Vaidya -
-
- - c4dr-me -
- c4dr-me -
-
- - alo7lika -
- alolika bhowmik -
-
- - varshapandiann -
- Varsha Pandian -
-
- - ShudarsanRegmi -
- Shudarsan Regmi -
-
- - shashmitha46 -
- Shashmitha V -
-
- - Dishaaa-T -
- Disha T -
-
- - purnima2904 -
- Purnima Gupta -
-
- - shamvrueth -
- shamvrueth -
-
- - IRFANSARI -
- Irfan Ansari -
-
- - AnushkaChouhan25 -
- Anushka Chouhan -
-
- - 17arindam -
- Arindam -
-
- - karanmaheshwari16 -
- karanmaheshwari16 -
-
- - vishantrathi -
- Vishant Rathi -
-
- - tanushrigoel -
- tanushrigoel -
-
- - Bhum-ika -
- Bhumika Sharma -
-
- - Kunj05 -
- Kunj Chandak -
-
- - narendra-dhangar -
- Narendra Dhangar -
-
- - kaabilcoder -
- Saurabh Kumar Sahu -
-
- - souvikpramanikgit -
- Souvik Kumar Pramanik -
-
- - Soumya03007 -
- Soumyadeep Paul -
-
- - KGupta2601 -
- Kashika -
-
- - 770navyasharma -
- Navya Sharma -
-
- - smog-root -
- smog-root -
-
- - ADITHYA-NS -
- Adithya N S -
-
- - ananydev -
- Anany Dev -
-
- - Grandhi-Harshitha -
- Grandhi-Harshitha -
-
- - meghanakn473 -
- K N Meghana -
-
- - Richajaishwal0 -
- Richa jaishwal -
-
- - AmanPathan -
- Ronin -
-
- - SKG24 -
- Sanat Kumar Gupta -
-
- - Shreya7tripathy -
- Shreya Tripathy -
-
- - vedhcet-07 -
- Vishwas M D -
-
- - yogeswari05 -
- Chekka Yogeswari -
-
- - 1-SubhamSingh -
- Subham Singh -
-
- - Khushi-51 -
- Khushi -
-
- - shalini-bhandari -
- Shalini Bhandari -
-
- - Uvesh99 -
- Saiyad Uveshali -
-
- - Suvadip-sana -
- Suvadip Sana -
-
- - shivenyadavs -
- SHIVEN YADAV S -
-
- - Ruksina01 -
- Ruksina -
-
- - rishabhrawat05 -
- Rishabh -
-
- - rees8 -
- Rhea -
-
- - CygnusST3RN -
- Rahul -
-
- - PRASHANTSWAROOP001 -
- PRASHANT SWAROOP -
-
- - nishakp3005 -
- Nishita Panchal -
-
- - Nelcy17 -
- Nelcy17 -
-
- - Himanshi-m -
- Himanshi Maheshwari -
-
- - jashwanthbavandlapalli -
- Jashwanth Bavandlapalli -
-
- - madhavi-peddireddy -
- PEDDIREDDY MADHAVI -
-
- - rajatsinghal02 -
- Rajat singhal -
-
- - RchtDshr -
- Rachita Dashore -
-
- - coder-writes -
- Rishi Verma -
-
- - SrijaVuppala295 -
- SrijaVuppala295 -
-
- - aditya07389 -
- aditya -
-
- - amiya-cyber -
- Amiya Singh -
-
- - ishita-1305 -
- Ishita Srivastava -
-
- - Mohith1490 -
- Mohith Singh -
-
- - siri-chandana-macha -
- siri-chandana-macha -
-
- - soham0028 -
- Soham Thorve -
-
- - Anandha-Vihari -
- Anandha-Vihari -
-
- - Lokesh11868 -
- Lokesh11868 -
-
- - Saurabhchaudhary9799 -
- Saurbh Kumar -
-
- - Aasthaa10 -
- Aastha kumari -
-
- - Aditijainnn -
- Aditi -
-
- - Akki-58 -
- AJ -
-
- - AnanteshG -
- Anantesh G -
-
- - Ananya-vastare -
- Ananya Ravikiran Vastare -
-
- - ChetanSingh14 -
- Chetan SIngh -
-
- - RahulScripted -
- Rahul Goswami -
-
- - meghanakn22 -
- meghanakn22 -
-
- - kartik1112 -
- Kartik Buttan -
-
- - Kratik1093 -
- Kratik Mandloi -
-
- - Mahi3454 -
- Mahi3454 -
-
- - Mansi-Tanwar -
- Mansi-Tanwar -
-
- - NishantRana07 -
- Nishant Rana -
-
- - Raj100 -
- Raj Rawariya -
-
- - OmmDevgoswami -
- Omm Devgoswami -
-
- - Rahul7raj -
- Rahul7raj -
-
- - RanaJay3101 -
- Rana Jay -
-
- - RohanSai22 -
- RohanSai22 -
-
- - sejals23 -
- Sejal -
-
- - shivhere007 -
- Shivam Prasad Singh -
-
- - Tusharb331 -
- Tushar Bansal -
-
- - Bhabuk10 -
- Bhabuk Thapa -
-
- - aasritha-24 -
- aasritha-24 -
-
- - adwityac -
- Adwitya Chakraborty -
-
- - pa1narendra -
- PAVAN NARENDRA PEELA -
-
- - sujal-GITHUB -
- Sujal Kumar -
-
- - oebelus -
- Oebelus -
-
- - shubhagarwal1 -
- Shubh Agarwal -
-
- - Lokesh-Bijarniya -
- Lokesh_Bijarniya_ -
-
- - LNischala -
- LNischala -
-
- - krishpathak -
- Krish Pathak -
-
- - jayanththalla -
- Thalla Jayanth -
-
- - ImgBotApp -
- Imgbot -
-
- - IRFANSARI2 -
- IRFANSARI2 -
-
- - iking07 -
- Harsh -
-
- - arzoosingh147 -
- Arzoo Singh -
-
- - ArchanRD -
- Archan Dhrangadharia -
-
- - Amankr200 -
- Amankr200 -
-
- - -
- -## Stargazers - -[![Stargazers repo roster for @ajay-dhangar/algo](https://reporoster.com/stars/dark/ajay-dhangar/algo)](https://github.com/ajay-dhangar/algo/stargazers) - -## Forkers - -[![Forkers repo roster for @ajay-dhangar/algo](https://reporoster.com/forks/dark/ajay-dhangar/algo)](https://github.com/ajay-dhangar/algo/network/members) - -## Resources for Guidance -Here are some resources that may be helpful as you contribute to Algo: -- [Docusaurus Documentation](https://docusaurus.io/docs/docs-introduction) -- [React.js Documentation](https://legacy.reactjs.org/docs/getting-started.html) -- [Markdown Guide](https://www.markdownguide.org/) -- [MDX Documentation](https://mdxjs.com/docs/) -- [Mermaid Documentation](https://mermaid.js.org/) - - diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 034e84803..000000000 --- a/SECURITY.md +++ /dev/null @@ -1,21 +0,0 @@ -# Security Policy - -## Supported Versions - -Use this section to tell people about which versions of your project are -currently being supported with security updates. - -| Version | Supported | -| ------- | ------------------ | -| 5.1.x | :white_check_mark: | -| 5.0.x | :x: | -| 4.0.x | :white_check_mark: | -| < 4.0 | :x: | - -## Reporting a Vulnerability - -Use this section to tell people how to report a vulnerability. - -Tell them where to go, how often they can expect to get an update on a -reported vulnerability, what to expect if the vulnerability is accepted or -declined, etc. diff --git a/admin/scripts/formatLighthouseReport.js b/admin/scripts/formatLighthouseReport.js deleted file mode 100644 index 6bfa5e8d0..000000000 --- a/admin/scripts/formatLighthouseReport.js +++ /dev/null @@ -1,88 +0,0 @@ -// @ts-check - -/** - * @typedef {Record<'performance' | 'accessibility' | 'best-practices' | 'seo', -* number>} LighthouseSummary -*/ - -/** @type {Record} */ -const summaryKeys = { - performance: "Performance", - accessibility: "Accessibility", - "best-practices": "Best Practices", - seo: "SEO", -}; - -/** @param {number} rawScore */ -const scoreEntry = (rawScore) => { - const score = Math.round(rawScore * 100); - const scoreIcon = score >= 90 ? "🟢" : score >= 50 ? "🟡" : "🔴"; - return `${scoreIcon} ${score}`; -}; - -/** -* @param {string} url -* @returns {module:url.URL} -*/ -function createURL(url) { - try { - return new URL(url); - } catch (e) { - throw new Error(`Can't create URL for string=${url}`, { cause: e }); - } -} - -/** -* @param {Object} param0 -* @param {string} param0.url -* @param {LighthouseSummary} param0.summary -* @param {string} param0.reportUrl -*/ -const createMarkdownTableRow = ({ url, summary, reportUrl }) => - [ - `| [${createURL(url).pathname}](${url})`, - .../** @type {(keyof LighthouseSummary)[]} */ ( - Object.keys(summaryKeys) - ).map((k) => scoreEntry(summary[k])), - `[📄](${reportUrl}) |`, - ].join(" | "); - -const createMarkdownTableHeader = () => [ - ["| URL 🌐", ...Object.values(summaryKeys), "📊 |"].join(" | "), - ["|---", ...Array(Object.keys(summaryKeys).length).fill("---"), "---|"].join( - "|", - ), -]; - -/** -* @param {Object} param0 -* @param {Record} param0.links -* @param {{url: string, summary: LighthouseSummary}[]} param0.results -*/ -const createLighthouseReport = ({ results, links }) => { - const tableHeader = createMarkdownTableHeader(); - const tableBody = results.map((result) => { - const testUrl = /** @type {string} */ ( - Object.keys(links).find((key) => key === result.url) - ); - const reportPublicUrl = /** @type {string} */ (links[testUrl]); - - return createMarkdownTableRow({ - url: testUrl, - summary: result.summary, - reportUrl: reportPublicUrl, - }); - }); - const comment = [ - "### ⚡️ Lighthouse Report for the Deploy Preview of this PR 🚀", - "", - "🔗 Site: [Algo](https://github.com/ajay-dhangar/algo) | [Live Site](https://ajay-dhangar.github.io/algo/)", - "", - ...tableHeader, - ...tableBody, - "", - ]; - return comment.join("\n"); -}; - -export default createLighthouseReport; \ No newline at end of file diff --git a/admin/scripts/package.json b/admin/scripts/package.json deleted file mode 100644 index a1f1970a2..000000000 --- a/admin/scripts/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "algo-scripts", - "description": "These are the scripts used in various places of CodeHarborHub to automate tasks.", - "private": true, - "license": "MIT", - "type": "module", - "version": "1.0.0", - "main": "formatLighthouseReport.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "ajay-dhangar" - } \ No newline at end of file diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index e00595dae..000000000 --- a/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: [require.resolve('@docusaurus/core/lib/babel/preset')], -}; diff --git a/blog/20-most-important-coding-pattern.md b/blog/20-most-important-coding-pattern.md deleted file mode 100644 index ccd9f189e..000000000 --- a/blog/20-most-important-coding-pattern.md +++ /dev/null @@ -1,423 +0,0 @@ ---- -slug: 20-most-important-coding-pattern -title: '20 Most Essential Coding Patterns' -authors: [Rishi-Verma] -tags: [coding, interview, dsa, C++,Rishi-Verma, java, python, programming,sliding window, two pointers, fast and slow pointers, merge intervals, cyclic sort] ---- - - -Navigating through coding interviews requires more than just a good grasp of algorithms and data structures; it demands a strategic approach and a keen eye for patterns. In today's competitive world of tech job interviews, understanding and mastering coding patterns can significantly enhance your problem-solving skills and boost your performance. - - -Coding patterns, or as we like to call them, are recurring techniques that provide a structured approach to solving complex problems. Think of them as the building blocks of algorithms, helping you to break down problems into more manageable parts. - -In this blog, we will explore 20 essential coding patterns that are pivotal for acing coding interviews. We will delve into the pros and cons of each pattern, providing you with a balanced view to help you make informed decisions during your interviews. And to top it off, we will equip you with real problem examples from the Grokking the Coding Interview course. I'm the author of this course, feel free to reach out to me if you have questions. - -Let's go through each pattern one by one. - -## 1. Two Pointers - -**Description**: The Two Pointers technique is a clever strategy used in algorithm design, particularly when dealing with arrays or linked lists. Imagine you have two fingers, and you place each at different ends or positions of an array. These ‘fingers’ or pointers then traverse through the array, helping you to compare, search, or even manipulate the data efficiently. - -**Usage**: -- Ordered Data Structures: This pattern shines when applied to ordered arrays or lists, allowing for intelligent, position-based decisions that can significantly optimize the algorithm. -- Efficiency: By reducing the need for nested loops, the Two Pointers technique helps in achieving linear time complexity, making your algorithm faster and more efficient. - -**Pros and Cons**: -- **Pros**: - - Efficiency: Achieves O(n) time complexity for problems that might otherwise require O(n^2). - - Simplicity: Once mastered, it provides a straightforward and elegant solution. -- **Cons**: - - Applicability: Mainly beneficial for problems involving sequences or intervals. - - Initial Complexity: It might take some time to get the hang of this pattern and understand where and how to move the pointers. - -**Example Problems from Grokking the Coding Interview**: -- Pair with Target Sum: Find a pair in an array that adds up to a specific target sum. -- Squaring a Sorted Array: Given a sorted array, create a new array containing squares of all the numbers of the input array in the sorted order. -- Triplet Sum to Zero: Given an array of unsorted numbers, find all unique triplets in it that add up to zero. - -## 2. Island (Matrix Traversal) Pattern - -**Description**: The Island pattern, also known as Matrix Traversal, is a technique used to navigate through a 2D array or matrix. The primary goal is to identify and process contiguous groups of elements, often referred to as ‘islands’. This pattern is particularly useful when you need to explore and manipulate grid-based data. - -**Usage**: -- Grid-Based Problems: Excelling in problems where you need to traverse a grid to find connected components or regions. -- Contiguous Elements: Ideal for situations where you need to group together adjacent elements that share a common property. - -**Pros and Cons**: -- **Pros**: - - Comprehensive: Provides a thorough way to explore all the elements in a grid. - - Versatile: Can be used to solve a variety of problems related to 2D arrays. -- **Cons**: - - Complexity: Can be more complex to implement compared to linear data structure traversal. - - Space Overhead: May require additional space for recursion or queue/stack for breadth-first/depth-first traversal. - -**Example Problems from Grokking the Coding Interview**: -- Number of Islands: Count the number of islands in a given 2D matrix. -- Biggest Island: Find the largest island in terms of area or number of cells. -- Flood Fill: Change the color of an image represented by a 2D array. - -## 3. Fast & Slow Pointers - -**Description**: The Fast & Slow Pointers technique involves two pointers traversing through a data structure at different speeds. This ingenious approach is particularly useful in identifying cycles, finding middle elements, and solving various other problems related to linked lists and arrays. - -**Usage**: -- Cycle Detection: Perfect for identifying cycles in a linked list or array, which is a common interview question. -- Finding Middle Elements: Efficiently find the middle element of a linked list without knowing the length beforehand. -- Problem-Specific Solutions: Solve specific problems like finding the start of a cycle in a linked list. - -**Pros and Cons**: -- **Pros**: - - Space Efficiency: Achieves solutions without the need for extra space, adhering to O(1) space complexity. - - Versatility: Applicable to a variety of problems, making it a versatile pattern to know. -- **Cons**: - - Initial Complexity: Understanding how to move the pointers and at what speed can be tricky at first. - - Specificity: While versatile, it is mostly beneficial for problems related to linked lists and certain array problems. - -**Example Problems from Grokking the Coding Interview**: -- LinkedList Cycle: Determine if a linked list has a cycle. -- Middle of the LinkedList: Find the middle node of a linked list. -- Palindrome LinkedList: Check if a linked list is a palindrome. - -## 4. Sliding Window - -**Description**: The Sliding Window pattern involves creating a ‘window’ over a portion of data and sliding it across to solve problems efficiently. This technique is particularly useful for array or list-based problems where you need to find or calculate something among all the contiguous subarrays or sublists of a given size. - -**Usage**: -- Contiguous Subarrays: Ideal for problems that require you to deal with contiguous subarrays or sublists. -- Variable Sized Window: Can be adapted for problems where the window size is not fixed and needs to be adjusted based on certain conditions. - -**Pros and Cons**: -- **Pros**: - - Efficiency: Provides a way to reduce time complexity from O(n^2) to O(n) for specific problems. - - Versatility: Can be used for a variety of problems, including maximum sum subarray, smallest subarray with a given sum, and longest substring with K distinct characters. -- **Cons**: - - Initial Complexity: Understanding how to adjust the window size and when to slide the window can be challenging initially. - - Specificity: Mainly beneficial for problems involving contiguous subarrays or sublists. - -**Example Problems from Grokking the Coding Interview**: -- Maximum Sum Subarray of Size K: Given an array of positive numbers and a positive number ‘k’, find the maximum sum of any contiguous subarray of size ‘k’. -- Fruits Into Baskets: Given an array of characters where each character represents a fruit tree, you are given two baskets, and your goal is to put maximum number of fruits in each basket. -- Longest Substring with K Distinct Characters: Given a string, find the length of the longest substring in it with no more than K distinct characters. - -## 5. Merge Intervals - -**Description**: The Merge Intervals pattern is a powerful technique used to deal with overlapping intervals or ranges. It involves sorting and then merging intervals based on specific conditions. This pattern is incredibly useful for time-based problems, scheduling, and range manipulation. - -**Usage**: -- Overlapping Intervals: Perfect for problems where you need to merge overlapping intervals or find if an interval overlaps with any other. -- Interval Scheduling: Useful for problems that involve scheduling based on time intervals. - -**Pros and Cons**: -- **Pros**: - - Clarity: Provides a clear and systematic way to deal with overlapping intervals. - - Efficiency: Helps in reducing the problem complexity and achieving optimal solutions. -- **Cons**: - - Sorting Overhead: Requires the intervals to be sorted beforehand, which could add to the time complexity. - - Specificity: Mainly beneficial for problems involving intervals and ranges. - -**Example Problems from Grokking the Coding Interview**: -- Merge Intervals: Given a list of intervals, merge all the overlapping intervals to produce a list that has only mutually exclusive intervals. -- Insert Interval: Given a list of non-overlapping intervals sorted by their start time, insert a given interval at the correct position and merge all necessary intervals to produce a list that has only mutually exclusive intervals. -- Intervals Intersection: Given two lists of intervals, find the intersection of these two lists. Each list consists of disjoint intervals sorted on their start time. - -## 6. Cyclic Sort - -**Description**: Cyclic Sort is a unique and intuitive sorting algorithm, particularly well-suited for problems where you are given a range of numbers and asked to sort them. The beauty of this pattern lies in its ability to sort the numbers in-place, utilizing the fact that the numbers are consecutive or have a specific range. - -**Usage**: -- Consecutive Numbers: Ideal for scenarios where you have an array of numbers in a specific range, and you need to sort them or find missing/duplicate numbers. -- In-Place Sorting: Provides a way to sort the numbers without using any extra space. - -**Pros and Cons**: -- **Pros**: - - Space Efficiency: Achieves sorting without the need for additional space, adhering to O(1) space complexity. - - Time Efficiency: Offers a linear time complexity solution for specific range-based sorting problems. -- **Cons**: - - Limited Applicability: Best suited for problems involving numbers in a specific range and may not be applicable for other types of sorting problems. - - Initial Learning Curve: Understanding the cyclic sort pattern and knowing when to apply it can take some time. - -**Example Problems from Grokking the Coding Interview**: -- Find the Missing Number: Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. -- Find all Duplicates: Find all the duplicate numbers (without using extra space and in O(n) runtime). -- Duplicates In Array: Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. - -## 7. In-place Reversal of a Linked List - -**Description**: The In-place Reversal of a Linked List pattern is a technique used to reverse the elements of a linked list without using additional memory. This is achieved by manipulating the pointers of the nodes in the linked list to reverse their direction. - -**Usage**: -- Memory Efficiency: Since no additional data structures are used, this pattern is memory efficient. -- Reversing Sub-lists: Can be extended to reverse sub-lists within a linked list, providing versatility in solving more complex problems. - -**Pros and Cons**: -- **Pros**: - - Space Efficiency: Achieves in-place reversal, ensuring O(1) space complexity. - - Versatility: Can be used to solve various problems related to linked lists, including reversing sub-lists and finding palindromes. -- **Cons**: - - Pointer Manipulation: Requires careful manipulation of pointers, which can be error-prone. - - Initial Learning Curve: Understanding how to reverse the pointers without losing the rest of the linked list can be challenging initially. - -**Example Problems from Grokking the Coding Interview**: -- Reverse a LinkedList: Given the head of a Singly LinkedList, reverse the LinkedList. -- Reverse a Sub-list: Given the head of a LinkedList and two positions ‘p’ and ‘q’, reverse the LinkedList from position ‘p’ to ‘q’. -- Reverse Every K-element Sub-list: Given the head of a LinkedList and a number ‘k’, reverse every ‘k’ sized sub-list starting from the head. - -## 8. Tree Breadth First Search - -**Description**: The Tree Breadth First Search (BFS) pattern involves traversing a tree level by level, ensuring that you visit all the nodes at the current depth before moving on to the nodes at the next depth level. This is usually implemented using a queue. - -**Usage**: -- Level Order Traversal: Ideal for problems that require you to traverse a tree in level order or when you need to perform operations on nodes at the same depth. -- Minimum Depth: Useful for finding the minimum depth of a tree, as you can stop the traversal once you find the first leaf node. - -**Pros and Cons**: -- **Pros**: - - Complete Traversal: Ensures that every node in the tree is visited. - - Level Order Information: Provides information about the depth or level of each node. -- **Cons**: - - Space Overhead: Requires additional space for the queue, which can be as large as the number of nodes at the largest level. - - Not as Efficient for Depth-Related Queries: For problems that depend on depth information, a depth-first search might be more efficient. - -**Example Problems from Grokking the Coding Interview**: -- Binary Tree Level Order Traversal: Traverse a tree in level order and return the values of the nodes at each level. -- Reverse Level Order Traversal: Traverse a tree in reverse level order. -- Zigzag Traversal: Traverse a tree in a zigzag order. - -## 9. Tree Depth First Search - -**Description**: The Tree Depth First Search (DFS) pattern involves traversing a tree in a depth-first manner, meaning you go as deep as possible down one branch before backing up and exploring other branches. This is typically implemented using recursion or a stack. - -**Usage**: -- Path Finding: Ideal for problems where you need to find a path or check the existence of a path with certain properties. -- Complex Tree Traversals: Useful for more complex tree traversal problems where you need to maintain state or perform operations as you traverse. - -**Pros and Cons**: -- **Pros**: - - Space Efficiency: For a balanced tree, DFS uses less space than BFS. - - Simplicity: Recursive implementations can be more straightforward and concise. -- **Cons**: - - Can Be Less Efficient for Wide Trees: For very wide trees, DFS can use more space than BFS. - - May Not Find the Shortest Path: If you're looking for the shortest path in an unweighted tree, BFS is generally a better choice. - -**Example Problems from Grokking the Coding Interview**: -- Binary Tree Path Sum: Given a binary tree and a number ‘S’, find if the tree has a path from root-to-leaf such that the sum of all the node values of that path equals ‘S’. -- All Paths for a Sum: Find all root-to-leaf paths in a binary tree that have a sum equal to a given number. -- Count Paths for a Sum: Find the number of paths in a tree that sum up to a given value. - -## 10. Two Heaps - -**Description**: The Two Heaps pattern involves using two priority queues (heaps) to maintain a running balance or median of a set of numbers. One heap keeps track of the smaller half of the numbers, and the other keeps track of the larger half. - -**Usage**: -- Running Median: Perfect for problems where you need to find the median of a set of numbers as new numbers are added. -- Balanced Partition: Useful for problems where you need to maintain a balanced partition of numbers. - -**Pros and Cons**: -- **Pros**: - - Efficiency: Provides a way to efficiently find the median or maintain balance in O(log N) time. - - Dynamic: Can handle dynamic datasets where numbers are added over time. -- **Cons**: - - Complexity: Implementation can be more complex due to the need to balance the two heaps. - - Space Overhead: Requires additional space to store the numbers in the heaps. - -**Example Problems from Grokking the Coding Interview**: -- Find the Median of a Number Stream: Design a class to calculate the median of a number stream. -- Sliding Window Median: Find the median of all subarrays of size ‘K’ in the array. -- Maximize Capital: Given a set of investment projects with their respective profits, we need to find the most profitable projects. We are given an initial capital and are allowed to invest only in a fixed number of projects. Our goal is to choose projects that give us the maximum profit. - -## 11. Subsets - -**Description**: The Subsets pattern involves dealing with problems that require generating all possible combinations or subsets of a set. This pattern is particularly useful when you need to explore all the different ways to combine elements, which is a common scenario in many coding problems. - -**Usage**: -- Combinatorial Problems: Ideal for problems where you need to generate all possible combinations of elements. -- Exhaustive Search: Useful when you need to perform an exhaustive search over all possible subsets of a set. - -**Pros and Cons**: -- **Pros**: - - Comprehensive: Ensures that you consider all possible combinations of elements. - - Versatile: Can be used to solve a variety of problems, including generating power sets, combinations, and permutations. -- **Cons**: - - Time Complexity: Can lead to exponential time complexity, as the number of subsets of a set is 2^N. - - Space Complexity: Requires additional space to store all the subsets. - -**Example Problems from Grokking the Coding Interview**: -- Subsets: Given a set with distinct elements, find all of its distinct subsets. -- Subsets With Duplicates: Given a set of numbers that might contain duplicates, find all of its distinct subsets. -- Permutations: Given a set of distinct numbers, find all of its permutations. - -## 12. Modified Binary Search - -**Description**: The Modified Binary Search pattern involves adapting the classic binary search algorithm to solve various problems, often related to searching in a sorted array or finding the boundary of a condition. - -**Usage**: -- Sorted Arrays: Perfect for problems involving searching or making decisions based on sorted arrays. -- Finding Boundaries: Useful for finding the start or end of a condition in a sorted array. - -**Pros and Cons**: -- **Pros**: - - Efficiency: Provides a logarithmic time complexity solution for searching problems, making it highly efficient. - - Versatility: Can be adapted to solve a wide range of problems beyond simple searching. -- **Cons**: - - Applicability: Mainly beneficial for problems involving sorted arrays or conditions with clear boundaries. - - Implementation Nuances: Requires careful implementation to handle edge cases and avoid infinite loops. - -**Example Problems from Grokking the Coding Interview**: -- Order-agnostic Binary Search: Given a sorted array of numbers, find the index of a given number. The array could be sorted in ascending or descending order. -- Ceiling of a Number: Given an array of numbers sorted in ascending order, find the ceiling of a given number. The ceiling of a number is the smallest number in the given array greater than or equal to the given number. -- Next Letter: Given an array of lowercase letters sorted in ascending order, find the smallest letter in the given array greater than a given ‘key’. - -## 13. Bitwise XOR - -**Description**: The Bitwise XOR pattern involves using the XOR bitwise operator to solve problems, often related to finding missing numbers or duplicate numbers in an array. XOR is a binary operator that returns 1 when the two bits are different and 0 when they are the same. - -**Usage**: -- Finding Missing or Duplicate Numbers: Ideal for problems where you need to find a missing number or duplicate numbers - -## 14. Top 'K' Elements - -**Description**: The Top 'K' Elements pattern involves finding the 'K' largest or smallest elements in an array or stream of data. This pattern is particularly useful when dealing with large datasets and you need to maintain a subset of the data based on certain criteria. - -**Usage**: -- **Priority Queue**: Utilizes a min-heap or max-heap to efficiently keep track of the 'K' largest or smallest elements. -- **Streaming Data**: Ideal for scenarios where the data is streaming in, and you need to maintain the 'K' largest or smallest elements at any given time. - -**Pros and Cons**: -- **Pros**: - - **Efficiency**: Provides a way to find the 'K' largest or smallest elements in O(N log K) time. - - **Space Efficiency**: Only requires O(K) space, regardless of the size of the dataset. -- **Cons**: - - **Limited to 'K' Elements**: Only maintains information about the top 'K' elements, not the entire dataset. - - **Heap Maintenance**: Requires careful maintenance of the heap to ensure efficiency. - -**Example Problems from Grokking the Coding Interview**: -- **Top 'K' Numbers**: Given an unsorted array of numbers, find the ‘K’ largest numbers in it. -- **Kth Smallest Number**: Given an unsorted array of numbers, find the Kth smallest number in it. -- **‘K’ Closest Points to the Origin**: Given an array of points in the a 2D plane, find ‘K’ closest points to the origin. - -## 15. K-way Merge - -**Description**: The K-way Merge pattern involves merging multiple sorted arrays or lists into a single sorted list. This pattern is highly useful in scenarios where you have multiple sorted datasets that you need to combine and maintain the sorted order. - -**Usage**: -- **Multiple Sorted Arrays**: Ideal for merging multiple sorted arrays or lists. -- **External Sorting**: Useful in external sorting, where the data to be sorted does not fit into memory and is stored in sorted chunks. - -**Pros and Cons**: -- **Pros**: - - **Efficiency**: Provides a way to merge multiple sorted arrays in O(N log K) time, where ‘N’ is the total number of elements across all arrays, and ‘K’ is the number of arrays. - - **Space Efficiency**: Only requires O(K) space for the priority queue. -- **Cons**: - - **Dependent on Sorting**: The efficiency of this pattern depends on the arrays being sorted. - - **Priority Queue Overhead**: Requires maintenance of a priority queue, which adds to the complexity. - -**Example Problems from Grokking the Coding Interview**: -- **Merge K Sorted Lists**: Given an array of ‘K’ sorted LinkedLists, merge them into one sorted list. -- **Kth Smallest Number in M Sorted Lists**: Given ‘M’ sorted arrays, find the K’th smallest number among all the arrays. -- **Find the Smallest Range Covering Elements from K Lists**: Given ‘M’ sorted arrays, find the smallest range that includes at least one number from each of the ‘M’ lists. - -## 16. Topological Sort - -**Description**: Topological Sort is a pattern used for linearly ordering the vertices of a directed graph in such a way that for every directed edge (U, V), vertex U comes before V. This pattern is particularly useful in scenarios where you have a set of tasks and some tasks depend on others. - -**Usage**: -- **Task Scheduling**: Ideal for problems where tasks need to be scheduled in a specific order, respecting their dependencies. -- **Course Scheduling**: Useful in scenarios like course scheduling where some courses have prerequisites. - -**Pros and Cons**: -- **Pros**: - - **Clarity**: Provides a clear and systematic way to order tasks or vertices. - - **Detecting Cycles**: Helps in detecting cycles in a directed graph, which is important for understanding if a valid ordering is possible. -- **Cons**: - - **Applicability**: Mainly beneficial for problems involving directed graphs and ordering of vertices. - - **Complexity**: Implementation can be complex, especially for beginners. - -**Example Problems from Grokking the Coding Interview**: -- **Topological Sort**: Given a directed graph, find the topological ordering of its vertices. -- **Tasks Scheduling**: Find if it is possible to schedule all the tasks. -- **Tasks Scheduling Order**: Find the order of tasks we should pick to finish all tasks. - -## 17. Trie - -**Description**: A Trie, also known as a prefix tree, is a tree-like data structure used to store a dynamic set of strings, where the keys are usually strings. It is particularly useful for retrieval of a key in a dataset of strings, which makes it highly efficient for solving word-based problems. - -**Usage**: -- **Autocomplete**: Ideal for implementing autocomplete functionality in search engines or text editors. -- **Spell Checker**: Useful for building spell checkers in word processors. -- **IP Routing**: Used in IP routing to store and search routes. - -**Pros and Cons**: -- **Pros**: - - **Efficiency**: Provides fast retrieval of strings and is more efficient than hash tables or sets when it comes to string keys. - - **Prefix Searching**: Excellent for problems that require prefix searching or matching. -- **Cons**: - - **Space Overhead**: Can use more space compared to other data structures when the dataset is sparse. - - **Complexity**: Implementation can be complex, especially when handling deletion of words from the Trie. - -**Example Problems from Grokking the Coding Interview**: -- **Insert into and Search in a Trie**: Implement insertion and search in a Trie. -- **Longest Common Prefix**: Find the longest common prefix of a set of strings. -- **Word Search**: Given a 2D board and a word, find if the word exists in the grid. - -## 18. Backtracking -**Description** : Backtracking is a general algorithmic technique that considers searching through all the possible configurations of a search space in order to solve computational problems. It is particularly useful for optimization problems and when a complete search of the solution space is required. The main idea is to explore each possibility until the solution is found or all possibilities have been exhausted. - -**Usage** -- **Combinatorial Problems**: Ideal for solving problems that require generating all possible configurations like permutations, combinations, and subsets. -- **Puzzle Solving**: Useful for solving puzzles such as Sudoku, crossword puzzles, and the N-Queens problem. - -**Pros and Cons** -- **Pros** - - **Completeness** Ensures that the entire solution space is explored, guaranteeing that the optimal solution will be found if it exists. - - **Space Efficiency** Uses less memory as it only needs to store the current state and the decision stack. -- **Cons** - - **Time Complexity** Can lead to exponential time complexity, as it explores all possible configurations. - - **Space Efficiency** May require additional optimizations like pruning to be practical for larger instances. -**Example Problems from Grokking the Coding Interview**: - - **Subsets** Given a set of numbers, find all of its subsets. - - **Permutations** Given a set of distinct numbers, find all of its permutations. - - **N-Queens** Place N queens on an N×N chessboard so that no two queens threaten each other. - - -## 19. Monotonic Stack - -**Description**: A Monotonic Stack is a specialized data structure that maintains elements in a sorted order while supporting stack operations. It is particularly useful for problems where you need to find the next greater or smaller element in an array or when you need to maintain a running maximum or minimum value efficiently. - -**Usage**: -- **Next Greater Element**: Ideal for finding the next greater element for each element in an array. -- **Maximum Area Histogram**: Useful for problems like finding the largest rectangular area under a histogram. - -**Pros and Cons**: -- **Pros**: - - **Efficiency**: Provides a way to solve certain problems in linear time, making it highly efficient. - - **Simplicity**: Once understood, the monotonic stack can lead to concise and elegant solutions. -- **Cons**: - - **Specificity**: Mainly beneficial for problems involving finding the next greater or smaller element and related problems. - - **Learning Curve**: Understanding how and when to use a monotonic stack can take some time. - -**Example Problems**: -- **Next Greater Element**: Given an array, find the next greater element for each element in the array. -- **Maximum Area Histogram**: Given a histogram, find the largest rectangular area under the histogram. -- **Largest Rectangle in Histogram**: Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. - -## 20. 0/1 Knapsack (Dynamic Programming) - -**Description**: The 0/1 Knapsack problem is a classic optimization problem that falls under the category of Dynamic Programming. In this problem, you are given a set of items, each with a weight and a value, and a knapsack with a maximum capacity. The goal is to determine the maximum value that can be accommodated in the knapsack without exceeding its capacity. The "0/1" part of the name reflects the fact that you can't break an item, you either take it or leave it. - -**Usage**: -- **Resource Allocation**: Ideal for problems where you need to optimally allocate limited resources to maximize profit or minimize cost. -- **Budgeting**: Useful for budgeting scenarios where you need to choose a subset of projects or investments to maximize return. - -**Pros and Cons**: -- **Pros**: - - **Optimality**: Ensures that the optimal solution is found, provided that the problem satisfies the principle of optimality. - - **Generality**: Can be adapted to solve a wide variety of optimization problems. -- **Cons**: - - **Time and Space Complexity**: The naive implementation has a time and space complexity of O(nW), where n is the number of items and W is the capacity of the knapsack. This can be prohibitive for large inputs. - - **Requires Integer Weights and Values**: The classic 0/1 Knapsack problem requires weights and values to be integers. - -**Example Problems from Grokking the Coding Interview**: -- **0/1 Knapsack**: Given the weights and profits of ‘N’ items, put these items in a knapsack which has a capacity ‘C’. The goal is to get the maximum profit out of the items in the knapsack. -- **Equal Subset Sum Partition**: Given a set of positive numbers, find if we can partition it into two subsets such that the sum of elements in both subsets is equal. -- **Subset Sum**: Given a set of positive numbers, determine if there exists a subset in the set whose sum is equal to a given number ‘S’. \ No newline at end of file diff --git a/blog/Common-Recursion-Patterns.md b/blog/Common-Recursion-Patterns.md deleted file mode 100644 index 1da58a6c7..000000000 --- a/blog/Common-Recursion-Patterns.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -slug: common-recursion-patterns -title: Common Recursion Patterns in Algorithms -authors: [AKSHITHA-CHILUKA] -tags: [akshitha-chiluka, algo, dsa, algorithms, recursion] ---- - -Recursion is a powerful technique in programming that allows functions to call themselves. It is widely used in various algorithms, especially when dealing with problems that can be broken down into smaller subproblems. - - - -In this blog, we'll explore: - -- **Tree Traversal**: How to traverse tree structures using recursion. -- **Backtracking**: An approach to solve problems by trying multiple possibilities. - ---- - -## What are Recursion Patterns? - -Recursion patterns are common techniques employed in recursive algorithms that can help solve various computational problems. - -### 1. Tree Traversal - -Tree traversal is a common use case for recursion, where we visit each node in a tree data structure. There are several methods of tree traversal: - -- **Pre-order Traversal**: Visit the root, then recursively visit the left subtree and the right subtree. -- **In-order Traversal**: Recursively visit the left subtree, the root, and then the right subtree. -- **Post-order Traversal**: Recursively visit the left subtree, the right subtree, and then the root. - -#### Example: Pre-order Traversal - -```javascript -function preOrder(node) { - if (node) { - console.log(node.value); - preOrder(node.left); - preOrder(node.right); - } -} -``` -### 2. Backtracking -Backtracking is a method for solving problems incrementally by trying partial solutions and then abandoning them if they do not lead to a valid solution. - -#### Example: N-Queens Problem -```javascript -function solveNQueens(n) { - const board = Array(n).fill().map(() => Array(n).fill('.')); - const results = []; - - function backtrack(row) { - if (row === n) { - results.push(board.map(r => r.join('')).join('\n')); - return; - } - for (let col = 0; col < n; col++) { - if (isValid(row, col)) { - board[row][col] = 'Q'; - backtrack(row + 1); - board[row][col] = '.'; // backtrack - } - } - } - - backtrack(0); - return results; -} -``` -### Why are Recursion Patterns Important? -Understanding common recursion patterns can significantly enhance your problem-solving skills, allowing you to tackle complex problems more efficiently. - diff --git a/blog/Exploring-Graph-Algorithms.md b/blog/Exploring-Graph-Algorithms.md deleted file mode 100644 index 3706dccc5..000000000 --- a/blog/Exploring-Graph-Algorithms.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -slug: exploring-graph-algorithms-bfs-vs-dfs -title: "Exploring Graph Algorithms: BFS vs DFS" -authors: [Harshitha-Grandhi] -tags: [Harshitha-Grandhi, algo, dsa, algorithms, graph-theory] ---- - -Graph algorithms are fundamental in computer science, enabling us to navigate and analyze networks effectively. Two of the most prominent graph traversal algorithms are Breadth-First Search (BFS) and Depth-First Search (DFS). This blog post will delve into the key differences between these algorithms, their implementations, and their applications in real-world scenarios. - - - -In this blog, we'll explore: - -- **Understanding Graphs**: What are graphs and their components? -- **Breadth-First Search (BFS)**: How does it work? -- **Depth-First Search (DFS)**: A step-by-step explanation. -- **Comparison of BFS and DFS**: When to use which algorithm. -- **Implementation**: Code examples in Python and Java. -- **Real-World Applications**: How these algorithms are applied in practice. - ---- - -## Understanding Graphs - -Graphs consist of vertices (nodes) connected by edges (links). They can be directed or undirected, weighted or unweighted, and are used to model relationships and structures in various fields, from social networks to transportation systems. - -### Graph Representation Example: - -Consider the following undirected graph: - -This graph can be represented using an adjacency list or matrix. - -## Breadth-First Search (BFS) - -BFS explores the graph level by level, starting from a source node and visiting all its neighbors before moving on to the next level of nodes. - -### The Algorithm - -1. **Initialization**: Use a queue to keep track of nodes to visit. -2. **Visit Nodes**: Dequeue a node, mark it as visited, and enqueue its unvisited neighbors. -3. **Repeat**: Continue until there are no more nodes to visit. - -### Time Complexity - -BFS runs in O(V + E) time, where `V` is the number of vertices and `E` is the number of edges. - -## Depth-First Search (DFS) - -DFS explores as far as possible along each branch before backtracking. It can be implemented using recursion or an explicit stack. - -### The Algorithm - -1. **Initialization**: Use a stack to keep track of nodes. -2. **Visit Nodes**: Pop a node, mark it as visited, and push its unvisited neighbors onto the stack. -3. **Repeat**: Continue until the stack is empty. - -### Time Complexity - -DFS also runs in O(V + E) time. - -## Comparison of BFS and DFS - -| Feature | BFS | DFS | -|-------------------------|-----------------------------|-----------------------------| -| Strategy | Level by level | Deep into the graph | -| Data Structure | Queue | Stack (or recursion) | -| Memory Usage | Higher (for wide graphs) | Lower (for deep graphs) | -| Shortest Path | Yes | No | -| Suitable for | Finding shortest paths | Solving puzzles (e.g., mazes)| - -## Code Implementation - -### Python Implementation: - -```python -from collections import deque - -# BFS Implementation -def bfs(graph, start): - visited = set() - queue = deque([start]) - - while queue: - vertex = queue.popleft() - if vertex not in visited: - visited.add(vertex) - print(vertex, end=' ') - queue.extend(neighbor for neighbor in graph[vertex] if neighbor not in visited) - -# Example usage -graph = { - 'A': ['B', 'C'], - 'B': ['A', 'D'], - 'C': ['A', 'D'], - 'D': ['B', 'C'] -} -bfs(graph, 'A') # Output: A B C D -# DFS Implementation -def dfs(graph, start, visited=None): - if visited is None: - visited = set() - if start not in visited: - visited.add(start) - print(start, end=' ') - for neighbor in graph[start]: - dfs(graph, neighbor, visited) - -# Example usage -dfs(graph, 'A') # Output: A B D C -``` - -### Java Implementation: -```java -import java.util.*; - -public class Graph { - private Map> adjList; - - public Graph() { - adjList = new HashMap<>(); - } - - public void addEdge(String source, String destination) { - adjList.putIfAbsent(source, new ArrayList<>()); - adjList.putIfAbsent(destination, new ArrayList<>()); - adjList.get(source).add(destination); - adjList.get(destination).add(source); // For undirected graph - } - - // BFS Implementation - public void bfs(String start) { - Set visited = new HashSet<>(); - Queue queue = new LinkedList<>(); - queue.add(start); - - while (!queue.isEmpty()) { - String vertex = queue.poll(); - if (!visited.contains(vertex)) { - visited.add(vertex); - System.out.print(vertex + " "); - queue.addAll(adjList.get(vertex)); - } - } - } - - // DFS Implementation - public void dfs(String start) { - Set visited = new HashSet<>(); - dfsHelper(start, visited); - } - - private void dfsHelper(String vertex, Set visited) { - if (!visited.contains(vertex)) { - visited.add(vertex); - System.out.print(vertex + " "); - for (String neighbor : adjList.get(vertex)) { - dfsHelper(neighbor, visited); - } - } - } - - public static void main(String[] args) { - Graph g = new Graph(); - g.addEdge("A", "B"); - g.addEdge("A", "C"); - g.addEdge("B", "D"); - g.addEdge("C", "D"); - - g.bfs("A"); // Output: A B C D - System.out.println(); - g.dfs("A"); // Output: A B D C - } -} -``` - -### Real-World Applications -BFS and DFS are widely used in various domains, such as: - --**Web Crawling**: Exploring the web by visiting pages in breadth or depth. --**Social Networks**: Finding friends of friends (BFS) or deep connections (DFS). --**Pathfinding**: In games or robotics, to find routes or explore environments. - -### Conclusion -Understanding BFS and DFS is crucial for solving complex problems in graph theory. Both algorithms have their strengths and are suited for different tasks. Mastering these traversal methods can significantly enhance your problem-solving skills in data structures and algorithms. \ No newline at end of file diff --git a/blog/Getting-started-with-array-data-structure.md b/blog/Getting-started-with-array-data-structure.md deleted file mode 100644 index 87cb3d43c..000000000 --- a/blog/Getting-started-with-array-data-structure.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -slug: Getting-started-with-array-data-structure -title: Getting Started With Array Data Structure -authors: [Rishi-Verma] -tags: [Rishi-Verma, algo, dsa, algorithms, array,c++,java,python] ---- - -Array is a collection of items of the same variable type that are stored at contiguous memory locations. It is one of the most popular and simple data structures used in programming. In this article, we have decided to provide a complete guide for Arrays, which will help you to tackle any problem based on Arrays. - - - -In this blog, we'll break down: - -- **What is an Array**: Array is a Linear Data Structure that Stores collection of items. -- **Basic Terminologies of array** like $(Array Index)$, $(Array Element)$, and $O(Array Length)$. -- **Declaration and Intialization of Array** and its time and Space Complexity. -- **Operation on Array** -- **Advantages and Disadvantages of Array** - ---- - -## What is Array? - -Array is a linear data structure that stores a collection of items of same data type in contiguous memory locations. Each item in an array is indexed starting with 0. We can directly access an array element by using its index value. - -### Basic Terminologies of Array: - -1. **$(Array Index)$ :** - - In an array, elements are identified by their indexes. Array index starts from 0. - -2. **$(Array Element)$ :** - - Elements are items stored in an array and can be accessed by their index. - -3. **$(Array Length)$ :** - - The length of an array is determined by the number of elements it can contain. - -### Declaration and Intialization of Array: -Arrays can be declared in various ways in different languages. For better illustration, below are some language-specific array declarations: - -```C++ title="main.cpp" -// This array will store integer type element -int arr[5]; -// This array will store char type element -char arr[10]; -// This array will store float type element -float arr[20]; -``` - -Arrays can be initialized in different ways in different languages. Below are some language-specific array initializations: - -```C++ title="main.cpp" -int arr[] = { 1, 2, 3, 4, 5 }; -char arr[5] = { 'a', 'b', 'c', 'd', 'e' }; -float arr[10] = { 1.4, 2.0, 24, 5.0, 0.0 }; -``` - ---- - -## Operation on Array - -1. **Array Traversal** - -Array traversal involves visiting all the elements of the array once. Below is the implementation of Array traversal in C++. - -```C++ title="main.cpp" -int arr[] = { 1, 2, 3, 4, 5 }; -int len = sizeof(arr) / sizeof(arr[0]); -// Traversing over arr[] -for (int i = 0; i < len; i++) { - cout << arr[i] << " "; -``` - -2. **Insertion in Array** - -We can insert one or multiple elements at any position in the array. Below is the implementation of Insertion in Array in C++. - -```C++ title="main.cpp" -// Function to insert element -// at a specific position -void insertElement(int arr[], int n, int x, int pos) -{ - // shift elements to the right - // which are on the right side of pos - for (int i = n - 1; i >= pos; i--) - arr[i + 1] = arr[i]; - - arr[pos] = x; -} - -``` -2. **Deletion in Array** - -We can delete an element at any index in an array. Below is the implementation of Deletion of element in an array in different C++. - -```C++ title="main.cpp" -// Function to insert element -// at a specific position -// To search a key to be deleted -int findElement(int arr[], int n, int key); - -// Function to delete an element -int deleteElement(int arr[], int n, int key) -{ - // Find position of element to be deleted - int pos = findElement(arr, n, key); - - if (pos == -1) { - cout << "Element not found"; - return n; - } - - // Deleting element - int i; - for (i = pos; i < n - 1; i++) - arr[i] = arr[i + 1]; - - return n - 1; -} - -// Function to implement search operation -int findElement(int arr[], int n, int key) -{ - int i; - for (i = 0; i < n; i++) - if (arr[i] == key) - return i; - // Return -1 if key is not found - return -1; -} -``` -2. **Searching in Array** - -We can traverse over an array and search for an element. Below is the implementation of Deletion of element in an arrayin C++. - -```C++ title="main.cpp" -// Function to implement search operation -int findElement(int arr[], int n, int key) -{ - int i; - for (i = 0; i < n; i++) - if (arr[i] == key) - return i; - - // If the key is not found - return -1; -} - -``` -### Advantages of Array - -- Arrays allow random access to elements. This makes accessing elements by position faster. - -- Arrays have better cache locality which makes a pretty big difference in performance. -- Arrays represent multiple data items of the same type using a single name. -- Arrays are used to implement the other data structures like linked lists, stacks, queues, trees, graphs, etc. - -### Disadvantages of Array: - -- As arrays have a fixed size, once the memory is allocated to them, it cannot be increased or decreased, making it impossible to store extra data if required. An array of fixed size is referred to as a static array. -- Allocating less memory than required to an array leads to loss of data. -- An array is homogeneous in nature so, a single array cannot store values of different data types. - ---- -## Final Thoughts - -We concluded that arrays are a simple method of accessing elements of the same type by grouping them and we can find the elements efficiently by their indexes and can perform different operations using them. Thus, they are more efficient when it comes to memory allocation and should be used in all modern programming languages. diff --git a/blog/Kadanes-algorithm.md b/blog/Kadanes-algorithm.md deleted file mode 100644 index cef44d073..000000000 --- a/blog/Kadanes-algorithm.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -slug: kadanes-algorithm -title: "Kadane's Algorithm Explained: Efficient Maximum Subarray Sum" -authors: [LOKESH-BIJARNIYA] -tags: [lokesh-bijarniya, algo, dsa, algorithms, dynamic-programming] ---- - -Kadane's Algorithm is a popular and efficient approach to solving the maximum subarray sum problem. It uses dynamic programming to find the contiguous subarray with the largest sum in linear time. This blog post will provide an in-depth look at how Kadane's Algorithm works, why it's useful, and how you can implement it in various programming languages. - - - -In this blog, we'll explore: - -- **Understanding the Maximum Subarray Problem**: What is the problem, and why is it important? -- **Kadane's Algorithm**: A step-by-step explanation of how it works. -- **Implementation**: Code examples in Java and Python. -- **Real-World Applications**: How this algorithm is useful in real-life scenarios. - ---- - -## The Maximum Subarray Problem - -The maximum subarray problem is about finding the contiguous subarray within a one-dimensional numeric array that has the largest sum. Given an array of both positive and negative numbers, the goal is to find the subarray with the maximum possible sum. - -### Problem Example: - -```python -Input: [-2, 1, -3, 4, -1, 2, 1, -5, 4] -Output: 6 # Subarray: [4, -1, 2, 1] -``` - -## Understanding Kadane's Algorithm - -The brilliance of Kadane's Algorithm lies in its simplicity. It processes the array in a single pass, maintaining two values: the current sum of the subarray (`currentSum`) and the maximum sum found so far (`maxSum`). - -### The Algorithm - -1. **Initialization**: Start with the first element as both `currentSum` and `maxSum`. -2. **Iterate Through the Array**: For each element, decide whether to add it to the current subarray or start a new subarray. -3. **Update Maximum**: At each step, check if the current subarray sum is the highest so far. -4. **Result**: After processing the entire array, the `maxSum` will contain the maximum subarray sum. - -### Step-by-Step Breakdown: - -1. Initialize: - - `currentSum = arr[0]` - - `maxSum = arr[0]` - -2. Loop through the array starting from index 1: - - `currentSum = max(arr[i], currentSum + arr[i])` - - `maxSum = max(maxSum, currentSum)` - -### Time Complexity - -Kadane’s Algorithm runs in O(n) time, where `n` is the number of elements in the array. This makes it highly efficient compared to brute force methods, which would require O(n²) time. - -## Code Implementation - -### Python Implementation: - -```python -def kadane(arr): - currentSum = maxSum = arr[0] - - for i in range(1, len(arr)): - currentSum = max(arr[i], currentSum + arr[i]) - maxSum = max(maxSum, currentSum) - - return maxSum - -# Example usage -arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4] -print(kadane(arr)) # Output: 6 -``` - -### Java Implementation: - -```java -public class Kadane { - public static int kadane(int[] arr) { - int currentSum = arr[0]; - int maxSum = arr[0]; - - for (int i = 1; i < arr.length; i++) { - currentSum = Math.max(arr[i], currentSum + arr[i]); - maxSum = Math.max(maxSum, currentSum); - } - - return maxSum; - } - - public static void main(String[] args) { - int[] arr = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; - System.out.println(kadane(arr)); // Output: 6 - } -} -``` - -## Real-World Applications - -Kadane's Algorithm is useful in various practical scenarios such as: - -- **Stock Price Analysis**: Finding the best time to buy and sell stocks to maximize profit over a series of days. -- **Signal Processing**: Identifying the largest continuous segment of high values in a signal or data stream. -- **Game Development**: Optimizing score tracking in continuous gameplay segments. - -### Conclusion - -Kadane’s Algorithm is a powerful tool for solving the maximum subarray problem efficiently. Its linear time complexity makes it a go-to solution in competitive programming and technical interviews. Understanding the algorithm, as well as its potential applications, can greatly enhance your problem-solving skills in dynamic programming. - diff --git a/blog/Recursion-vs-Iteration.md b/blog/Recursion-vs-Iteration.md deleted file mode 100644 index 1b9e9d95a..000000000 --- a/blog/Recursion-vs-Iteration.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -slug: recursion-vs-iteration -title: "Recursion vs. Iteration: A Comparative Analysis" -authors: [AKSHITHA-CHILUKA] -tags: [AKSHITHA-CHILUKA, algo, dsa, algorithms, recursion, iteration] ---- - -When designing algorithms, a common question arises: should you use recursion or iteration? Each approach has its strengths and weaknesses, and understanding these can help you choose the right one for your problem. - - - -In this blog, we'll compare: - -- **Performance**: How recursion and iteration differ in execution time and space. -- **Readability**: The clarity of code in recursive vs. iterative solutions. - ---- - -## Performance - -### Recursion - -- **Pros**: Easier to implement for problems that naturally fit a recursive structure, like tree traversals. -- **Cons**: May lead to stack overflow errors due to deep recursion. Higher space complexity due to function call stack. - -#### Example: Recursive Fibonacci - -```javascript -function fibonacci(n) { - if (n <= 1) return n; - return fibonacci(n - 1) + fibonacci(n - 2); -} -``` -## Iteration -Pros: More memory-efficient as it avoids the overhead of recursive function calls. Generally faster for most problems. -Cons: Can be less intuitive for problems that have a natural recursive structure. - -#### Example: Iterative Fibonacci - -```javascript -function fibonacci(n) { - let a = 0, b = 1; - for (let i = 2; i <= n; i++) { - [a, b] = [b, a + b]; - } - return b; -} -``` -## Readability -Recursion often results in cleaner and more understandable code for problems that involve hierarchical structures, while iteration may require additional variables and conditions. - -## Conclusion -Choosing between recursion and iteration depends on the specific problem you're tackling. Consider the trade-offs in performance and readability to make the best choice. diff --git a/blog/Understanding-Graph-Representation.md b/blog/Understanding-Graph-Representation.md deleted file mode 100644 index bdf777dba..000000000 --- a/blog/Understanding-Graph-Representation.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -slug: understanding-graph-representation-adjacency-matrix-vs-adjacency-list -title: "Understanding Graph Representation: Adjacency Matrix vs Adjacency List" -authors: [Harshitha-Grandhi] -tags: [Harshitha-Grandhi, algo, dsa, algorithms, graph-theory] ---- - -Graph representation is essential for effectively implementing graph algorithms and understanding the relationships between nodes. The two most common representations of graphs are the **Adjacency Matrix** and the **Adjacency List**. This blog post will compare these two representations, discussing their structures, advantages, and use cases. - - - -In this blog, we'll explore: - -- **Understanding Graphs**: What are graphs and their components? -- **Adjacency Matrix**: Structure and characteristics. -- **Adjacency List**: Structure and characteristics. -- **Comparison of Adjacency Matrix and Adjacency List**: When to use which representation. -- **Implementation**: Code examples in Python and Java. -- **Real-World Applications**: How these representations are applied in practice. - ---- - -## Understanding Graphs - -Graphs consist of vertices (nodes) connected by edges (links). They can be directed or undirected, weighted or unweighted, and are used to model relationships and structures in various fields, from social networks to transportation systems. - -### Graph Representation Example: - -Consider the following undirected graph: - -This graph can be represented using an adjacency matrix or an adjacency list. - -## Adjacency Matrix - -An adjacency matrix is a 2D array where each cell at position (i, j) indicates whether there is an edge between vertex i and vertex j. If there is an edge, the cell contains a value (usually 1 for unweighted graphs or the weight of the edge for weighted graphs); otherwise, it contains 0. - -### Characteristics: - -- **Space Complexity**: O(V²), where V is the number of vertices. -- **Direct Access**: Allows O(1) time complexity for checking if an edge exists between two vertices. -- **Memory Inefficiency**: Less efficient for sparse graphs (graphs with few edges compared to the number of vertices). - -### Example Implementation (Python): - -```python -class GraphAdjacencyMatrix: - def __init__(self, vertices): - self.V = vertices - self.matrix = [[0] * vertices for _ in range(vertices)] - - def add_edge(self, u, v): - self.matrix[u][v] = 1 # For undirected graph, add the reverse edge as well - self.matrix[v][u] = 1 - - def display(self): - for row in self.matrix: - print(row) - -# Example usage -g_matrix = GraphAdjacencyMatrix(4) -g_matrix.add_edge(0, 1) # A - B -g_matrix.add_edge(0, 2) # A - C -g_matrix.add_edge(1, 3) # B - D -g_matrix.add_edge(2, 3) # C - D -g_matrix.display() - -#output -[0, 1, 1, 0] -[1, 0, 0, 1] -[1, 0, 0, 1] -[0, 1, 1, 0] -``` - - -## Adjacency List -An adjacency list is a collection of lists or arrays where each list corresponds to a vertex and contains a list of adjacent vertices. It is more space-efficient for sparse graphs. - -### Characteristics: --**Space Complexity**: O(V + E), where E is the number of edges. --**Memory Efficiency**: More efficient for sparse graphs, as it only stores existing edges. --**Traversal**: It may take longer to check if an edge exists between two vertices (O(V) in the worst case). - -### Example Implementation (Python): -```python -class GraphAdjacencyList: - def __init__(self): - self.graph = {} - - def add_edge(self, u, v): - if u not in self.graph: - self.graph[u] = [] - if v not in self.graph: - self.graph[v] = [] - self.graph[u].append(v) # For undirected graph, add the reverse edge as well - self.graph[v].append(u) - - def display(self): - for vertex, edges in self.graph.items(): - print(f"{vertex}: {edges}") - -# Example usage -g_list = GraphAdjacencyList() -g_list.add_edge('A', 'B') # A - B -g_list.add_edge('A', 'C') # A - C -g_list.add_edge('B', 'D') # B - D -g_list.add_edge('C', 'D') # C - D -g_list.display() - -# output -A: ['B', 'C'] -B: ['A', 'D'] -C: ['A', 'D'] -D: ['B', 'C'] - - -``` - -### Java Implementation (Adjacency Matrix): -```java -public class GraphMatrix { - private int[][] matrix; - private int V; - - public GraphMatrix(int vertices) { - V = vertices; - matrix = new int[V][V]; - } - - public void addEdge(int u, int v) { - matrix[u][v] = 1; // For undirected graph, also set matrix[v][u] - matrix[v][u] = 1; - } - - public void display() { - for (int[] row : matrix) { - for (int val : row) { - System.out.print(val + " "); - } - System.out.println(); - } - } - - public static void main(String[] args) { - GraphMatrix g_matrix = new GraphMatrix(4); - g_matrix.addEdge(0, 1); // A - B - g_matrix.addEdge(0, 2); // A - C - g_matrix.addEdge(1, 3); // B - D - g_matrix.addEdge(2, 3); // C - D - g_matrix.display(); - } -} -//output: -0 1 1 0 -1 0 0 1 -1 0 0 1 -0 1 1 0 - - -``` - - -### Java Implementation (Adjacency List): -```java -import java.util.*; - -public class GraphList { - private Map> adjList; - - public GraphList() { - adjList = new HashMap<>(); - } - - public void addEdge(String u, String v) { - adjList.putIfAbsent(u, new ArrayList<>()); - adjList.putIfAbsent(v, new ArrayList<>()); - adjList.get(u).add(v); // For undirected graph, also add reverse edge - adjList.get(v).add(u); - } - - public void display() { - for (String vertex : adjList.keySet()) { - System.out.println(vertex + ": " + adjList.get(vertex)); - } - } - - public static void main(String[] args) { - GraphList g_list = new GraphList(); - g_list.addEdge("A", "B"); // A - B - g_list.addEdge("A", "C"); // A - C - g_list.addEdge("B", "D"); // B - D - g_list.addEdge("C", "D"); // C - D - g_list.display(); - } -} -//output: -A: [B, C] -B: [A, D] -C: [A, D] -D: [B, C] - -``` -### Real-World Applications -Understanding how to represent graphs using adjacency matrices and adjacency lists is crucial in many applications, such as: --**Social Network Analysis**: Modeling relationships between users. --**Routing Algorithms**: Efficiently determining paths in networks. --**Computer Networks**: Representing connections in a network topology. - -## Conclusion -Choosing the right graph representation is essential for optimizing the performance of graph algorithms. Adjacency matrices and adjacency lists each have their strengths and weaknesses, making them suitable for different scenarios. Mastering these representations will enhance your understanding of graph theory and improve your problem-solving skills in computer science. - - - - - diff --git a/blog/a-very-useful-data-structure-linked-lists.md b/blog/a-very-useful-data-structure-linked-lists.md deleted file mode 100644 index b125195ac..000000000 --- a/blog/a-very-useful-data-structure-linked-lists.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -slug: a-very-useful-data-structure-linked-lists -title: A Very Useful Data Structure - Linked Lists -authors: [Aryan-Jain] -tags: [linked-list, data-structures, algorithms, C++, java, python] ---- - -A linked list is a linear data structure where elements are not stored in contiguous memory locations. Instead, each element, or node, contains data and a pointer to the next node in the sequence. This structure offers flexibility and dynamic memory allocation, making it a powerful tool for various programming tasks. - - - -In this blog, we'll explore: - -- **Dynamic Size**: How linked lists can grow or shrink dynamically as needed. -- **Efficiency**: The benefits of insertion and deletion operations. -- **Flexibility**: Representing different data structures. - ---- - -## Why Use Linked Lists? - -* **Dynamic Size:** Linked lists can grow or shrink dynamically as needed, unlike arrays which have a fixed size. -* **Efficient Insertion and Deletion:** Inserting or deleting elements in a linked list is efficient, especially when operations are performed at the beginning or end of the list. -* **Flexibility:** Linked lists can represent various data structures, such as stacks, queues, and trees. -* **Memory Efficient:** Linked lists can be more memory efficient than arrays in certain scenarios, as they don't require contiguous memory allocation. - -## Types of Linked Lists - -1. **Singly Linked List:** Each node points to the next node. -2. **Doubly Linked List:** Each node points to both the next and previous nodes. -3. **Circular Linked List:** The last node points back to the first node, forming a circular structure. - -## Common Operations on Linked Lists - -* **Traversal:** Iterating through the list to access each node. -* **Insertion:** Adding a new node at a specific position. -* **Deletion:** Removing a node from a specific position. -* **Searching:** Finding a node with a specific value. -* **Reversal:** Reversing the order of nodes in the list. - -## Real-world Applications - -* Implementing data structures like stacks and queues -* Managing dynamic memory -* Creating undo/redo functionality in software -* Implementing music players and video players -* Implementing hash tables - -## C Code Examples - -### Singly Linked List - -```c -#include -#include - -struct Node { - int data; - struct Node* next; -}; - -// Function to create a new node -struct Node* newNode(int data) { - struct Node* new_node = (struct Node*)malloc(sizeof(struct Node)); - new_node->data = data; - new_node->next = NULL; - return new_node; -} - -// Function to insert a new node at the beginning -void insertAtBeginning(struct Node** head_ref, int new_data) { - struct Node* new_node = newNode(new_data); - new_node->next = (*head_ref); - (*head_ref) = new_node; -} - -// Function to print the linked list -void printList(struct Node* head) { - struct Node* temp = head; - while (temp != NULL) { - printf("%d ", temp->data); - temp = temp->next; - } - printf("\n"); -} - -int main() { - struct Node* head = NULL; - - insertAtBeginning(&head, 3); - insertAtBeginning(&head, 2); - insertAtBeginning(&head, 1); - - printList(head); - - return 0; -} -``` diff --git a/blog/a-very-useful-data-structure-string.md b/blog/a-very-useful-data-structure-string.md deleted file mode 100644 index 24082ee3b..000000000 --- a/blog/a-very-useful-data-structure-string.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -slug: a-very-useful-data-structure-string -title: 'A Very Useful Data Structure i.e. String' -authors: [Rishi-Verma] -tags: [string, algorithms, dsa, C++, narendra-dhangar,java,python,data-structures] ---- - -In data structures, a string is a sequence of characters used to represent text. Strings are commonly used for storing and manipulating textual data in computer programs. They can be manipulated using various operations like concatenation, substring extraction, and comparison. - - - -## What is String? - -In Data Structure, a string is a data type used to represent a sequence of characters. Strings can include letters, numbers, symbols, and spaces. They are often used to represent text, such as words, sentences, or any collection of readable characters. - -**Below are Some Examples of String:** -```markdown -"geeks","for","geeks""GeeksforGeeks" ,"Geeks for Geeks","123Geeks","@123 Geeks" -``` -## How String is Represented: - -In C, a string can be referred to either using a character pointer or as a character array. Here are some important points: - -- **Character Array**: When strings are declared as character arrays, they are stored like other types of arrays in C. - ```c - char str[] = "Hello, World!"; - ``` - - If `str[]` is an auto variable, the string is stored in the stack segment. - - If `str[]` is a global or static variable, it is stored in the data segment. - -- **Character Pointer**: Strings can also be referred to using a character pointer. - ```c - char *str = "Hello, World!"; - ``` - - The string literal is stored in the read-only section of memory, and `str` points to this location. - -Understanding these storage mechanisms is crucial for efficient memory management and avoiding common pitfalls like buffer overflows. - - -### How String is represented in Memory: -In C, a string can be referred to either using a character pointer or as a character array. When strings are declared as character arrays, they are stored like other types of arrays in C. For example, if str[] is an auto variable then the string is stored in the stack segment, if it’s a global or static variable then stored in the data segment, etc. - ---- - -### Declaration of Strings: - -In various programming languages, strings can be declared in different ways. Here are some examples: - -- **C++**: - ```cpp - std::string str = "Hello, World!"; - ``` - -- **Java**: - ```java - String str = "Hello, World!"; - ``` - -- **Python**: - ```python - str = "Hello, World!" - ``` - -Each language has its own syntax and methods for handling strings, but the fundamental concept remains the same: a string is a sequence of characters. - - diff --git a/blog/authors.yml b/blog/authors.yml deleted file mode 100644 index 2498c1ff9..000000000 --- a/blog/authors.yml +++ /dev/null @@ -1,114 +0,0 @@ -ajay-dhangar: - name: Ajay Dhangar - title: Founder of CodeHarborHub - url: https://ajay-dhangar.github.io/ - image_url: https://avatars.githubusercontent.com/u/99037494?v=4 - email: ajaydhangar49@gmail.com - page: true # Turns the feature on - description: > - A passionate developer who loves to code and build new things. I am a Full Stack Developer and a Cyber Security, ML & AI Enthusiast. I am also a Technical Content Writer and a Speaker. I love to share my knowledge with the community. I am the Founder of CodeHarborHub. I am also a Technical Content Writer at GeeksforGeeks. I am a Girl Script Summer of Code 2024 Project Manager (PA). - - socials: - x: CodesWithAjay - linkedin: ajay-dhangar - github: ajay-dhangar - stackoverflow: 18530900 - newsletter: https://ajay-dhangar.github.io - -narendra-dhangar: - name: Narendra Dhangar - title: B.Tech (CSE) Student - url: https://www.instagram.com/narendra_dh._05/ - image_url: https://github.com/narendra-dhangar.png - email: narendradhangar63@gmail.com - page: true # Turns the feature on - description: > - A dedicated Computer Science and Engineering student with a passion for problem-solving and algorithms. I am constantly exploring various fields of computer science, from data structures and algorithms to web development and machine learning. As an avid learner, I enjoy tackling challenging problems and sharing knowledge with the community. Eager to contribute to open-source projects and make an impact in the tech world. - - socials: - linkedin: narendra-dhangar-880558297 - github: narendra-dhangar - -AKSHITHA-CHILUKA: - name: Chiluka Akshitha - title: B.Tech (IT) Student - url: https://github.com/AKSHITHA-CHILUKA - image_url: https://github.com/AKSHITHA-CHILUKA.png - email: 22wh1a12b5@bvrithyderabad.edu.in - page: true # Turns the feature on - description: > - a passionate software developer with an interest in developing innovative programs. - socials: - linkedin: https://www.linkedin.com/in/akshitha-chiluka-b19245259/ - github: https://github.com/AKSHITHA-CHILUKA - - -ADITYA-JANI: - name: Aditya Jani - title: First-Year MCA Student, Developer, Tech Enthusiast - url: https://github.com/AdityaJani616 - image_url: https://github.com/AdityaJani616.png - email: adityajani616@gmail.com - page: true # Turns the feature on - description: > - A passionate developer with an interest in building solutions that blend technology and social impact. I am a Full Stack Developer, with a keen interest in projects related to web development, and community-driven initiatives. - socials: - linkedin: https://www.linkedin.com/in/adityajani616 - github: https://github.com/AdityaJani616 - portfolio: https://portfolio-azure-tau-65.vercel.app/ - - -Rishi-Verma: - name: Rishi Verma - title: B.Tech(CSE) STUDENT, Developer, Tech Enthusiast , Competitive Programmer - url: https://github.com/coder-writes - image_url: https://github.com/coder-writes.png - email: vrishi7654@gmail.com - page: true # Turns the feature on - description: > - A tech enthusiast and competitive programmer with a knack for developing innovative solutions. I am a B.Tech(CSE) student who loves to dive deep into coding challenges and explore the latest trends in technology. My interests span across web development, software engineering, and community-driven projects. - socials: - linkedin: https://www.linkedin.com/in/rishi-verma-sde/ - github: https://github.com/coder-writes - -LOKESH-BIJARNIYA: - name: Lokesh Bijarniya - title: BTech CSE Student | Full Stack Developer | DSA Enthusiast - url: https://github.com/Lokesh-Bijarniya - image_url: https://github.com/Lokesh-Bijarniya.png - email: lkbijarniya2@gmail.com - page: true # Turns the feature on - description: > - I am a BTech CSE student with a passion for full stack development and a deep interest in data structures and algorithms (DSA). As an aspiring software engineer, I enjoy building web applications that solve real-world problems and continuously improving my problem-solving skills through DSA. My goal is to create impactful solutions using modern technologies, while constantly learning and growing in the field of software development. - socials: - linkedin: https://www.linkedin.com/in/lokesh-bijarniya/ - github: https://github.com/Lokesh-Bijarniya/ - leetcode: https://leetcode.com/u/Lokesh_Bijarniya_/ - portfolio: https://lokesh-bijarniya-portfolio.vercel.app/ - - -Harshitha-Grandhi: - name: Grandhi Harshitha - title: B.Tech (IT) Student - url: https://github.com/Grandhi-Harshitha - image_url: https://avatars.githubusercontent.com/u/120390344?v=4 - email: 22wh1a1295@bvrithyderabad.edu.in - page: true # Turns the feature on - description: > - a passionate software developer with an interest in developing innovative programs. - socials: - linkedin: https://www.linkedin.com/in/harshitha-grandhi-0a0890308/ - github: https://github.com/Grandhi-Harshitha - -Aryan-Jain: - name: Aryan Jain - title: B.Tech (CSE) Student - url: https://github.com/jainaryan04 - image_url: https://avatars.githubusercontent.com/u/138214350?v=4 - email: aryanrameshjain@gmail.com - page: true # Turns the feature on - description: > - full stack developer - socials: - linkedin: https://www.linkedin.com/in/jainaryan04/ - github: https://github.com/jainaryan04 \ No newline at end of file diff --git a/blog/balancing-speed-and-memory-A-Guide-to-Time-and-Space-Complexity.md b/blog/balancing-speed-and-memory-A-Guide-to-Time-and-Space-Complexity.md deleted file mode 100644 index 5c5eea3b6..000000000 --- a/blog/balancing-speed-and-memory-A-Guide-to-Time-and-Space-Complexity.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -slug: balancing-speed-and-memory-A-Guide-to-Time-and-Space-Complexity -title: "Balancing Speed and Memory: A Guide to Time and Space Complexity" -authors: [ADITYA-JANI] -tags: [ADITYA-JANI, algorithms, time-complexity,dsa, space-complexity, big-o-notation, efficiency, optimization, coding, programming, computer-science, learning] ---- -At its core, an algorithm is a step-by-step procedure or formula for solving a problem. From following a recipe to searching for a word in a dictionary or navigating the fastest route on Google Maps, algorithms are at work. In the realm of computer science, algorithms are the driving force behind how programs process data, make decisions, and deliver results efficiently. - -In this blog, we’ll cover: - -- **Why Algorithms are Important** -- **Time Complexity** -- **Space Complexity** -- **The Time-Space Trade-off** -- **Conclusion** - -## Why are Algorithms Important? -Algorithms are crucial because they define how efficiently a task can be performed. The same problem can have multiple solutions, but some solutions are faster, use less memory, or are more scalable. Here's why algorithms matter: - -- **Efficiency**: Well-designed algorithms perform tasks faster, saving computing resources and time. -- **Optimization**: They help in choosing the best possible solution for problems. -- **Scalability**: Efficient algorithms are key when scaling applications to handle large amounts of data. - -Let’s imagine you’re searching for a book in a library. You could: - -- Start looking at every shelf randomly until you find it (brute force method). -- Or, you could follow the library’s categorization (like starting at the correct genre or alphabetically arranged sections) to minimize the search time. - -The second approach is more efficient and resembles an algorithm designed to optimize search time. This demonstrates how algorithms allow you to perform tasks in an optimized and structured way. - -When evaluating algorithms, two key metrics come into play: **time complexity** and **space complexity**. These determine how efficient an algorithm is in terms of speed and memory usage. - -## Time Complexity - -Time complexity refers to how an algorithm’s runtime scales as the input size grows. It is expressed using Big O notation. Common examples include: - -- **O(1)**: Constant time—performance remains the same regardless of input size. -- **O(n)**: Linear time—the runtime increases proportionally to the input size. -- **O(n²)**: Quadratic time—common in nested loops, it slows down significantly as input size grows. - -For example, if you’re sorting a list, algorithms with **O(n log n)** (like Merge Sort) are more efficient than **O(n²)** (like Bubble Sort) for large datasets. - -## Space Complexity - -Space complexity measures how much memory an algorithm uses as the input size increases. Some algorithms might be fast but require extra memory, while others might be slower but use less memory. Common space complexities include: - -- **O(1)**: Constant space—no extra memory used. -- **O(n)**: Linear space—memory usage grows with the input size. - -For example, sorting algorithms like Merge Sort require additional memory, while Quick Sort can sort "in place," using less memory. - -## The Time-Space Trade-off - -In practice, developers often face a trade-off between time and space complexity. A faster algorithm may use more memory, while a memory-efficient algorithm might be slower. The key is to balance both, depending on the problem’s requirements. - - -## Conclusion - -Understanding the balance between time and space complexity is crucial for developing efficient algorithms. By evaluating the trade-offs, you can choose the best approach for your specific problem. This knowledge not only enhances your coding skills but also prepares you to tackle larger datasets effectively. Embrace the principles of algorithm efficiency to optimize your applications and ensure scalable solutions. diff --git a/blog/language-matters-your-path-to-dsa-success-starts-here.md b/blog/language-matters-your-path-to-dsa-success-starts-here.md deleted file mode 100644 index 5a408b71f..000000000 --- a/blog/language-matters-your-path-to-dsa-success-starts-here.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -slug: language-matters-your-path-to-dsa-success-starts-here -title: "Language Matters: Your Path to DSA Success Starts Here" -authors: [ADITYA-JANI] -tags: [ADITYA-JANI, programming, dsa, data-structures, algorithms, python, java, c++, learning] ---- -In the realm of computer science and software development, mastering Data Structures and Algorithms (DSA) is crucial for creating efficient and effective software solutions. However, a common question arises: Which programming language should one choose to learn DSA? This blog explores the factors to consider when choosing a language for DSA, highlights some of the most popular languages, and provides recommendations based on various scenarios. - - -In this blog, we’ll cover: - -- **Factors to Consider** -- **Popular Languages for DSA** -- **Conclusion** - ---- -## Factors to Consider - -- **Syntax**: Choose a language with clear syntax to focus on concepts rather than complexity. - -- **Community**: A strong community provides support and resources for learning. - -- **Performance**: Consider the efficiency of the language, especially for computationally intensive tasks. - -- **Industry Relevance**: Opt for languages in demand in the job market. - -- **Personal Preference**: Select a language you enjoy and feel motivated to learn. -## Popular Languages for DSA - -### 1. Python -- **Pros**: Simple syntax, rich libraries, large community. -- **Cons**: Slower performance. -- **Recommendation**: Ideal for beginners and quick implementation. - -### 2. Java -- **Pros**: Strong OOP features, high performance, extensive resources. -- **Cons**: More verbose syntax. -- **Recommendation**: Balanced choice for students and professionals. - -### 3. C++ -- **Pros**: Fast execution, efficient memory management, STL support. -- **Cons**: Complex syntax. -- **Recommendation**: Best for competitive programming and performance-focused projects. - -### 4. C# -- **Pros**: Strong OOP, excellent tooling. -- **Cons**: Less popular in competitive programming. -- **Recommendation**: Great for Microsoft environments and game development. - -### 5. JavaScript -- **Pros**: Widely used in web development, practical application of algorithms. -- **Cons**: Lower performance compared to compiled languages. -- **Recommendation**: Suitable for web developers. - - -## Conclusion - -Your choice of language for DSA should align with your goals and preferences. Python is excellent for beginners, while C++ suits competitive programmers. Java and C# are ideal for application development. Focus on mastering DSA concepts, and the programming language will enhance your problem-solving abilities. \ No newline at end of file diff --git a/blog/mastering-recursion.md b/blog/mastering-recursion.md deleted file mode 100644 index da32478b5..000000000 --- a/blog/mastering-recursion.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -slug: mastering-recursion -title: 'Mastering Recursion: Concepts, Problems, and Optimization' -authors: [narendra-dhangar] -tags: [recursion, algorithms, dsa, optimization, narendra-dhangar] ---- - -Recursion is a fundamental concept in programming and problem-solving. It provides an elegant solution to many problems, yet understanding recursion requires a solid grasp of the underlying principles. In this blog, we will dive deep into the concept of recursion, explore common recursive problems, and look at techniques for optimizing recursive algorithms. - - - -## What is Recursion? - -Recursion is a process where a function calls itself to solve a problem. A recursive function breaks down a problem into smaller, easier-to-solve sub-problems. - -### Structure of a Recursive Function: -A typical recursive function consists of two main parts: -1. **Base Case**: The condition under which the recursion ends. Without this, the function would call itself indefinitely, leading to a stack overflow. -2. **Recursive Case**: The part where the function calls itself to solve smaller instances of the problem. - -### Example of Recursion: -Here’s a simple example of recursion, calculating the factorial of a number `n`: - -```javascript -function factorial(n) { - if (n === 0) { - return 1; // Base case: factorial of 0 is 1 - } - return n * factorial(n - 1); // Recursive case -} -``` - -In this example, the problem of calculating the factorial is broken down into multiplying `n` by the factorial of `n - 1`, until it reaches the base case. - ---- - -## Key Concepts in Recursion: - -1. **Base Case and Recursive Case**: These are the most critical components of any recursive function. Without a base case, your function will recurse infinitely. - -2. **Stack Memory**: Every time a recursive function is called, its execution is stored in the stack. When the base case is reached, the function starts returning, popping values off the stack. - -3. **Recursive Tree**: Visualizing recursion as a tree can help in understanding how recursive calls are executed. Each recursive call splits into further sub-calls until the base case is hit. - -### Common Pitfalls: -- **Missing Base Case**: Leads to infinite recursion. -- **Redundant Computations**: In some problems, recursive calls recompute the same values multiple times (like in the Fibonacci sequence). - ---- - -## Recursion Problems: - -### 1. Fibonacci Series: - -The Fibonacci series is a classic problem to demonstrate recursion. The nth Fibonacci number is the sum of the two preceding numbers. - -**Recursive Fibonacci Solution**: - -```javascript -function fibonacci(n) { - if (n <= 1) { - return n; // Base case - } - return fibonacci(n - 1) + fibonacci(n - 2); // Recursive case -} -``` - -While this solution is intuitive, it performs redundant computations and can be very slow for larger values of `n`. - ---- - -## Optimizing Recursive Algorithms: - -### 1. **Memoization**: -Memoization stores the results of expensive function calls and reuses them when the same inputs occur again, reducing the time complexity of the function. - -**Optimized Fibonacci with Memoization**: - -```javascript -function fibonacci(n, memo = {}) { - if (n in memo) { - return memo[n]; // Return stored result if available - } - if (n <= 1) { - return n; // Base case - } - memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo); // Recursive call with memoization - return memo[n]; -} -``` -This optimized version reduces the time complexity from $O(2^n)$ to $O(n)$. - -### 2. **Tail Recursion**: -Tail recursion is a specific form of recursion where the recursive call is the last thing executed by the function. Tail-recursive functions can be optimized by some compilers or interpreters to prevent stack overflow. - -**Tail-Recursive Factorial**: - -```javascript -function tailFactorial(n, accumulator = 1) { - if (n === 0) { - return accumulator; // Base case - } - return tailFactorial(n - 1, n * accumulator); // Tail-recursive call -} -``` - -### 3. **Recursion to Iteration**: -For some problems, recursion can be replaced with iteration to avoid deep recursion, which can lead to stack overflow. Converting recursive functions to iterative ones ensures better memory management. - ---- - -## Problem-Solving with Recursion: - -Recursion is widely used to solve various algorithmic problems, such as: - -1. **Binary Search**: - A divide-and-conquer algorithm that works efficiently by dividing the array into halves. - -2. **Towers of Hanoi**: - A mathematical problem that requires moving disks between rods under certain conditions. - -3. **Permutations and Combinations**: - Recursion is used to generate all possible arrangements of a set of items. - -4. **Tree Traversal**: - Recursion is the natural way to traverse tree structures, such as in **pre-order**, **in-order**, and **post-order** traversals. - ---- - -## Conclusion: - -Recursion is a powerful tool in a developer's arsenal. However, it is essential to understand when and how to use it effectively. Optimizing recursive algorithms with techniques like memoization, tail recursion, or converting them into iterative solutions ensures they remain efficient even for large inputs. - -With practice, mastering recursion will open doors to solving complex problems in a more structured and elegant way. diff --git a/blog/omega-notation-the-key-to-understanding-algorithm-efficiency.md b/blog/omega-notation-the-key-to-understanding-algorithm-efficiency.md deleted file mode 100644 index 472445fc6..000000000 --- a/blog/omega-notation-the-key-to-understanding-algorithm-efficiency.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -slug: omega-notation-the-key-to-understanding-algorithm-efficiency -title: "Omega Notation: The Key to Understanding Algorithm Efficiency" -authors: [ADITYA-JANI] -tags: [ADITYA-JANI, algorithms,dsa, omega-notation, time-complexity, space-complexity, efficiency, optimization, coding, programming, computer-science, learning] ---- - -When working with algorithms, understanding their performance is crucial, especially in the best-case scenarios. Omega Notation is a mathematical concept that helps computer scientists and developers measure the lower bounds of an algorithm's efficiency. It allows us to analyze how the algorithm’s runtime or space requirements behave in the most favorable conditions. - -In this blog, we’ll cover: - -- **Why Omega Notation is Important** -- **Time Complexity** -- **Space Complexity** -- **The Omega-Time Trade-off** - -## What is Omega Notation? - -At its core, Omega Notation describes the best-case scenario for the growth of an algorithm’s runtime or memory usage. It focuses on two main aspects: - -- **Time Complexity**: The minimum time an algorithm takes to complete. -- **Space Complexity**: The minimum memory an algorithm requires. - -### Important Points: - -- Omega notation describes the asymptotic behavior of a function in the best-case scenario, not its exact value. -- It can be used to provide a lower bound for the efficiency of different algorithms or data structures. - -## Why is Omega Notation Important? - -Understanding Omega Notation is essential for assessing the potential efficiency of algorithms. For instance, if you have a sorting algorithm that typically performs well but has a worst-case scenario that significantly slows down performance, knowing the best-case (Omega) can help you gauge its effectiveness. - -By knowing the Omega of an algorithm, you can: - -- Identify the best-performing algorithms for specific scenarios. -- Make decisions based on optimal conditions. -- Develop strategies to enhance algorithm performance under ideal circumstances. - -## Common Omega Notations - -Here are some common Omega notations you’ll encounter: - -- **Ω(1)**: Constant time—performance remains the same regardless of input size. -- **Ω(n)**: Linear time—the runtime increases proportionally to the input size. -- **Ω(n log n)**: Linearithmic time—typical for efficient algorithms that can perform well with larger datasets. -- **Ω(n²)**: Quadratic time—common in algorithms with nested loops, indicating performance in favorable conditions. -- **Ω(2ⁿ)**: Exponential time—although inefficient in general, it provides insight into the best-case scenario for certain algorithms. - -## Understanding Omega with a Real-Life Example - -Imagine you're searching for a specific book in a library: - -- **Ω(1)**: You ask the librarian, and they instantly tell you where the book is. -- **Ω(n)**: You find the book on the first shelf you check. -- **Ω(log n)**: You follow a structured approach, like dividing the library in half each time (binary search). - -## Conclusion - -Omega Notation is essential for understanding the efficiency of algorithms in optimal scenarios. By grasping its principles, you can write more effective code, choose the right algorithms, and design scalable applications. Whether you're optimizing your code or analyzing existing algorithms, Omega Notation will always be a crucial tool in your toolkit. diff --git a/blog/optimizing-recursive-functions.md b/blog/optimizing-recursive-functions.md deleted file mode 100644 index 8ca42fa65..000000000 --- a/blog/optimizing-recursive-functions.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -slug: optimizing-recursive-functions -title: "Optimizing Recursive Functions: Techniques and Tips" -authors: [AKSHITHA-CHILUKA] -tags: [AKSHITHA-CHILUKA, algo, dsa, algorithms, recursion, optimization] ---- - -While recursion is a useful programming technique, it can lead to inefficiencies if not implemented correctly. Understanding how to optimize recursive functions is essential for better performance. - - - -In this blog, we’ll cover: - -- **Memoization**: Caching results to avoid redundant calculations. -- **Tail Recursion**: A special case of recursion that can be optimized by the compiler. - ---- - -## Memoization - -Memoization is an optimization technique where you store the results of expensive function calls and return the cached result when the same inputs occur again. - -### Example: Fibonacci with Memoization - -```javascript -const memo = {}; -function fibonacci(n) { - if (n in memo) return memo[n]; - if (n <= 1) return n; - memo[n] = fibonacci(n - 1) + fibonacci(n - 2); - return memo[n]; -} -``` -### Tail Recursion -Tail recursion is when a function calls itself as its last action. Some programming languages can optimize tail recursive calls to avoid adding a new stack frame. - -#### Example: Tail Recursive Factorial -```javascript -function factorial(n, accumulator = 1) { - if (n <= 1) return accumulator; - return factorial(n - 1, n * accumulator); -} -``` -## Conclusion -By applying techniques like memoization and tail recursion, you can optimize your recursive algorithms for better performance, making your code faster and more efficient. diff --git a/blog/practical-applications-of-recursion.md b/blog/practical-applications-of-recursion.md deleted file mode 100644 index df986f2e4..000000000 --- a/blog/practical-applications-of-recursion.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -slug: practical-applications-of-recursion -title: Practical Applications of Recursion in Algorithms -authors: [AKSHITHA-CHILUKA] -tags: [AKSHITHA-CHILUKA , algo, dsa, algorithms, recursion] ---- - -Recursion is more than just a theoretical concept; it has numerous practical applications across various algorithms. Understanding these applications can greatly enhance your programming skills. - - - -In this blog, we’ll discuss: - -- **Sorting Algorithms**: How recursion is used in sorting. -- **Searching Algorithms**: The role of recursion in searching. - ---- - -## Sorting Algorithms - -### Quick Sort - -Quick Sort is a recursive sorting algorithm that works by selecting a 'pivot' element and partitioning the other elements into two sub-arrays, according to whether they are less than or greater than the pivot. - -#### Example: Quick Sort - -```javascript -function quickSort(arr) { - if (arr.length <= 1) return arr; - const pivot = arr[arr.length - 1]; - const left = arr.slice(0, -1).filter(x => x < pivot); - const right = arr.slice(0, -1).filter(x => x >= pivot); - return [...quickSort(left), pivot, ...quickSort(right)]; -} -``` -# Searching Algorithms -## Binary Search -Binary Search is a classic example of recursion in searching algorithms. It divides the search interval in half repeatedly until the target value is found. - -#### Example: Binary Search -```javacsript -function binarySearch(arr, target) { - function search(low, high) { - if (low > high) return -1; - const mid = Math.floor((low + high) / 2); - if (arr[mid] === target) return mid; - return arr[mid] > target ? search(low, mid - 1) : search(mid + 1, high); - } - return search(0, arr.length - 1); -} -``` -## Conclusion -Recursion is a powerful tool that finds applications in various sorting and searching algorithms. Mastering these practical uses can elevate your algorithmic skills. diff --git a/blog/understanding-big-o-notation.md b/blog/understanding-big-o-notation.md deleted file mode 100644 index 2f4ad7330..000000000 --- a/blog/understanding-big-o-notation.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -slug: understanding-big-o-notation -title: Understanding Big O Notation in Algorithm Analysis -authors: [AKSHITHA-CHILUKA] -tags: [AKSHITHA-CHILUKA , algo, dsa, algorithms, big-o, time-complexity] ---- - -When analyzing algorithms, **Big O Notation** is a critical concept that helps us understand the performance and efficiency of an algorithm in terms of time and space complexity. - - - -In this blog, we’ll delve into: - -- **What is Big O Notation?**: An overview of the concept. -- **Common Time Complexities**: Exploring the most frequent complexities. - ---- - -## What is Big O Notation? - -Big O Notation describes the upper limit of an algorithm's growth rate, allowing us to express how the runtime or space requirements grow as the size of the input increases. - -### Common Time Complexities: - -1. **$O(1)$ - Constant Time** -2. **$O(n)$ - Linear Time** -3. **$O(log n)$ - Logarithmic Time** -4. **$O(n^2)$ - Quadratic Time** - ---- - -## Example of Time Complexity Analysis - -Consider a simple loop that calculates the sum of an array: - -```javascript -function sumArray(arr) { - let sum = 0; - for (let num of arr) { - sum += num; - } - return sum; -} -``` -The time complexity of this function is $O(n)$, where n is the length of the array. - -## Space Complexity -In addition to time complexity, it's essential to consider space complexity, which measures the amount of memory an algorithm uses relative to its input size. - -## Conclusion -Understanding Big O Notation is fundamental for analyzing algorithms and making informed decisions when selecting or designing them. By mastering this concept, you will improve your ability to evaluate algorithm performance effectively. diff --git a/blog/understanding-time-space-complexity.md b/blog/understanding-time-space-complexity.md deleted file mode 100644 index 723b58e0f..000000000 --- a/blog/understanding-time-space-complexity.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -slug: understanding-time-space-complexity -title: Understanding Time and Space Complexity in Algorithms -authors: [ajay-dhangar] -tags: [ajay-dhangar, algo, dsa, algorithms, time-complexity, space-complexity] ---- - -When building efficient algorithms, one of the most crucial concepts to grasp is **Time and Space Complexity**. This concept helps us measure the performance of an algorithm in terms of the time it takes to run and the memory it consumes. - - - -In this blog, we'll break down: - -- **Big O Notation**: The mathematical notation used to describe the performance of an algorithm. -- **Common time complexities** like $O(1)$, $O(n)$, and $O(log n)$. -- **Space complexity** and its impact on algorithm design. - ---- - -## What is Time Complexity? - -Time complexity is a way to describe how the runtime of an algorithm grows as the size of the input grows. It is denoted using **Big O Notation**, which describes the upper limit of an algorithm's execution time. - -### Common Time Complexities: - -1. **$O(1)$ - Constant Time:** - - The algorithm's runtime is constant regardless of the input size. - - Example: Accessing an element in an array by its index. - -2. **$O(n)$ - Linear Time:** - - The algorithm's runtime grows linearly with the input size. - - Example: Looping through an array of `n` elements. - -3. **$O(log n)$ - Logarithmic Time:** - - The algorithm reduces the problem size with each step, making it very efficient for large inputs. - - Example: Binary search on a sorted array. - -4. **$O(n^2)$ - Quadratic Time:** - - The runtime grows proportionally to the square of the input size. - - Example: Nested loops, such as comparing each pair of elements in a list. - -### Example of Time Complexity Analysis: - -Consider a simple loop that prints each element of an array of size `n`: - -```javascript title="index.js" -for (let i = 0; i < n; i++) { - console.log(arr[i]); -} -``` - -The time complexity of this operation is **$O(n)$** because the algorithm's runtime increases linearly with the size of the input array. - ---- - -## What is Space Complexity? - -Space complexity refers to the amount of memory an algorithm needs to execute relative to the input size. It includes both the space required for the input data and any additional variables or data structures the algorithm uses. - -### Example of Space Complexity: - -If an algorithm uses a constant amount of extra space, its space complexity is **$O(1)$**. On the other hand, if the algorithm requires a data structure proportional to the input size (like an extra array of size `n`), the space complexity is **$O(n)$**. - -### Space-Time Tradeoff: - -In many cases, improving time complexity might require using more memory, and vice versa. For example, **Memoization** techniques in dynamic programming optimize time at the cost of extra space. - ---- - -## Why Does This Matter? - -Understanding time and space complexity allows developers to make informed decisions about which algorithms to use based on the problem at hand. It's important to select algorithms that perform well, especially for large inputs. - ---- - -## Final Thoughts - -Analyzing the time and space complexity of algorithms is a fundamental skill for optimizing code. While Big O Notation helps in understanding the worst-case scenario, always aim to balance both time and space complexity when designing efficient algorithms. - -With this foundation, you're better equipped to analyze and select algorithms for your projects. \ No newline at end of file diff --git a/docs/Approximation Algorithm/Approximation.md b/docs/Approximation Algorithm/Approximation.md deleted file mode 100644 index 85cad1bb3..000000000 --- a/docs/Approximation Algorithm/Approximation.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -id: approximation-algorithm -title: "Introduction to Approximation Algorithms" -sidebar_label: "Approximation Algorithm" -sidebar_position: 1 -description: "Overview and applications of Approximation Algorithms in computational problems." -tags: [Algorithm, Approximation Algorithm, Optimization] ---- - -# Approximation Algorithms -## Overview -Approximation Algorithms are designed to find near-optimal solutions to optimization problems within a guaranteed factor of the optimal. These algorithms are particularly useful for NP-hard problems, where finding an exact solution is computationally expensive or infeasible. - -## Use Cases -- **Combinatorial Optimization**: Useful in problems like the Traveling Salesman, Knapsack, and Vertex Cover. -- **Resource Allocation**: Commonly applied in scenarios requiring efficient resource distribution, such as server load balancing. -- **Network Design**: Used in designing cost-effective networks with minimum latency or optimal bandwidth. - -## Algorithm Details -### Key Concepts -1. **Approximation Factor**: Measures how close the solution is to the optimal value, often expressed as a ratio. -2. **Heuristic Approach**: Many approximation algorithms utilize heuristics to reduce computation time. -3. **Classes of Approximation Algorithms**: - - **Greedy Algorithms**: Build a solution step-by-step, picking the locally optimal choice at each step. - - **Local Search Algorithms**: Start with an initial solution and iteratively improve it by local adjustments. - - **Relaxation-Based Algorithms**: Solve a relaxed version of the problem, then round the solution to an integer. - -### Performance Guarantees -- Approximation algorithms provide solutions within a factor, \( \alpha \), of the optimal solution. For example, a 2-approximation algorithm guarantees that the result will be at most twice the optimal solution. - -## Example Pseudocode: Vertex Cover (Greedy Approach) - -```cpp -// Given an undirected graph G(V, E), this is a 2-approximation algorithm for the Minimum Vertex Cover problem. - -function approximateVertexCover(graph): - cover = empty set - for each edge (u, v) in graph: - if u and v are not already in cover: - add u and v to cover - return cover -``` - -## 1. Example Code in C++: Vertex Cover Approximation -Here’s a C++ implementation of the 2-approximation algorithm for the Vertex Cover problem: - -```cpp -#include -#include -using namespace std; - -class Graph { - int V; // Number of vertices - vector> edges; // List of edges - -public: - // Constructor to initialize the graph with V vertices - Graph(int V) : V(V) {} - - // Function to add an edge to the graph - void addEdge(int u, int v) { - edges.push_back({u, v}); - } - - // Approximate solution for Vertex Cover - vector approximateVertexCover() { - vector visited(V, false); - vector cover; - - // Traverse through all edges - for (auto &edge : edges) { - int u = edge.first; - int v = edge.second; - - // If both vertices of the edge are unvisited, add both to cover - if (!visited[u] && !visited[v]) { - cover.push_back(u); - cover.push_back(v); - visited[u] = true; - visited[v] = true; - } - } - return cover; - } -}; - -int main() { - Graph g(4); - g.addEdge(0, 1); - g.addEdge(1, 2); - g.addEdge(2, 3); - g.addEdge(3, 0); - - vector cover = g.approximateVertexCover(); - cout << "Approximate Vertex Cover: "; - for (int v : cover) { - cout << v << " "; - } - cout << endl; - - return 0; -} -``` - -## 2. Knapsack Problem (Dynamic Programming-Based Approximation) -The Knapsack Problem requires maximizing the total value of items packed into a knapsack without exceeding a weight limit. Here is a C++ example of an approximation algorithm using dynamic programming to get a near-optimal solution. - -### Pseudocode -- Sort items by their value-to-weight ratio. -- Fill the knapsack as much as possible while staying within the weight limit. -- Choose a fractional part of the next item if needed to maximize the value without exceeding the capacity. -C++ Implementation (Fractional Knapsack Approximation) - -```cpp -#include -#include -#include -using namespace std; - -struct Item { - int weight, value; - Item(int w, int v) : weight(w), value(v) {} -}; - -bool compare(const Item &a, const Item &b) { - double r1 = (double)a.value / a.weight; - double r2 = (double)b.value / b.weight; - return r1 > r2; -} - -double fractionalKnapsack(int W, vector &items) { - sort(items.begin(), items.end(), compare); - double totalValue = 0.0; - - for (auto &item : items) { - if (W >= item.weight) { - W -= item.weight; - totalValue += item.value; - } else { - totalValue += item.value * ((double)W / item.weight); - break; - } - } - return totalValue; -} - -int main() { - vector items = { {10, 60}, {20, 100}, {30, 120} }; - int W = 50; - cout << "Maximum value in Knapsack = " << fractionalKnapsack(W, items) << endl; - - return 0; -} -``` -## Explanation of the Code -- Edge Selection: For each edge, if neither endpoint is in the cover, add both vertices to the cover. -- Greedy Selection: Ensures that the algorithm picks a minimal set of vertices to cover all edges, though it may not be the smallest possible set. - -## Example Walkthrough -Imagine a graph with four vertices and edges forming a cycle. The greedy approximation method would select two pairs of vertices to cover all edges. This solution is within a factor of 2 of the optimal. - -## Real-World Example -Approximation algorithms are widely used in fields like telecommunications for network design, logistics for routing optimization, and data science for clustering large datasets. Their ability to yield feasible solutions quickly makes them invaluable for real-time decision-making and large-scale data processing. - diff --git a/docs/Circular_array/Application.md b/docs/Circular_array/Application.md deleted file mode 100644 index 17b290937..000000000 --- a/docs/Circular_array/Application.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -id: circular-array-application -sidebar_position: 2 -title: Applications of Circular Arrays -sidebar_label: Applications of Circular Arrays -description: "Circular arrays are used in various real-world applications for efficient memory usage and continuous data management." -tags: [circular array, applications, data structure, DSA, programming] ---- - -## Common Applications in Real-World Scenarios -- **Network Packet Buffers**: Used in routers to handle packets with limited memory. -- **Operating System Buffers**: Useful for managing I/O data streams. -- **Real-Time Data Logging**: Used to store recent data while continuously overwriting the oldest data. - - -Here is a real-world example where a circular array can be practically applied: - -## Circular Buffer for Logging Events - -This documentation provides the implementations of a circular buffer in Java, C++, and Python. This data structure is commonly used in logging systems to maintain a fixed-size buffer of recent entries, where the oldest entries are overwritten when the buffer becomes full. - ---- - -### Java Code - -```java -import java.util.Arrays; - -public class CircularBuffer { - private String[] buffer; - private int front; - private int rear; - private int size; - private int capacity; - - public CircularBuffer(int capacity) { - this.capacity = capacity; - buffer = new String[capacity]; - front = -1; - rear = -1; - size = 0; - } - - public boolean isEmpty() { - return size == 0; - } - - public boolean isFull() { - return size == capacity; - } - - public void logEvent(String event) { - if (isFull()) { - front = (front + 1) % capacity; // Move front forward if buffer is full - } else { - size++; - } - rear = (rear + 1) % capacity; - buffer[rear] = event; - System.out.println("Logged event: " + event); - } - - public String[] getEvents() { - String[] events = new String[size]; - int index = front == -1 ? 0 : (front + 1) % capacity; - for (int i = 0; i < size; i++) { - events[i] = buffer[index]; - index = (index + 1) % capacity; - } - return events; - } - - public static void main(String[] args) { - CircularBuffer logger = new CircularBuffer(5); - logger.logEvent("Event 1"); - logger.logEvent("Event 2"); - logger.logEvent("Event 3"); - logger.logEvent("Event 4"); - logger.logEvent("Event 5"); - - // Adding more events to show circular behavior - logger.logEvent("Event 6"); // Overwrites oldest - logger.logEvent("Event 7"); - - System.out.println("Logged Events: " + Arrays.toString(logger.getEvents())); - } -} -``` -### C++ Implementation -```cpp -#include -#include -#include - -class CircularBuffer { -private: - std::vector buffer; - int front, rear, size, capacity; - -public: - CircularBuffer(int capacity) : capacity(capacity), front(-1), rear(-1), size(0) { - buffer.resize(capacity); - } - - bool isEmpty() const { - return size == 0; - } - - bool isFull() const { - return size == capacity; - } - - void logEvent(const std::string& event) { - if (isFull()) { - front = (front + 1) % capacity; // Move front forward if buffer is full - } else { - size++; - } - rear = (rear + 1) % capacity; - buffer[rear] = event; - std::cout << "Logged event: " << event << std::endl; - } - - void getEvents() const { - if (isEmpty()) { - std::cout << "No events logged." << std::endl; - return; - } - - int index = front == -1 ? 0 : (front + 1) % capacity; - std::cout << "Logged Events: "; - for (int i = 0; i < size; i++) { - std::cout << buffer[index] << " "; - index = (index + 1) % capacity; - } - std::cout << std::endl; - } -}; - -int main() { - CircularBuffer logger(5); - logger.logEvent("Event 1"); - logger.logEvent("Event 2"); - logger.logEvent("Event 3"); - logger.logEvent("Event 4"); - logger.logEvent("Event 5"); - - // Adding more events to show circular behavior - logger.logEvent("Event 6"); // Overwrites oldest - logger.logEvent("Event 7"); - - logger.getEvents(); - return 0; -} -``` -### Python Implementation - -```python -class CircularBuffer: - def __init__(self, capacity): - self.capacity = capacity - self.buffer = [None] * capacity - self.front = -1 - self.rear = -1 - self.size = 0 - - def is_empty(self): - return self.size == 0 - - def is_full(self): - return self.size == self.capacity - - def log_event(self, event): - if self.is_full(): - self.front = (self.front + 1) % self.capacity # Move front forward if buffer is full - else: - self.size += 1 - self.rear = (self.rear + 1) % self.capacity - self.buffer[self.rear] = event - print(f"Logged event: {event}") - - def get_events(self): - events = [] - index = 0 if self.front == -1 else (self.front + 1) % self.capacity - for _ in range(self.size): - events.append(self.buffer[index]) - index = (index + 1) % self.capacity - return events - - -# Example usage -logger = CircularBuffer(5) -logger.log_event("Event 1") -logger.log_event("Event 2") -logger.log_event("Event 3") -logger.log_event("Event 4") -logger.log_event("Event 5") - -# Adding more events to show circular behavior -logger.log_event("Event 6") # Overwrites oldest -logger.log_event("Event 7") - -print("Logged Events:", logger.get_events()) -``` -### Explanation -These implementations of a circular buffer manage a fixed-size collection where the oldest entries are overwritten when the buffer becomes full. In each version (Java, C++, and Python), the circular buffer uses an array to store entries, along with variables to track the `front`, `rear`, and `size`. When an event (or entry) is logged, the program checks if the buffer is full. If full, the `front` pointer advances to discard the oldest entry, while the `rear` pointer increments to store the new event in a "circular" manner, wrapping around to the start of the array when reaching the end. This approach maintains a constant buffer size, making it ideal for real-time applications like logging systems. Finally, a method retrieves all stored events in the correct order for review. -### Conclusion -Each implementation demonstrates how a circular buffer can manage a fixed-size buffer, retaining only the most recent entries by overwriting the oldest ones when the buffer is full. \ No newline at end of file diff --git a/docs/Circular_array/Introduction.md b/docs/Circular_array/Introduction.md deleted file mode 100644 index 71f81af4f..000000000 --- a/docs/Circular_array/Introduction.md +++ /dev/null @@ -1,267 +0,0 @@ ---- -id: circular-array-introduction -sidebar_position: 1 -title: Introduction of Circular -sidebar_label: Introduction -description: "A B-tree is a self-balancing tree data structure that maintains sorted data for efficient insertion, deletion, and search operations." -tags: [b-tree, algorithms, problem-solving, DSA, data structure] ---- - -## Introduction - -A **circular array** (or circular buffer) is a linear data structure that wraps around to the beginning once it reaches the end. -It is used in scenarios where we need a fixed-size buffer that can overwrite old data with new data, such as in queue operations -or buffering systems. - -## Key Features -- **Fixed Size:** The array has a fixed capacity. -- **Circular Nature:** When you reach the end, the next element is placed at the beginning of the array. -- **Efficient Usage:** Enables optimal memory usage by reusing space without reallocating the array. - -## Use Cases -- **Circular Queue Implementations:** Useful for implementing queue structures where the oldest data gets replaced by new entries - when capacity is full. -- **Buffering Systems:** Common in audio/video buffering or any system that needs constant data flow with limited memory. - -## Basic Operations -1. **Initialization:** Setting up the array with a fixed size and pointers for start (`front`) and end (`rear`). -2. **Insertion (Enqueue):** Adding an element at the rear and updating the position circularly. -3. **Deletion (Dequeue):** Removing an element from the front and updating the position circularly. -4. **Check Full/Empty Status:** Methods to check if the array is full or empty. - -## Implementation Example (Python) - -Here is an example in Python to demonstrate the circular array: - -```python -class CircularArray: - def __init__(self, size): - self.size = size - self.array = [None] * size - self.front = -1 - self.rear = -1 - - def is_empty(self): - return self.front == -1 - - def is_full(self): - return (self.rear + 1) % self.size == self.front - - def enqueue(self, value): - if self.is_full(): - print("The circular array is full. Cannot enqueue.") - return - if self.front == -1: - self.front = 0 - self.rear = (self.rear + 1) % self.size - self.array[self.rear] = value - print(f"Enqueued: {value}") - - def dequeue(self): - if self.is_empty(): - print("The circular array is empty. Cannot dequeue.") - return None - value = self.array[self.front] - if self.front == self.rear: - self.front = -1 - self.rear = -1 - else: - self.front = (self.front + 1) % self.size - print(f"Dequeued: {value}") - return value - - def display(self): - if self.is_empty(): - print("The circular array is empty.") - return - index = self.front - print("Circular Array Elements: ", end="") - while True: - print(self.array[index], end=" ") - if index == self.rear: - break - index = (index + 1) % self.size - print() -``` -## Java Implementation - -```java -public class CircularArray { - private int[] array; - private int front; - private int rear; - private int size; - - public CircularArray(int size) { - this.size = size; - array = new int[size]; - front = -1; - rear = -1; - } - - public boolean isEmpty() { - return front == -1; - } - - public boolean isFull() { - return (rear + 1) % size == front; - } - - public void enqueue(int value) { - if (isFull()) { - System.out.println("The circular array is full. Cannot enqueue."); - return; - } - if (front == -1) { - front = 0; - } - rear = (rear + 1) % size; - array[rear] = value; - System.out.println("Enqueued: " + value); - } - - public int dequeue() { - if (isEmpty()) { - System.out.println("The circular array is empty. Cannot dequeue."); - return -1; - } - int value = array[front]; - if (front == rear) { - front = -1; - rear = -1; - } else { - front = (front + 1) % size; - } - System.out.println("Dequeued: " + value); - return value; - } - - public void display() { - if (isEmpty()) { - System.out.println("The circular array is empty."); - return; - } - System.out.print("Circular Array Elements: "); - int index = front; - while (true) { - System.out.print(array[index] + " "); - if (index == rear) { - break; - } - index = (index + 1) % size; - } - System.out.println(); - } - - public static void main(String[] args) { - CircularArray ca = new CircularArray(5); - ca.enqueue(10); - ca.enqueue(20); - ca.enqueue(30); - ca.display(); - ca.dequeue(); - ca.display(); - } -} -``` -### C++ Implementation - -```C++ -#include -using namespace std; - -class CircularArray { -private: - int *array; - int front, rear, size; - -public: - CircularArray(int s) { - size = s; - array = new int[size]; - front = -1; - rear = -1; - } - - ~CircularArray() { - delete[] array; - } - - bool isEmpty() { - return front == -1; - } - - bool isFull() { - return (rear + 1) % size == front; - } - - void enqueue(int value) { - if (isFull()) { - cout << "The circular array is full. Cannot enqueue." << endl; - return; - } - if (front == -1) { - front = 0; - } - rear = (rear + 1) % size; - array[rear] = value; - cout << "Enqueued: " << value << endl; - } - - int dequeue() { - if (isEmpty()) { - cout << "The circular array is empty. Cannot dequeue." << endl; - return -1; - } - int value = array[front]; - if (front == rear) { - front = -1; - rear = -1; - } else { - front = (front + 1) % size; - } - cout << "Dequeued: " << value << endl; - return value; - } - - void display() { - if (isEmpty()) { - cout << "The circular array is empty." << endl; - return; - } - cout << "Circular Array Elements: "; - int index = front; - while (true) { - cout << array[index] << " "; - if (index == rear) { - break; - } - index = (index + 1) % size; - } - cout << endl; - } -}; - -int main() { - CircularArray ca(5); - ca.enqueue(10); - ca.enqueue(20); - ca.enqueue(30); - ca.display(); - ca.dequeue(); - ca.display(); - return 0; -} - -``` -## Complexity Analysis -- **Time Complexity**: - - **Enqueue/Dequeue**: $O(1)$ for insertion and deletion. -- **Space Complexity**: $O(n)$, where $n$ is the fixed size of the circular array. - -## Potential Issues and Solutions -- **Overflow**: Can occur if elements are added without checking if the array is full. - - Solution: Implement the `is_full()` method to prevent enqueueing when the array is at capacity. -- **Underflow**: Attempting to dequeue from an empty array. - - Solution: Implement the `is_empty()` method to handle this gracefully. - diff --git a/docs/DSA-Problem-Solution/Add_two_number_as_LL.md b/docs/DSA-Problem-Solution/Add_two_number_as_LL.md deleted file mode 100644 index 18f818445..000000000 --- a/docs/DSA-Problem-Solution/Add_two_number_as_LL.md +++ /dev/null @@ -1,241 +0,0 @@ ---- -id: add-two-numbers-as-linked-lists -title: "Add two numbers represented as linked lists" -sidebar_label: "Addition" -sidebar_position: 11 -description: "This document provides a detailed explanation and implementation for adding two numbers represented as linked lists, including step-by-step instructions and example code." -tags: [Linked list] ---- - -# Adding Two Numbers Represented as Linked Lists - -## Problem Statement - -Given two linked lists, where each node contains a single digit, add the two numbers represented by these linked lists and return the result as a new linked list. The digits are stored in reverse order, meaning the head of the list contains the least significant digit. - -## Steps to Solve the Problem - -1. **Initialization**: - - Create a new linked list to store the result. - - Use a pointer (or current node) to traverse the result list. - - Initialize a variable to keep track of carry from the addition. - -2. **Traverse Both Lists**: - - Use a loop to traverse both linked lists until both are fully processed. - - At each step, retrieve the current digits from both linked lists (if available) and add them along with any carry from the previous step. - -3. **Calculate Sum**: - - - The sum for each position is calculated as: - sum = digit1 + digit2 + carry - - - The new digit to add to the result is: - new digit = sum mod 10 - -- The carry for the next position is: - carry = sum // 10 - - -4. **Create New Nodes**: - - Create a new node with the calculated new digit and attach it to the result list. - - Move the current pointer of the result list to the new node. - -5. **Handle Remaining Carry**: - - After the loop, if there is a carry left, create a new node for it. - -6. **Return the Result**: - - Return the head of the result linked list. - -## Example - -**Input**: -``` - List1: `2 -> 4 -> 3` (represents the number 342) - List2: `5 -> 6 -> 4` (represents the number 465) -``` - -**Process**: -- Start with carry = 0. -- Add the digits: -``` - - (3 + 4 + 0 = 7) → New list: `7` - - (4 + 6 + 0 = 10) → New list: `7 -> 0` (carry = 1) - - (2 + 5 + 1 = 8) → New list: `7 -> 0 -> 8` - ``` - -**Output**: -``` -- Result: `7 -> 0 -> 8` (represents the number 807) -``` - -## Java Code Implementation - -```java -// Definition for singly-linked list. -class ListNode { - int val; // Value of the node - ListNode next; // Pointer to the next node - - ListNode(int val) { - this.val = val; - this.next = null; // Initialize next to null - } -} - -public class Solution { - public ListNode addTwoNumbers(ListNode l1, ListNode l2) { - ListNode dummyHead = new ListNode(0); // Dummy head for the result list - ListNode current = dummyHead; // Pointer for the current node in the result - int carry = 0; // Variable to store carry value - - // Loop until both lists are processed and no carry remains - while (l1 != null || l2 != null || carry != 0) { - int val1 = (l1 != null) ? l1.val : 0; // Get value from l1 or 0 - int val2 = (l2 != null) ? l2.val : 0; // Get value from l2 or 0 - - int sum = val1 + val2 + carry; // Calculate sum - carry = sum / 10; // Update carry for next iteration - current.next = new ListNode(sum % 10); // Create new node for the result - current = current.next; // Move to the next node in the result - - // Move to the next nodes in l1 and l2 - if (l1 != null) l1 = l1.next; - if (l2 != null) l2 = l2.next; - } - - return dummyHead.next; // Return the head of the resulting linked list - } - - // Example usage - public static void main(String[] args) { - // Create first linked list: 2 -> 4 -> 3 (represents 342) - ListNode l1 = new ListNode(2); - l1.next = new ListNode(4); - l1.next.next = new ListNode(3); - - // Create second linked list: 5 -> 6 -> 4 (represents 465) - ListNode l2 = new ListNode(5); - l2.next = new ListNode(6); - l2.next.next = new ListNode(4); - - // Create a solution object and add the two numbers - Solution solution = new Solution(); - ListNode result = solution.addTwoNumbers(l1, l2); - - // Output the result - System.out.print("Result: "); - while (result != null) { - System.out.print(result.val + " "); - result = result.next; - } - // Output: Result: 7 0 8 (represents 807) - } -} - -``` - -## C++ Code Implementation - -```cpp -#include - -// Definition for singly-linked list. -struct ListNode { - int val; // Value of the node - ListNode* next; // Pointer to the next node - ListNode(int x) : val(x), next(nullptr) {} // Constructor -}; - -class Solution { -public: - ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { - ListNode* dummyHead = new ListNode(0); // Dummy head for the result list - ListNode* current = dummyHead; // Pointer for the current node in the result - int carry = 0; // Variable to store carry value - - // Loop until both lists are processed and no carry remains - while (l1 != nullptr || l2 != nullptr || carry != 0) { - int val1 = (l1 != nullptr) ? l1->val : 0; // Get value from l1 or 0 - int val2 = (l2 != nullptr) ? l2->val : 0; // Get value from l2 or 0 - - int sum = val1 + val2 + carry; // Calculate sum - carry = sum / 10; // Update carry for next iteration - current->next = new ListNode(sum % 10); // Create new node for the result - current = current->next; // Move to the next node in the result - - // Move to the next nodes in l1 and l2 - if (l1 != nullptr) l1 = l1->next; - if (l2 != nullptr) l2 = l2->next; - } - - return dummyHead->next; // Return the head of the resulting linked list - } -}; - -// Example usage -int main() { - // Create first linked list: 2 -> 4 -> 3 (represents 342) - ListNode* l1 = new ListNode(2); - l1->next = new ListNode(4); - l1->next->next = new ListNode(3); - - // Create second linked list: 5 -> 6 -> 4 (represents 465) - ListNode* l2 = new ListNode(5); - l2->next = new ListNode(6); - l2->next->next = new ListNode(4); - - // Create a solution object and add the two numbers - Solution solution; - ListNode* result = solution.addTwoNumbers(l1, l2); - - // Output the result - std::cout << "Result: "; - while (result != nullptr) { - std::cout << result->val << " "; - result = result->next; - } - // Output: Result: 7 0 8 (represents 807) - - // Free memory (cleanup) - delete l1->next->next; - delete l1->next; - delete l1; - delete l2->next->next; - delete l2->next; - delete l2; - // Free the result list nodes here as needed - - return 0; -} - - -``` - - -## Python Code Implementation - -```python -class ListNode: - def __init__(self, val=0, next=None): - self.val = val - self.next = next - -def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode: - dummy_head = ListNode(0) - current = dummy_head - carry = 0 - - while l1 or l2 or carry: - val1 = (l1.val if l1 else 0) - val2 = (l2.val if l2 else 0) - - total = val1 + val2 + carry - carry = total // 10 - current.next = ListNode(total % 10) - - current = current.next - if l1: l1 = l1.next - if l2: l2 = l2.next - - return dummy_head.next -``` diff --git a/docs/DSA-Problem-Solution/Clone Linked List with Random and Next Pointer.md b/docs/DSA-Problem-Solution/Clone Linked List with Random and Next Pointer.md deleted file mode 100644 index aaa1c4545..000000000 --- a/docs/DSA-Problem-Solution/Clone Linked List with Random and Next Pointer.md +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: clone-linked-list-with-random-and-next-pointer -title: "Cloning a Linked List with Random and Next Pointers" -sidebar_label: "clone linked list" -sidebar_position: 16 -description: "Cloning a linked list that contains both next and random pointers involves creating a new linked list that is an exact copy of the original, preserving the structure and relationships of the nodes." -tags: [linked list,clone] ---- - -# Cloning a Linked List with Random and Next Pointers - -## Introduction - -Cloning a linked list that contains random pointers can be complex. Each node in the list has two pointers: -- **Next Pointer**: Points to the next node in the list. -- **Random Pointer**: Points to any node in the list or null. - -This guide will walk you through the steps to create a deep copy of such a linked list. - -Here are the detailed steps to clone a linked list with random and next pointers: - -### Step 1: Define the Node Structure -First, define the structure of the linked list node, which includes the value, next, and random pointers. - -### Step 2: Clone Nodes and Insert Them -Iterate Through the Original List: For each node, create a copy and insert it right after the original node. - -### Step 3: Set Random Pointers -Set Random Pointers: For each original node, set the random pointer of the cloned node to the cloned version of the node pointed to by the original node's random pointer. - -### Step 4: Separate the Lists -Restore the Original List and Extract the Cloned List: Iterate through the modified list to separate the original and cloned nodes. - -### Step 5: Combine Steps into a Single Function - -## Implementation - -## Java - -```java -class Node { - int value; - Node next; - Node random; - - public Node(int value) { - this.value = value; - this.next = null; - this.random = null; - } -} - -public class CloneLinkedList { - - // Step 1: Clone Nodes and Insert Them - public void cloneWithNextPointer(Node head) { - Node current = head; - while (current != null) { - Node cloneNode = new Node(current.value); - cloneNode.next = current.next; - current.next = cloneNode; - current = cloneNode.next; - } - } - - // Step 2: Set Random Pointers - public void setRandomPointers(Node head) { - Node current = head; - while (current != null) { - if (current.random != null) { - current.next.random = current.random.next; - } - current = current.next.next; - } - } - - // Step 3: Separate the Lists - public Node separateLists(Node head) { - if (head == null) return null; - - Node original = head; - Node cloneHead = head.next; - Node cloneCurrent = cloneHead; - - while (original != null && cloneCurrent != null) { - original.next = cloneCurrent.next; - original = original.next; - cloneCurrent.next = (original != null) ? original.next : null; - cloneCurrent = cloneCurrent.next; - } - - return cloneHead; - } - - // Main function to clone the linked list - public Node cloneLinkedList(Node head) { - if (head == null) return null; - - cloneWithNextPointer(head); - setRandomPointers(head); - return separateLists(head); - } - - // Function to print the linked list for verification - public void printList(Node head) { - Node current = head; - while (current != null) { - int randomValue = (current.random != null) ? current.random.value : -1; - System.out.println("Node value: " + current.value + ", Random points to: " + randomValue); - current = current.next; - } - } - - // Example usage - public static void main(String[] args) { - Node node1 = new Node(1); - Node node2 = new Node(2); - Node node3 = new Node(3); - - node1.next = node2; - node2.next = node3; - node1.random = node3; // node1's random points to node3 - node2.random = node1; // node2's random points to node1 - node3.random = node2; // node3's random points to node2 - - CloneLinkedList cloner = new CloneLinkedList(); - Node clonedHead = cloner.cloneLinkedList(node1); - - System.out.println("Original List:"); - cloner.printList(node1); - System.out.println("\nCloned List:"); - cloner.printList(clonedHead); - } -} - - -``` - -## C++ - -```cpp -#include - -class Node { -public: - int value; - Node* next; - Node* random; - - Node(int val) : value(val), next(nullptr), random(nullptr) {} -}; - -class CloneLinkedList { -public: - // Step 1: Clone Nodes and Insert Them - void cloneWithNextPointer(Node* head) { - Node* current = head; - while (current != nullptr) { - Node* cloneNode = new Node(current->value); - cloneNode->next = current->next; - current->next = cloneNode; - current = cloneNode->next; - } - } - - // Step 2: Set Random Pointers - void setRandomPointers(Node* head) { - Node* current = head; - while (current != nullptr) { - if (current->random != nullptr) { - current->next->random = current->random->next; - } - current = current->next->next; - } - } - - // Step 3: Separate the Lists - Node* separateLists(Node* head) { - if (head == nullptr) return nullptr; - - Node* original = head; - Node* cloneHead = head->next; - Node* cloneCurrent = cloneHead; - - while (original != nullptr && cloneCurrent != nullptr) { - original->next = cloneCurrent->next; - original = original->next; - cloneCurrent->next = (original != nullptr) ? original->next : nullptr; - cloneCurrent = cloneCurrent->next; - } - - return cloneHead; - } - - // Main function to clone the linked list - Node* cloneLinkedList(Node* head) { - if (head == nullptr) return nullptr; - - cloneWithNextPointer(head); - setRandomPointers(head); - return separateLists(head); - } - - // Function to print the linked list for verification - void printList(Node* head) { - Node* current = head; - while (current != nullptr) { - int randomValue = (current->random != nullptr) ? current->random->value : -1; - std::cout << "Node value: " << current->value << ", Random points to: " << randomValue << std::endl; - current = current->next; - } - } -}; - -// Example usage -int main() { - Node* node1 = new Node(1); - Node* node2 = new Node(2); - Node* node3 = new Node(3); - - node1->next = node2; - node2->next = node3; - node1->random = node3; // node1's random points to node3 - node2->random = node1; // node2's random points to node1 - node3->random = node2; // node3's random points to node2 - - CloneLinkedList cloner; - Node* clonedHead = cloner.cloneLinkedList(node1); - - std::cout << "Original List:" << std::endl; - cloner.printList(node1); - std::cout << "\nCloned List:" << std::endl; - cloner.printList(clonedHead); - - // Clean up memory (optional) - // Note: In a real application, you'd want to properly delete the nodes - // to avoid memory leaks. - - return 0; -} - -``` -## Python - -```python -class Node: - def __init__(self, value): - self.value = value - self.next = None - self.random = None - -class CloneLinkedList: - # Step 1: Clone Nodes and Insert Them - def clone_with_next_pointer(self, head): - current = head - while current: - clone_node = Node(current.value) - clone_node.next = current.next - current.next = clone_node - current = clone_node.next - - # Step 2: Set Random Pointers - def set_random_pointers(self, head): - current = head - while current: - if current.random: - current.next.random = current.random.next - current = current.next.next - - # Step 3: Separate the Lists - def separate_lists(self, head): - if not head: - return None - - original = head - clone_head = head.next - clone_current = clone_head - - while original and clone_current: - original.next = clone_current.next - original = original.next - clone_current.next = original.next if original else None - clone_current = clone_current.next - - return clone_head - - # Main function to clone the linked list - def clone_linked_list(self, head): - if not head: - return None - - self.clone_with_next_pointer(head) - self.set_random_pointers(head) - return self.separate_lists(head) - - # Function to print the linked list for verification - def print_list(self, head): - current = head - while current: - random_val = current.random.value if current.random else None - print(f"Node value: {current.value}, Random points to: {random_val}") - current = current.next - -# Example usage -if __name__ == "__main__": - # Creating nodes - node1 = Node(1) - node2 = Node(2) - node3 = Node(3) - - # Establishing next and random pointers - node1.next = node2 - node2.next = node3 - node1.random = node3 # node1's random points to node3 - node2.random = node1 # node2's random points to node1 - node3.random = node2 # node3's random points to node2 - - cloner = CloneLinkedList() - cloned_head = cloner.clone_linked_list(node1) - - print("Original List:") - cloner.print_list(node1) - print("\nCloned List:") - cloner.print_list(cloned_head) - -``` - - diff --git a/docs/DSA-Problem-Solution/Contains_duplicate.md b/docs/DSA-Problem-Solution/Contains_duplicate.md deleted file mode 100644 index efbd79ee1..000000000 --- a/docs/DSA-Problem-Solution/Contains_duplicate.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: contains-duplicate-leetcode-217 -title: Contains Duplicate -sidebar_label: Leetcode 217 -tags: [Leetcode, Array, DSA, Contains duplicate] -description: Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct. ---- - -## 217. Contains Duplicate -**Description**: -You are given an array of integers, `nums`, which may contain both positive and negative numbers. Your task is to determine whether any value appears more than once in the array. If at least one duplicate exists, return `true`. Otherwise, return `false`. - -## Example 1: - -**Input:** -`nums = [1, 2, 3, 1]` - -**Output:** -`true` (because 1 appears twice) - -**Explanation:** -- The frequency of 1 is 2 -- The frequency of 2 is 1 -- The frequency of 3 is 1 -- Since 1 appears twice, there is a duplicate, so the output is `true`. - -## Example 2: - -**Input:** -`nums = [1, 2, 3, 4]` - -**Output:** -`false` (because all elements are distinct) - -**Explanation:** -- All elements are unique and appear only once. - -## C++ Code: -```cpp -#include -#include -#include - -using namespace std; - -bool containsDuplicate(const vector& nums) { - unordered_set uniques; - - for (int num : nums) { - // If the number is already in the set, it means it's a duplicate - if (uniques.find(num) != uniques.end()) { - return true; - } - // Add the number to the set - uniques.insert(num); - } - return false; -} - -int main() { - vector nums = {1, 2, 3, 1}; // Example input - if (containsDuplicate(nums)) { - cout << "Array contains duplicates." << endl; - } else { - cout << "Array does not contain duplicates." << endl; - } - - return 0; -} - -``` -## Approach and code explanation -**Using a Set for Uniqueness:** -- A set data structure inherently stores unique values. In C++, we used an unordered_set for this purpose, which allows us to: -Insert elements in O(1) average time. -Check if an element exists (lookup) in O(1) average time. - -**Iterating Through the Array:** -- The algorithm iterates through each element of the array. -For each element: -It checks if the element already exists in the set (using the find() method). If it does, this means the element is a duplicate, so we return true. -If the element is not found in the set, it is added to the set to track that we’ve seen it before. - -**Returning the Result:** -- If the loop completes without finding any duplicates, the function returns false, meaning all elements in the array are distinct. -Code Flow: -Initialization: We declare an `unordered_set` uniques to store the unique numbers encountered during the iteration. - -**Loop through the array:** -- For each number in the array: -Check for duplication: If the number is already in the set, return true (duplicate found). -Insert into the set: If not found, add the number to the set. -Final Result: If the loop completes without finding any duplicates, return false. - -## complexcity -## Time Complexity: -Time complexity- O(n), where n is the size of the input array. - -## Space complexity: --O(n), as we are using an unordered_set to store up to n unique elements. \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/Convert Date to Binary.md b/docs/DSA-Problem-Solution/Convert Date to Binary.md deleted file mode 100644 index 0e597ec29..000000000 --- a/docs/DSA-Problem-Solution/Convert Date to Binary.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -id: date-to-binary-conversion -title: DSA Problem Solution -sidebar_label: DSA Problem Solution -sidebar-position: 1 -description: The "Date to Binary Conversion" problem on LeetCode typically involves converting a given date into its binary representation. -tags: [DSA, leetcode, problem-solving] ---- - -# Leetcode: Problem-3280 - -## Description: - -You are given a string ``date`` representing a Gregorian calendar date in the ``yyyy-mm-dd`` format. -``date`` can be written in its binary representation obtained by converting year, month, and day to their binary representations without any leading zeroes and writing them down in ``year-month-day`` format. -Return the binary representation of ``date``. - -**Example 1:** -Input: date = "2080-02-29" -Output: "100000100000-10-11101" - -**Explanation:** -100000100000, 10, and 11101 are the binary representations of 2080, 02, and 29 respectively. - -**Example 2:** -Input: date = "1900-01-01" -Output: "11101101100-1-1" - -**Explanation:** -11101101100, 1, and 1 are the binary representations of 1900, 1, and 1 respectively. - -## Steps: -**1. Date Input:** Given a date in the format YYYY-MM-DD. - -**2. Binary Conversion:** - - • Convert the year (YYYY) to binary. - • Convert the month (MM) to binary. - • Convert the day (DD) to binary. - -**3. Output:** Provide the combined binary representation. - -# Solution in Java - -```java -class Solution { - public String convertDateToBinary(String date) { - String[] parts = date.split("-"); - int year = Integer.parseInt(parts[0]); - int month = Integer.parseInt(parts[1]); - int day = Integer.parseInt(parts[2]); - - String yearBinary = Integer.toBinaryString(year); - String monthBinary = Integer.toBinaryString(month); - String dayBinary = Integer.toBinaryString(day); - return yearBinary + "-" + monthBinary + "-" + dayBinary; - } -} -``` diff --git a/docs/DSA-Problem-Solution/Cousins in Binary Tree.md b/docs/DSA-Problem-Solution/Cousins in Binary Tree.md deleted file mode 100644 index b3d98e00d..000000000 --- a/docs/DSA-Problem-Solution/Cousins in Binary Tree.md +++ /dev/null @@ -1,193 +0,0 @@ ---- -id: cousins-in-binary-tree -title: "Cousins in Binary Tree" -sidebar_label: "Cousins" -sidebar_position: 11 -description: "This document includes the solution to the problem of determining if two nodes in a binary tree are cousins, along with the approach and implementation." -tags: [binary tree, cousins] ---- - -# Cousins in Binary Tree - -## Problem Description - -Given the root of a binary tree with unique values and the values of two different nodes of the tree, `x` and `y`, return `true` if the nodes corresponding to the values `x` and `y` in the tree are cousins, or `false` otherwise. - -Two nodes of a binary tree are considered cousins if they have the same depth but different parents. - -Note that in a binary tree, the root node is at depth 0, and children of each depth `k` node are at depth `k + 1`. - -## Approach - -To determine if two nodes are cousins, we can use a **Breadth-First Search (BFS)** approach. We will traverse the tree level by level while keeping track of the parent of each node and their respective depths. - -### Steps: - -1. **Initialization**: Use a queue to facilitate the BFS traversal. Store each node along with its parent and depth. - -2. **BFS Traversal**: - - Dequeue each node from the front of the queue. - - If the current node has children, enqueue them along with their parent and the incremented depth. - - Check if both `x` and `y` are found at the same depth but with different parents. - -3. **Return Result**: - - If both nodes are found to be cousins during the traversal, return `true`. - - If the traversal ends without finding them, return `false`. - -## Java Implementation - -```java -import java.util.LinkedList; -import java.util.Queue; - -class TreeNode { - int val; - TreeNode left; - TreeNode right; - TreeNode(int x) { val = x; } -} - -class Solution { - public boolean isCousins(TreeNode root, int x, int y) { - if (root == null) return false; - - Queue queue = new LinkedList<>(); - queue.add(root); - - while (!queue.isEmpty()) { - int size = queue.size(); - boolean foundX = false, foundY = false; - - for (int i = 0; i < size; i++) { - TreeNode node = queue.poll(); - - // Check if both x and y are found at the same level - if (node.val == x) foundX = true; - if (node.val == y) foundY = true; - - // Check for siblings (same parent) - if (node.left != null && node.right != null) { - if ((node.left.val == x && node.right.val == y) || - (node.left.val == y && node.right.val == x)) { - return false; // x and y are siblings, not cousins - } - } - - // Add child nodes to the queue - if (node.left != null) queue.add(node.left); - if (node.right != null) queue.add(node.right); - } - - // If both x and y are found at the same level, they are cousins - if (foundX && foundY) return true; - } - - return false; // Not cousins if the loop completes - } -} -//C++ Implementation -#include -#include - -using namespace std; - -struct TreeNode { - int val; - TreeNode* left; - TreeNode* right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -class Solution { -public: - bool isCousins(TreeNode* root, int x, int y) { - if (!root) return false; - - queue q; - q.push(root); - - while (!q.empty()) { - int size = q.size(); - bool foundX = false, foundY = false; - - for (int i = 0; i < size; i++) { - TreeNode* node = q.front(); - q.pop(); - - // Check if both x and y are found at the same level - if (node->val == x) foundX = true; - if (node->val == y) foundY = true; - - // Check for siblings (same parent) - if (node->left && node->right) { - if ((node->left->val == x && node->right->val == y) || - (node->left->val == y && node->right->val == x)) { - return false; // x and y are siblings, not cousins - } - } - - // Add child nodes to the queue - if (node->left) q.push(node->left); - if (node->right) q.push(node->right); - } - - // If both x and y are found at the same level, they are cousins - if (foundX && foundY) return true; - } - - return false; // Not cousins if the loop completes - } -}; -//Python Implementation -from collections import deque - -class TreeNode: - def __init__(self, x): - self.val = x - self.left = None - self.right = None - -class Solution: - def isCousins(self, root: TreeNode, x: int, y: int) -> bool: - if not root: - return False - - queue = deque([root]) - - while queue: - size = len(queue) - foundX = foundY = False - - for _ in range(size): - node = queue.popleft() - - # Check if both x and y are found at the same level - if node.val == x: - foundX = True - if node.val == y: - foundY = True - - # Check for siblings (same parent) - if node.left and node.right: - if (node.left.val == x and node.right.val == y) or \ - (node.left.val == y and node.right.val == x): - return False # x and y are siblings, not cousins - - # Add child nodes to the queue - if node.left: - queue.append(node.left) - if node.right: - queue.append(node.right) - - # If both x and y are found at the same level, they are cousins - if foundX and foundY: - return True - - return False # Not cousins if the loop completes - ``` - - - - -### Time Complexity: O(n) -### Space Complexity: O(n) \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/Delete middle node.md b/docs/DSA-Problem-Solution/Delete middle node.md deleted file mode 100644 index d44c7f231..000000000 --- a/docs/DSA-Problem-Solution/Delete middle node.md +++ /dev/null @@ -1,300 +0,0 @@ ---- -id: delete-middle-node-of-a-linked-list -title: "Deleting middle node of linked list." -sidebar_label: "Deleting middle node of linked list." -sidebar_position: 9 -description: " This document explains the 'Deleting the middle element of a linked list' problem, including its description, approach, and implementation." -tags: [DSA,problem-solving,linked list] ---- - -# Delete the Middle Node of a Linked List - -## Problem Description - -Given a singly linked list, the task is to delete the middle node. If the list has an even number of nodes, delete the second middle node. For example, given the linked list `1 -> 2 -> 3 -> 4 -> 5`, after deletion, it should become `1 -> 2 -> 4 -> 5`. If the list is `1 -> 2 -> 3 -> 4`, it should become `1 -> 2 -> 4`. - -## Approach - -To delete the middle node of a linked list, we can use the following approach: - -1. **Find the Length of the List**: - - Traverse the list to count the total number of nodes. - -2. **Determine the Middle Index**: - - Calculate the middle index based on whether the length is even or odd. - -3. **Traverse to the Node Before the Middle**: - - Move through the list until reaching the node just before the middle node. - -4. **Delete the Middle Node**: - - Adjust the pointers to bypass the middle node, effectively removing it from the list. - -## Implementation - -## Java -```java -class Node { - int value; - Node next; - - Node(int val) { - this.value = val; - this.next = null; - } -} - -class LinkedList { - Node head; - - // Function to delete the middle node - public void deleteMiddle() { - if (head == null) return; // If the list is empty - - // Step 1: Find the length of the list - int length = 0; - Node current = head; - while (current != null) { - length++; - current = current.next; - } - - // Step 2: Determine the middle index - int middleIndex = length / 2; - - // Step 3: Traverse to the node before the middle - current = head; - for (int i = 0; i < middleIndex - 1; i++) { - current = current.next; - } - - // Step 4: Delete the middle node - if (current.next != null) { - current.next = current.next.next; // Bypass the middle node - } else { - // If the list has only one node - head = null; - } - } - - // Function to add a new node at the end of the list - public void append(int value) { - Node newNode = new Node(value); - if (head == null) { - head = newNode; - return; - } - - Node current = head; - while (current.next != null) { - current = current.next; - } - current.next = newNode; - } - - // Function to print the linked list - public void printList() { - Node current = head; - while (current != null) { - System.out.print(current.value + " -> "); - current = current.next; - } - System.out.println("null"); - } -} - -// Example usage -public class Main { - public static void main(String[] args) { - LinkedList ll = new LinkedList(); - ll.append(1); - ll.append(2); - ll.append(3); - ll.append(4); - ll.append(5); - - System.out.print("Original Linked List: "); - ll.printList(); - - ll.deleteMiddle(); - - System.out.print("Linked List After Deleting Middle Node: "); - ll.printList(); - } -} - - -``` - -## C++ - -```cpp - -#include - -class Node { -public: - int value; - Node* next; - - Node(int val) { - value = val; - next = nullptr; - } -}; - -class LinkedList { -public: - Node* head; - - LinkedList() { - head = nullptr; - } - - // Function to delete the middle node - void deleteMiddle() { - if (head == nullptr) return; // If the list is empty - - // Step 1: Find the length of the list - int length = 0; - Node* current = head; - while (current != nullptr) { - length++; - current = current->next; - } - - // Step 2: Determine the middle index - int middleIndex = length / 2; - - // Step 3: Traverse to the node before the middle - current = head; - for (int i = 0; i < middleIndex - 1; i++) { - current = current->next; - } - - // Step 4: Delete the middle node - if (current->next != nullptr) { - current->next = current->next->next; // Bypass the middle node - } else { - // If the list has only one node - head = nullptr; - } - } - - // Function to add a new node at the end of the list - void append(int value) { - Node* newNode = new Node(value); - if (head == nullptr) { - head = newNode; - return; - } - - Node* current = head; - while (current->next != nullptr) { - current = current->next; - } - current->next = newNode; - } - - // Function to print the linked list - void printList() { - Node* current = head; - while (current != nullptr) { - std::cout << current->value << " -> "; - current = current->next; - } - std::cout << "nullptr" << std::endl; - } -}; - -// Example usage -int main() { - LinkedList ll; - ll.append(1); - ll.append(2); - ll.append(3); - ll.append(4); - ll.append(5); - - std::cout << "Original Linked List: "; - ll.printList(); - - ll.deleteMiddle(); - - std::cout << "Linked List After Deleting Middle Node: "; - ll.printList(); - - return 0; -} - -``` - -## Python - -```python -class Node: - def __init__(self, value): - self.value = value - self.next = None - -class LinkedList: - def __init__(self): - self.head = None - - def delete_middle(self): - if not self.head: - return - - # Step 1: Find the length of the list - length = 0 - current = self.head - while current: - length += 1 - current = current.next - - # Step 2: Determine the middle index - middle_index = length // 2 - - # Step 3: Traverse to the node before the middle - current = self.head - for _ in range(middle_index - 1): - current = current.next - - # Step 4: Delete the middle node - if current.next: # If there is a middle node to delete - current.next = current.next.next - - def append(self, value): - new_node = Node(value) - if not self.head: - self.head = new_node - return - - current = self.head - while current.next: - current = current.next - current.next = new_node - - def print_list(self): - current = self.head - while current: - print(current.value, end=" -> ") - current = current.next - print("None") - -# Example usage -if __name__ == "__main__": - ll = LinkedList() - ll.append(1) - ll.append(2) - ll.append(3) - ll.append(4) - ll.append(5) - - print("Original Linked List: ") - ll.print_list() - - ll.delete_middle() - - print("Linked List After Deleting Middle Node: ") - ll.print_list() -``` \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/Delete_occurences_of_key.md b/docs/DSA-Problem-Solution/Delete_occurences_of_key.md deleted file mode 100644 index f841a035b..000000000 --- a/docs/DSA-Problem-Solution/Delete_occurences_of_key.md +++ /dev/null @@ -1,263 +0,0 @@ ---- -id: delete-all-occurences-of-key -title: "Deleting All Occurrences of a Key in a Doubly Linked List" -sidebar_label: "Deleting All Occurrences of a Key in a Doubly Linked List" -sidebar_position: 12 -description: "This document provides a detailed explanation and implementation for deleting all occurrences of a key in a doubly linked list , including step-by-step instructions and example code." -tags: [Linked list,Deletion] ---- - - -# Deleting All Occurrences of a Key in a Doubly Linked List (DLL) - -## Introduction - -A Doubly Linked List (DLL) is a data structure consisting of nodes, where each node contains three components: -- A data field -- A pointer to the next node -- A pointer to the previous node. - -This structure allows traversal in both directions and efficient insertion and deletion operations. - -## Problem Statement - -Given a DLL and a key, the task is to delete all nodes that contain the specified key. - -### Example - -*Input:* -``` -DLL: 10 <-> 20 <-> 30 <-> 20 <-> 40 Key: 20 -``` - -*Output:* -``` -DLL: 10 <-> 30 <-> 40 -``` - - -## Approach - -1. *Initialize Pointers*: Start with a pointer at the head of the list. -2. *Traverse the DLL*: Loop through the list and check each node's data against the key. -3. *Delete Nodes*: - - If a node's data matches the key: - - Adjust the pointers of the previous and next nodes. - - If the node is the head, update the head pointer. - - Move to the next node after deletion. -4. *Continue Traversal*: Keep traversing until the end of the list. - -## Implementation -## Java Code Implementation -```java -class Node { - int data; - Node next; - Node prev; - - Node(int data) { - this.data = data; - this.next = null; - this.prev = null; - } -} - -class DoublyLinkedList { - Node head; - - // Method to append a node at the end of the list - public void append(int data) { - Node newNode = new Node(data); - if (head == null) { - head = newNode; - return; - } - Node last = head; - while (last.next != null) { - last = last.next; - } - last.next = newNode; - newNode.prev = last; - } - - // Method to delete all occurrences of a key - public void deleteAllOccurrences(int key) { - Node current = head; - - while (current != null) { - if (current.data == key) { - // Node to be deleted - if (current.prev != null) { - current.prev.next = current.next; - } - if (current.next != null) { - current.next.prev = current.prev; - } - if (current == head) { // Move head if needed - head = current.next; - } - // Move to next node - Node temp = current; - current = current.next; - temp = null; // Free the deleted node - } else { - current = current.next; - } - } - } - - // Method to display the list - public void display() { - Node current = head; - while (current != null) { - System.out.print(current.data + " <-> "); - current = current.next; - } - System.out.println("null"); - } -} - -// Example Usage -public class Main { - public static void main(String[] args) { - DoublyLinkedList dll = new DoublyLinkedList(); - dll.append(10); - dll.append(20); - dll.append(30); - dll.append(20); - dll.append(40); - - System.out.println("Original DLL:"); - dll.display(); - - dll.deleteAllOccurrences(20); - - System.out.println("DLL after deleting 20:"); - dll.display(); - } -} -``` - - -## C++ Code Implementation - -```cpp -#include - -class Node { -public: - int data; - Node* next; - Node* prev; - - Node(int data) { - this->data = data; - this->next = nullptr; - this->prev = nullptr; - } -}; - -class DoublyLinkedList { -public: - Node* head; - - DoublyLinkedList() { - head = nullptr; - } - - // Method to append a node at the end of the list - void append(int data) { - Node* newNode = new Node(data); - if (head == nullptr) { - head = newNode; - return; - } - Node* last = head; - while (last->next != nullptr) { - last = last->next; - } - last->next = newNode; - newNode->prev = last; - } - - // Method to delete all occurrences of a key - void deleteAllOccurrences(int key) { - Node* current = head; - - while (current != nullptr) { - if (current->data == key) { - // Node to be deleted - if (current->prev != nullptr) { - current->prev->next = current->next; - } - if (current->next != nullptr) { - current->next->prev = current->prev; - } - if (current == head) { // Move hea -``` - - -## Python Code Implementation -```python -class Node: - def __init__(self, data): - self.data = data - self.next = None - self.prev = None - -class DoublyLinkedList: - def __init__(self): - self.head = None - - def append(self, data): - new_node = Node(data) - if not self.head: - self.head = new_node - return - last = self.head - while last.next: - last = last.next - last.next = new_node - new_node.prev = last - - def delete_all_occurrences(self, key): - current = self.head - while current: - if current.data == key: - # Node to be deleted - if current.prev: - current.prev.next = current.next - if current.next: - current.next.prev = current.prev - if current == self.head: # Move head if needed - self.head = current.next - # Move to next node - temp = current - current = current.next - del temp # Free the deleted node - else: - current = current.next - - def display(self): - current = self.head - while current: - print(current.data, end=' <-> ') - current = current.next - print('None') - -# Example Usage -dll = DoublyLinkedList() -dll.append(10) -dll.append(20) -dll.append(30) -dll.append(20) -dll.append(40) - -print("Original DLL:") -dll.display() - -dll.delete_all_occurrences(20) - -print("DLL after deleting 20:") -dll.display() -``` diff --git a/docs/DSA-Problem-Solution/Loop in linked list.md b/docs/DSA-Problem-Solution/Loop in linked list.md deleted file mode 100644 index 916541e52..000000000 --- a/docs/DSA-Problem-Solution/Loop in linked list.md +++ /dev/null @@ -1,265 +0,0 @@ ---- -id: loop-in-a-linked-list -title: "Finding loop in a linked list." -sidebar_label: "loop" -sidebar_position: 10 -description: "This document includes solution to problem finding loop in a linked list along with approach and implementation." -tags: [Linked list, loop] ---- - - - -# Finding a Loop in a Linked List - -## Problem Description - -In a linked list, a **loop** occurs when a node's next pointer points back to a previous node, creating a cycle. Detecting a loop is crucial, as it can lead to infinite traversals and memory issues. The goal is to determine whether a loop exists in the linked list and, if so, identify the node where the loop begins. - -## Approach - -One of the most efficient methods for detecting a loop in a linked list is **Floyd's Cycle-Finding Algorithm**, also known as the "Tortoise and Hare" algorithm. - -### Steps: - -1. **Initialization**: Use two pointers, `slow` and `fast`. The `slow` pointer moves one step at a time, while the `fast` pointer moves two steps at a time. - -2. **Traversal**: - - Start both pointers at the head of the linked list. - - Move `slow` by one node and `fast` by two nodes in each iteration. - - If `fast` reaches the end of the list (`null`), there is no loop. - - If `slow` equals `fast`, a loop exists. - -3. **Finding the Start of the Loop**: - - Once a loop is detected, to find the starting node of the loop: - - Move one pointer back to the head of the list and keep the other at the meeting point. - - Move both pointers one step at a time; the node where they meet is the start of the loop. - -## Implementation - -## Java -```java -class Node { - int value; - Node next; - - Node(int value) { - this.value = value; - this.next = null; - } -} - -class LinkedList { - Node head; - - // Detect loop using Floyd's Cycle-Finding Algorithm - public Node detectLoop() { - Node slow = head; - Node fast = head; - - // Phase 1: Detect loop - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - if (slow == fast) { // Loop detected - break; - } - } - - // No loop - if (fast == null || fast.next == null) { - return null; - } - - // Phase 2: Find the start of the loop - slow = head; - while (slow != fast) { - slow = slow.next; - fast = fast.next; - } - - return slow; // Start of the loop - } - - // Method to create a loop for testing - public void createLoop(int loopStartIndex) { - Node loopStartNode = head; - Node lastNode = head; - int index = 0; - - // Find the loop start node - while (index < loopStartIndex) { - loopStartNode = loopStartNode.next; - index++; - } - - // Find the last node - while (lastNode.next != null) { - lastNode = lastNode.next; - } - - // Create the loop - lastNode.next = loopStartNode; - } -} - -// Example usage -public class Main { - public static void main(String[] args) { - LinkedList ll = new LinkedList(); - ll.head = new Node(1); - ll.head.next = new Node(2); - ll.head.next.next = new Node(3); - ll.head.next.next.next = new Node(4); - ll.head.createLoop(1); // Creating a loop back to node with value 2 - - Node loopStart = ll.detectLoop(); - if (loopStart != null) { - System.out.println("Loop detected at node with value: " + loopStart.value); - } else { - System.out.println("No loop detected."); - } - } -} -``` - -## C++ -```cpp -#include - -class Node { -public: - int value; - Node* next; - - Node(int val) : value(val), next(nullptr) {} -}; - -class LinkedList { -public: - Node* head; - - LinkedList() : head(nullptr) {} - - // Detect loop using Floyd's Cycle-Finding Algorithm - Node* detectLoop() { - Node* slow = head; - Node* fast = head; - - // Phase 1: Detect loop - while (fast != nullptr && fast->next != nullptr) { - slow = slow->next; - fast = fast->next->next; - - if (slow == fast) { // Loop detected - break; - } - } - - // No loop - if (fast == nullptr || fast->next == nullptr) { - return nullptr; - } - - // Phase 2: Find the start of the loop - slow = head; - while (slow != fast) { - slow = slow->next; - fast = fast->next; - } - - return slow; // Start of the loop - } - - // Method to create a loop for testing - void createLoop(int loopStartIndex) { - Node* loopStartNode = head; - Node* lastNode = head; - int index = 0; - - // Find the loop start node - while (index < loopStartIndex) { - loopStartNode = loopStartNode->next; - index++; - } - - // Find the last node - while (lastNode->next != nullptr) { - lastNode = lastNode->next; - } - - // Create the loop - lastNode->next = loopStartNode; - } -}; - -// Example usage -int main() { - LinkedList ll; - ll.head = new Node(1); - ll.head->next = new Node(2); - ll.head->next->next = new Node(3); - ll.head->next->next->next = new Node(4); - ll.head->createLoop(1); // Creating a loop back to node with value 2 - - Node* loopStart = ll.detectLoop(); - if (loopStart != nullptr) { - std::cout << "Loop detected at node with value: " << loopStart->value << std::endl; - } else { - std::cout << "No loop detected." << std::endl; - } - - return 0; -} -``` - -## Python -```python -class Node: - def __init__(self, value): - self.value = value - self.next = None - -class LinkedList: - def __init__(self): - self.head = None - - def detect_loop(self): - slow = fast = self.head - - # Phase 1: Detect loop - while fast and fast.next: - slow = slow.next - fast = fast.next.next - if slow == fast: # Loop detected - break - else: - return None # No loop - - # Phase 2: Find the start of the loop - slow = self.head - while slow != fast: - slow = slow.next - fast = fast.next - - return slow # Start of the loop - -# Example usage -if __name__ == "__main__": - ll = LinkedList() - ll.head = Node(1) - ll.head.next = Node(2) - ll.head.next.next = Node(3) - ll.head.next.next.next = Node(4) - ll.head.next.next.next.next = ll.head.next # Creating a loop - - loop_start = ll.detect_loop() - if loop_start: - print(f"Loop detected at node with value: {loop_start.value}") - else: - print("No loop detected.") -``` - - - - - diff --git a/docs/DSA-Problem-Solution/Merge Two Sorted Arrays.md b/docs/DSA-Problem-Solution/Merge Two Sorted Arrays.md deleted file mode 100644 index 7e90d18bc..000000000 --- a/docs/DSA-Problem-Solution/Merge Two Sorted Arrays.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -id: Merge Two Sorted Arrays -title: "Merge Two Sorted Arrays." -sidebar_label: "DSA Problem Solution" -sidebar_position: 5 -description: "This problem is a common exercise in understanding array manipulation and is often used to illustrate the two-pointer technique" -tags: [DSA, algorithms,Problem-Solving] ---- - - -# Merge Two Sorted Arrays - -## Problem Description -Given two sorted arrays, the task is to merge them into a single sorted array. The input arrays may contain duplicates, and the final output should also be sorted. This problem is a common exercise in understanding array manipulation and is often used to illustrate the two-pointer technique. - -### Example -- **Input**: - - `arr1 = [1, 3, 5]` - - `arr2 = [2, 4, 6]` - -- **Output**: - - `[1, 2, 3, 4, 5, 6]` - -## Approach -To merge the two sorted arrays efficiently, we can use the following approach: - -1. **Initialize Two Pointers**: Start with two pointers, one for each array, both set to zero. -2. **Compare Elements**: Traverse both arrays and compare the current elements pointed to by the pointers. - - If the element in the first array is smaller, add it to the merged array and increment the pointer for the first array. - - If the element in the second array is smaller, add it to the merged array and increment the pointer for the second array. -3. **Handle Remaining Elements**: Once one of the arrays is completely traversed, append any remaining elements from the other array to the merged array. -4. **Return the Merged Array**: The final output will be a single sorted array containing all elements from both input arrays. - -### Time Complexity -The time complexity for this approach is \(O(n + m)\), where \(n\) and \(m\) are the lengths of the two input arrays. - -## Implementation - -### Python Implementation - -```python -def merge_sorted_arrays(arr1, arr2): - i, j = 0, 0 # Pointers for arr1 and arr2 - merged_array = [] - - # Traverse both arrays - while i < len(arr1) and j < len(arr2): - if arr1[i] < arr2[j]: - merged_array.append(arr1[i]) - i += 1 - else: - merged_array.append(arr2[j]) - j += 1 - - # Add any remaining elements from arr1 - while i < len(arr1): - merged_array.append(arr1[i]) - i += 1 - - # Add any remaining elements from arr2 - while j < len(arr2): - merged_array.append(arr2[j]) - j += 1 - - return merged_array - -# Example usage -arr1 = [1, 3, 5] -arr2 = [2, 4, 6] -merged_result = merge_sorted_arrays(arr1, arr2) -print(merged_result) # Output: [1, 2, 3, 4, 5, 6] -``` -### JavaScript Implementation - -```javaScript -function mergeSortedArrays(arr1, arr2) { - let i = 0; // Pointer for arr1 - let j = 0; // Pointer for arr2 - const mergedArray = []; - - // Traverse both arrays - while (i < arr1.length && j < arr2.length) { - if (arr1[i] < arr2[j]) { - mergedArray.push(arr1[i]); - i++; - } else { - mergedArray.push(arr2[j]); - j++; - } - } - - // Add remaining elements from arr1 - while (i < arr1.length) { - mergedArray.push(arr1[i]); - i++; - } - - // Add remaining elements from arr2 - while (j < arr2.length) { - mergedArray.push(arr2[j]); - j++; - } - - return mergedArray; -} - -// Example usage -const arr1 = [1, 3, 5]; -const arr2 = [2, 4, 6]; -const mergedResult = mergeSortedArrays(arr1, arr2); -console.log(mergedResult); // Output: [1, 2, 3, 4, 5, 6] -``` -### Java Implementation - -```java -import java.util.ArrayList; -import java.util.Arrays; - -public class MergeSortedArrays { - public static int[] mergeSortedArrays(int[] arr1, int[] arr2) { - int i = 0, j = 0; - ArrayList mergedList = new ArrayList<>(); - - // Traverse both arrays - while (i < arr1.length && j < arr2.length) { - if (arr1[i] < arr2[j]) { - mergedList.add(arr1[i]); - i++; - } else { - mergedList.add(arr2[j]); - j++; - } - } - - // Add remaining elements from arr1 - while (i < arr1.length) { - mergedList.add(arr1[i]); - i++; - } - - // Add remaining elements from arr2 - while (j < arr2.length) { - mergedList.add(arr2[j]); - j++; - } - - // Convert ArrayList to int[] - return mergedList.stream().mapToInt(Integer::intValue).toArray(); - } - - public static void main(String[] args) { - int[] arr1 = {1, 3, 5}; - int[] arr2 = {2, 4, 6}; - int[] mergedResult = mergeSortedArrays(arr1, arr2); - System.out.println(Arrays.toString(mergedResult)); // Output: [1, 2, 3, 4, 5, 6] - } -} -``` diff --git a/docs/DSA-Problem-Solution/Merge_K_Sorted_Arrays.md b/docs/DSA-Problem-Solution/Merge_K_Sorted_Arrays.md deleted file mode 100644 index 3a61245cf..000000000 --- a/docs/DSA-Problem-Solution/Merge_K_Sorted_Arrays.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: merge-k-sorted-arrays -title: Merge K Sorted Arrays -sidebar_label: GFG -tags: [GFG, Arrays, Sorting, Heap, DSA] -description: Given k sorted arrays with each of size k arranged in the form of a matrix of size k * k. The task is to merge them into one sorted array. ---- - -# Partition Equal Subset Sum Algorithm (GFG) - -## Description - -The **Merge K Sorted Arrays** problem is an intuitive problem based on Priority Queue where we have to merge k sorted arrays into one final sorted array. - -### Problem Definition - -Given: - -- A 2D array of integers `arr` of size $k\*k$. - -Objective: - -- Merge these arrays into 1 sorted array. Return the merged sorted array. - -### Algorithm Overview - -1. **Min Heap Approach**: - -- Creating a `MinHeap` and Insert the `first` element `of all the k arrays`. -- Remove the `top most` element of Minheap and `put` it in the output array. -- And insert the `next` element `from`the `array of removed` elements. -- To get the `result` the step must continue until there is no element left in the MinHeap. - -2. **Return** `result`, which is the final sorted array after merging k sorted arrays. - -### Time Complexity - -- **Time Complexity**: $O(K^2\* log(K))$, where insertion and deletion in a Min Heap requires log K time and for all $K^2$ elements it takes $(K^2 \* log(K))$ time -- **Space Complexity**: $O(K)$ for the result array. - -### C++ Implementation - -```cpp -#include -using namespace std; - -//User function Template for C++ - - -class Solution -{ - public: - - class triplet{ - public: - int val; - int arr; - int i_indx; - }; - - struct cmp{ - bool operator()(triplet a , triplet b){ - return (a.val > b.val); - } - }; - //Function to merge k sorted arrays. - vector mergeKArrays(vector> arr, int k) - { - //code here - priority_queue , cmp> pq_min; - - - for(int i = 0 ; i < k ; i++){ - pq_min.push({arr[i][0] , i , 0});// pushing the first element of each array - //Heap Node => { element , array-number , indx of element in that array} - } - - vector ans; - - while(ans.size() != k*k){ - - triplet f = pq_min.top(); - pq_min.pop(); - - ans.push_back(f.val); - - int arr_indx = f.arr , i = f.i_indx; - i = i+1; - - if(i < arr[arr_indx].size()){ - pq_min.push({arr[arr_indx][i] , arr_indx , i}); //Pushing the next of that array from which popped out elements belongs to - } - } - - return ans; - } -}; - - -``` diff --git a/docs/DSA-Problem-Solution/Palindrome-number.md b/docs/DSA-Problem-Solution/Palindrome-number.md deleted file mode 100644 index b1e096954..000000000 --- a/docs/DSA-Problem-Solution/Palindrome-number.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -id: isPalindrome-problem -title: DSA Problem Solution -sidebar_label: DSA Problem Solution -sidebar-position: 1 -description: A palindrome reads the same forwards and backwards, like "121" or "racecar." -tags: [DSA, leetcode, problem-solving] ---- - -## Leetcode: Problem-9 - -### Description: - -Given an integer x, return true if x is a palindrome, and false otherwise. - -- **Example 1**: -Input: x = 121 -Output: true -Explanation: 121 reads as 121 from left to right and from right to left. - -- **Example 2**: -Input: x = -121 -Output: false -Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome. - -- **Example 3**: -Input: x = 10 -Output: false -Explanation: Reads 01 from right to left. Therefore it is not a palindrome. - -## Solution in Java: - -```java -public class Solution { - public boolean isPalindrome(int x) { - if (x < 0) { - return false; // Negative numbers are not palindromes - } - int original = x; - int reversed = 0; - while (x != 0) { - int digit = x % 10; //this returns the last digit - reversed = reversed * 10 + digit; - x /= 10; //x=x/10 which removes the last digit - } - return original == reversed; - } - public static void main(String args[]) { - int x = 121; - - PalindromeChecker checker = new PalindromeChecker(); - boolean result = checker.isPalindrome(x); - - if (result) { - System.out.println(x + " is a palindrome."); - } else { - System.out.println(x + " is not a palindrome."); - } - } -} -``` -## Output: - -![Screenshot 2024-10-15 162332](https://github.com/user-attachments/assets/18ec353a-3920-4151-bfcb-1805f45b08d4) - -## Analyze Complexity: - -![Screenshot 2024-10-15 162602](https://github.com/user-attachments/assets/7dd17351-82b9-4863-b072-58dfcf6d806b) - diff --git a/docs/DSA-Problem-Solution/Segregate even and odd nodes in LinkedList.md b/docs/DSA-Problem-Solution/Segregate even and odd nodes in LinkedList.md deleted file mode 100644 index 4076806d7..000000000 --- a/docs/DSA-Problem-Solution/Segregate even and odd nodes in LinkedList.md +++ /dev/null @@ -1,262 +0,0 @@ ---- -id: segregate-even-odd-nodes -title: "Segregate even and odd nodes in a linked list" -sidebar_label: "Segregate" -sidebar_position: 8 -description: "In a linked list, the goal is to rearrange the nodes such that all even-valued nodes appear before all odd-valued nodes. " -tags: [linked list] ---- - - - -# Segregate Even and Odd Nodes in a Linked List - -## Problem Description - -In a linked list, the goal is to rearrange the nodes such that all even-valued nodes appear before all odd-valued nodes. The relative order of the even and odd nodes should remain the same as in the original list. For example, given the linked list `1 -> 2 -> 3 -> 4 -> 5`, the output should be `2 -> 4 -> 1 -> 3 -> 5`. - -## Approach - -To segregate even and odd nodes, we can use the following approach: - -1. **Initialize Pointers**: - - Use two pointers to keep track of the even and odd nodes separately: `evenHead` and `oddHead`. - - Create two additional pointers to build the segregated list: `evenTail` and `oddTail`. - -2. **Traverse the List**: - - Iterate through the linked list and for each node: - - If the node's value is even, append it to the even list. - - If the node's value is odd, append it to the odd list. - -3. **Combine the Lists**: - - After traversing the list, connect the end of the even list to the head of the odd list. - -4. **Handle Edge Cases**: - - If the even list is empty, return the head of the odd list. - - If the odd list is empty, return the head of the even list. - -## Implementation - -## Java - -```java -class Node { - int value; - Node next; - - Node(int val) { - this.value = val; - this.next = null; - } -} - -class LinkedList { - Node head; - - // Function to segregate even and odd nodes - public Node segregateEvenOdd() { - if (head == null) return null; - - Node evenHead = null, oddHead = null; - Node evenTail = null, oddTail = null; - - Node current = head; - - while (current != null) { - if (current.value % 2 == 0) { - // Append to even list - if (evenHead == null) { - evenHead = current; - evenTail = evenHead; - } else { - evenTail.next = current; - evenTail = evenTail.next; - } - } else { - // Append to odd list - if (oddHead == null) { - oddHead = current; - oddTail = oddHead; - } else { - oddTail.next = current; - oddTail = oddTail.next; - } - } - current = current.next; - } - - // Combine even and odd lists - if (evenTail != null) { - evenTail.next = oddHead; - } - - if (oddTail != null) { - oddTail.next = null; // End the odd list - } - - return evenHead != null ? evenHead : oddHead; // Return the head of the combined list - } - - // Function to add a new node at the end of the list - public void a - - - - - -``` -## C++ - -```cpp -#include - -class Node { -public: - int value; - Node* next; - - Node(int val) : value(val), next(nullptr) {} -}; - -class LinkedList { -public: - Node* head; - - LinkedList() : head(nullptr) {} - - // Function to segregate even and odd nodes - Node* segregateEvenOdd() { - if (!head) return nullptr; - - Node* evenHead = nullptr; - Node* oddHead = nullptr; - Node* evenTail = nullptr; - Node* oddTail = nullptr; - - Node* current = head; - - while (current) { - if (current->value % 2 == 0) { - // Append to even list - if (!evenHead) { - evenHead = current; - evenTail = evenHead; - } else { - evenTail->next = current; - evenTail = evenTail->next; - } - } else { - // Append to odd list - if (!oddHead) { - oddHead = current; - oddTail = oddHead; - } else { - oddTail->next = current; - oddTail = oddTail->next; - } - } - current = current->next; - } - - // Combine even and odd lists - if (evenTail) { - evenTail->next = oddHead; - } - - if (oddTail) { - oddTail->next = nullptr; // End the odd list - } - - return evenHead ? evenHead : oddHead; // Return the head of the combined list - } - - // Function to add a new node at the end of the list - void append(int value) { - Node* newNode = new Node(value); - if (!head) { - head = newNode; - return; - } - - Node* current = head; - while (current->next) { - current = current->next; - } - current->next = newNode; - } - - // Function to print the linked list - void printList() { - Node* current = head; - while (current) { - std::cout << current->value << " -> "; - current = current->next; - } - std::cout << "nullptr" << std::endl; - } -}; - -// Example usage -int main() { - LinkedList ll; - ll.append(1); - ll.append(2); - ll.append(3); - ll.append(4); - ll.append(5); - - std::cout << "Original list: "; - ll.printList(); - - ll.head = ll.segregateEvenOdd(); - - std::cout << "Segregated list: "; - ll.printList(); - - return 0; -} - -``` - -## Python - -```python -class Node: - def __init__(self, value): - self.value = value - self.next = None - -class LinkedList: - def __init__(self): - self.head = None - - def segregate_even_odd(self): - if self.head is None: - return None - - even_head = even_tail = None - odd_head = odd_tail = None - - current = self.head - - while current: - if current.value % 2 == 0: - # Append to even list - if even_head is None: - even_head = even_tail = current - else: - even_tail.next = current - even_tail = even_tail.next - else: - # Append to odd list - if odd_head is None: - odd_head = odd_tail = current - else: - odd_tail.next = current - odd_tail = odd_tail.next - current = current.next - - # Combine even and odd lists - if even_tail: - eve -``` diff --git a/docs/DSA-Problem-Solution/Size_of_largest_BST_in_binary_tree.md b/docs/DSA-Problem-Solution/Size_of_largest_BST_in_binary_tree.md deleted file mode 100644 index d219ae4de..000000000 --- a/docs/DSA-Problem-Solution/Size_of_largest_BST_in_binary_tree.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: size-of-largest-bst-in-binary-tree -title: Size of Largest BST in Binary Tree -sidebar_label: GFG -tags: [GFG , Binary Tree , BST] -description: Determine whether the subtree rooted at each node is a Binary Search Tree (BST). Find the size of the largest BST. ---- - -# Size of Largest BST in Binary Tree (GFG) - -## Description - -The **Size of Largest BST in Binary Tree** problem is based on determining whether the subtree rooted at each node is a Binary Search Tree (BST). If any node follows the properties of a BST and has the maximum size, we update the size of the largest BST. - -### Problem Definition - -Given: - -- A binary tree - -Objective: - -- Find the size of largest BST in tree - -### Algorithm Overview - -1. **Recursion Approach**: - -- Create a structure to store the minimum value, maximum value, and size of the largest BST for any given subtree. -- Implement a recursive function that traverse through the binary tree. -- For each node, first, recursively gather information from its left and right children. -- For each node, check whether the current subtree is a BST by comparing the node’s value with the maximum of the left subtree and the minimum of the right subtree. -- If the conditions are satisfied, update the size of the largest BST found by combining the sizes of the valid left and right subtrees with the current node. -- As the recursive calls return, keep track of the largest BST size. - Finally, after traversing the entire tree, return the size of the largest BST found. - -2. **Return** `size`, which indicates the size of the largest BST found. - -### Time Complexity - -- **Time Complexity**: O(N) as we have to traverse throughout the tree consisting of N nodes. -- **Space Complexity**: O(N) for auxiliary stack space storing all the recursive calls. - -### C++ Implementation - -```cpp -#include -using namespace std; - -class Solution { -public: - class Node { - public: - int data; - Node *left; - Node *right; - - Node(int val) { - data = val; - left = nullptr; - right = nullptr; - } -}; - -// Information about the subtree: Minimum value, -// Maximum value, and Size of the largest BST -class BSTInfo { - public: - int min; - int max; - int mxSz; - - BSTInfo(int mn, int mx, int sz) { - min = mn; - max = mx; - mxSz = sz; - } -}; - -// Function to determine the largest BST in the binary tree -BSTInfo largestBSTBT(Node *root) { - if (!root) - return BSTInfo(INT_MAX, INT_MIN, 0); - - BSTInfo left = largestBSTBT(root->left); - BSTInfo right = largestBSTBT(root->right); - - // Check if the current subtree is a BST - if (left.max < root->data && right.min > root->data) { - return BSTInfo(min(left.min, root->data), - max(right.max, root->data), 1 + left.mxSz + right.mxSz); - } - - return BSTInfo(INT_MIN, INT_MAX, max(left.mxSz, right.mxSz)); -} - -// Function to return the size of the largest BST -int largestBST(Node *root) { - return largestBSTBT(root).mxSz; -} - -}; - -``` diff --git a/docs/DSA-Problem-Solution/Sliding Window Maximum.md b/docs/DSA-Problem-Solution/Sliding Window Maximum.md deleted file mode 100644 index e895194d8..000000000 --- a/docs/DSA-Problem-Solution/Sliding Window Maximum.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: sliding-window-maximum -title: Sliding Window Maximum -sidebar_label: LeetCode 239 -tags: [LeetCode , Arrays, Queue , Sliding Window , Heap (Priority Queue) , Monotonic Queue] -description: "Given array of integers nums , with sliding window of size k which is moving from the very left of the array to the very right.Return the max for each sliding window." ---- - -# Sliding Window Maximum (LeetCode 239) - -## Description - -The **Sliding Window Maximum** problem involves finding the maximum value in each subarray of fixed size k that slides across array from left to right. - -### Problem Definition - -Given: - -- An array of integers `nums` of size N , with a sliding window of size K , moving from left to right , every time sliding window shifts to right by 1 position. - -Objective: - -- Return the max for each sliding window of size K. - -### Algorithm Overview - -1. **Using Deque*: - -- Create a `Deque`, `dq` of `capacity k`, that stores only useful elements of current window of k elements. -- An element is `useful` if it is in current window and is `greater` than all other `elements on right side` of it in current window. -- Process all array elements one by one and maintain dq to contain useful elements of current window and these useful elements are maintained in sorted order. -- The element at `front` of the dq is the `largest` and `element at rear/back` of dq `is` the `smallest of current window`. - -2. **Return** `result`, which is the final array containing max of each sliding window of size k. - -### Time Complexity - -- **Time Complexity**: O(N) time -- **Space Complexity**: O(K) for the deque. - -### C++ Implementation - -```cpp -#include -using namespace std; - -//User function Template for C++ - -class Solution { -public: - vector maxSlidingWindow(vector& a, int k) { - - - vector ans; int n = a.size(); - deque dq; - - int i = 0; - for(int j = 0 ; j < n ; j++){ - - while(!dq.empty() && dq.back() < a[j]){ - //pop all the elements from the back if smaller than the current element since max of that window is the current element since greater than all of them. - dq.pop_back(); - } - - dq.push_back(a[j]); // push the current element - - if(j-i+1 == k){ - ans.push_back(dq.front()); // max of that window is the deque front - - if(dq.front() == a[i]){ - // if after shifting the window by 1 step the deque front is window's front element that need to be popped b/c now window is changed ,and so window max also. - dq.pop_front(); - } - - i++; - } - - } - - return ans; - - } -}; - -``` - diff --git a/docs/DSA-Problem-Solution/Symmetric Tree.md b/docs/DSA-Problem-Solution/Symmetric Tree.md deleted file mode 100644 index 8a8942367..000000000 --- a/docs/DSA-Problem-Solution/Symmetric Tree.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -id: symmetric-tree -title: "Symmetric Tree" -sidebar_label: "Symmetric" -sidebar_position: 12 -description: "This document includes the solution to the problem of checking whether a binary tree is symmetric around its center, along with the approach and implementation." -tags: [binary tree, symmetric] ---- - -# Symmetric Tree - -## Problem Description - -Given the root of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center). - -A binary tree is symmetric if the left subtree is a mirror reflection of the right subtree. - -## Approach - -To determine if a binary tree is symmetric, we can use a **recursive approach**. We will compare the left and right subtrees of the tree. - -### Steps: - -1. **Checker Function**: Create a helper function that takes two nodes as arguments and checks if they are mirrors of each other. - - If both nodes are `null`, return `true`. - - If one node is `null` and the other is not, return `false`. - - If the values of both nodes are different, return `false`. - - Recursively check the left child of the first node against the right child of the second node, and the right child of the first node against the left child of the second node. - -2. **Main Function**: In the main function, call the checker function with the left and right children of the root. - -## Java Implementation - -```java -/** - * Definition for a binary tree node. - */ -class TreeNode { - int val; // Node value - TreeNode left; // Left child - TreeNode right; // Right child - - // Constructor to create a node with no children - TreeNode() {} - - // Constructor to create a node with a value - TreeNode(int val) { - this.val = val; - } - - // Constructor to create a node with a value and children - TreeNode(int val, TreeNode left, TreeNode right) { - this.val = val; - this.left = left; - this.right = right; - } -} - -class Solution { - // Main function to check if the tree is symmetric - public boolean isSymmetric(TreeNode root) { - return checker(root.left, root.right); // Check if left and right subtrees are mirrors - } - - // Helper function to check if two nodes are mirrors of each other - public static boolean checker(TreeNode p, TreeNode q) { - // Both nodes are null, so they are symmetric - if (p == null && q == null) { - return true; - } - // One node is null while the other is not, so they are not symmetric - if (p == null || q == null) { - return false; - } - // Values of the nodes must be the same for them to be mirrors - if (p.val != q.val) { - return false; - } - // Recursively check the left and right children for mirror symmetry - return checker(p.left, q.right) && checker(p.right, q.left); - } -} -//C++ Implementation -#include - -using namespace std; - -/** - * Definition for a binary tree node. - */ -struct TreeNode { - int val; // Node value - TreeNode* left; // Pointer to left child - TreeNode* right; // Pointer to right child - - // Constructor to create a node with a value - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -class Solution { -public: - // Main function to check if the tree is symmetric - bool isSymmetric(TreeNode* root) { - return checker(root->left, root->right); // Check if left and right subtrees are mirrors - } - - // Helper function to check if two nodes are mirrors of each other - bool checker(TreeNode* p, TreeNode* q) { - // Both nodes are null, so they are symmetric - if (!p && !q) { - return true; - } - // One node is null while the other is not, so they are not symmetric - if (!p || !q) { - return false; - } - // Values of the nodes must be the same for them to be mirrors - if (p->val != q->val) { - return false; - } - // Recursively check the left and right children for mirror symmetry - return checker(p->left, q->right) && checker(p->right, q->left); - } -}; -//Python Implementation -class TreeNode: - def __init__(self, x): - self.val = x # Node value - self.left = None # Left child - self.right = None # Right child - -class Solution: - # Main function to check if the tree is symmetric - def isSymmetric(self, root: TreeNode) -> bool: - return self.checker(root.left, root.right) # Check if left and right subtrees are mirrors - - # Helper function to check if two nodes are mirrors of each other - def checker(self, p: TreeNode, q: TreeNode) -> bool: - # Both nodes are null, so they are symmetric - if not p and not q: - return True - # One node is null while the other is not, so they are not symmetric - if not p or not q: - return False - # Values of the nodes must be the same for them to be mirrors - if p.val != q.val: - return False - # Recursively check the left and right children for mirror symmetry - return self.checker(p.left, q.right) and self.checker(p.right, q.left) -``` - -## Time Complexity -Time Complexity : O(n) - -The time complexity is O(n) since we traverse each node in the binary tree once. -## Space Complexity -Space Complexity: O(h) -The space complexity is O(h), where h is the height of the tree. This space is used by the recursive stack. In the worst case (unbalanced tree), it can go up to O(n). \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/flattening-a-linked-list.md b/docs/DSA-Problem-Solution/flattening-a-linked-list.md deleted file mode 100644 index 2d57724be..000000000 --- a/docs/DSA-Problem-Solution/flattening-a-linked-list.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -id: flattening-a-linked-list -title: "Flattening a linked list involves converting a multi-level linked list into a single-level linked list." -sidebar_label: "flattening a linked list" -sidebar_position: 15 -description: "Flattening a linked list involves converting a multi-level linked list into a single-level linked list." -tags: [linked list,flattening] ---- - -# Flattening a Linked List - -Flattening a linked list involves converting a multi-level linked list into a single-level linked list. In this context, a multi-level linked list is one where each node may point to another linked list (next and child pointers). Flattening means that all child lists are combined into a single list, maintaining the original order. - -## Structure of the Linked List - -A node in a multi-level linked list can be represented as follows: - -```plaintext -class Node { - int data; - Node next; // Pointer to the next node in the same level - Node child; // Pointer to the child linked list -} -``` - -Example -Consider the following multi-level linked list: - -```plaintext -1 -> 2 -> 3 - | - 4 -> 5 - | - 6 -``` -The goal is to flatten this structure into a single linked list: - -```plaintext -1 -> 2 -> 3 -> 4 -> 5 -> 6 -``` - -## Steps to Flatten the Linked List -1. ### Traversal: Start from the head of the list and traverse through each node. -2. ### Recursive Flattening: - - For each node, recursively flatten the child list if it exists. - - Connect the child list to the current node and then continue with the next node. -3. ### Connecting Nodes: Ensure that the next pointers are set correctly so that the flattened structure maintains the correct order. - -## Implementation -## Java -```java -class Node { - int data; - Node next; - Node child; - - Node(int data) { - this.data = data; - this.next = null; - this.child = null; - } -} - -public class LinkedListFlattener { - - public Node flatten(Node root) { - if (root == null) { - return null; - } - - Node dummy = new Node(0); - Node tail = dummy; - - flattenHelper(root, tail); - - return dummy.next; - } - - private void flattenHelper(Node node, Node tail) { - while (node != null) { - tail.next = node; - tail = tail.next; - - if (node.child != null) { - flattenHelper(node.child, tail); - } - - node = node.next; - } - } - - // Example Usage - public static void main(String[] args) { - // Create nodes and link them as per the multi-level structure - } -} - -``` - -## C++ -```cpp -class Node { -public: - int data; - Node* next; - Node* child; - - Node(int data) : data(data), next(nullptr), child(nullptr) {} -}; - -class LinkedListFlattener { -public: - Node* flatten(Node* root) { - if (!root) { - return nullptr; - } - - Node* dummy = new Node(0); // Dummy head for the new flattened list - Node* tail = dummy; - - flattenHelper(root, tail); - - return dummy->next; // Return the next of dummy head which is the flattened list - } - -private: - void flattenHelper(Node* node, Node*& tail) { - while (node) { - // Attach current node to the tail of the flattened list - tail->next = node; - tail = tail->next; - - // If there's a child, flatten it - if (node->child) { - flattenHelper(node->child, tail); - } - - // Move to the next node - node = node->next; - } - } -}; - -// Example Usage -int main() { - // Create nodes and link them as per the multi-level structure -} - -``` -## Python -```python -class Node: - def __init__(self, data): - self.data = data - self.next = None - self.child = None - -def flatten(root): - if not root: - return None - - # Pointer to traverse the linked list - current = root - # Dummy head for the new flattened list - dummy = Node(0) - tail = dummy - - # Function to recursively flatten the linked list - def flatten_helper(node): - nonlocal tail - while node: - # Attach current node to the tail of the flattened list - tail.next = node - tail = tail.next - - # If there's a child, flatten it - if node.child: - flatten_helper(node.child) - - # Move to the next node - node = node.next - - flatten_helper(current) - # Return the next of dummy head which is the flattened list - return dummy.next - -# Example Usage -# Create nodes and link them as per the multi-level structure -``` diff --git a/docs/DSA-Problem-Solution/house-robber.md b/docs/DSA-Problem-Solution/house-robber.md deleted file mode 100644 index 69e599346..000000000 --- a/docs/DSA-Problem-Solution/house-robber.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -id: house-robber-algorithm -title: House Robber Algorithm -sidebar_label: Leetcode 198 -tags: [Leetcode, Dynamic Programming, DSA, House Robber] -description: Solve the House Robber problem using dynamic programming to maximize the amount of money that can be robbed from houses without robbing two adjacent houses. ---- - -# House Robber Algorithm - -## Description - -The **House Robber** problem is a classic dynamic programming problem that focuses on maximizing the amount of money that can be robbed from houses lined up in a row, under the constraint that adjacent houses cannot be robbed. - -### Problem Definition - -Given: -- An array of integers `nums` where each element represents the amount of money in each house. - -Objective: -- Determine the maximum amount of money that can be robbed without robbing two adjacent houses. - -### Algorithm Overview - -1. **Dynamic Programming Approach**: - - Use a DP array where `dp[i]` represents the maximum amount of money that can be robbed from the first `i` houses. - - Initialize: - - `dp[0] = 0` (no houses to rob) - - `dp[1] = nums[0]` (only one house) - - For each house `i` from 2 to `n`: - - Update `dp[i] = max(dp[i-1], dp[i-2] + nums[i-1])` - - `dp[i-1]`: maximum amount without robbing the current house - - `dp[i-2] + nums[i-1]`: maximum amount including the current house - -2. **Return** `dp[n]`, the maximum amount that can be robbed. - -### Time Complexity - -- **Time Complexity**: O(n), where n is the number of houses. -- **Space Complexity**: O(n) for the DP array. - -### C++ Implementation - -```cpp -#include -using namespace std; - -int rob(vector& nums) { - int n = nums.size(); - if (n == 0) return 0; - if (n == 1) return nums[0]; - - vector dp(n + 1); - dp[0] = 0; - dp[1] = nums[0]; - - for (int i = 2; i <= n; i++) { - dp[i] = max(dp[i - 1], dp[i - 2] + nums[i - 1]); - } - - return dp[n]; -} -```` diff --git a/docs/DSA-Problem-Solution/longest_substring_without_repeated_characters.md b/docs/DSA-Problem-Solution/longest_substring_without_repeated_characters.md deleted file mode 100644 index 0aea176a5..000000000 --- a/docs/DSA-Problem-Solution/longest_substring_without_repeated_characters.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -id: longest-substring-without-repeated-characters-problem -sidebar_position: 4 -title: Longest Substring Without Repeating Characters -sidebar_label: Longest Substring Without Repeating Characters -description: "This document explains the 'Longest Substring Without Repeating Characters' problem, including its description, approach, and implementation." -tags: [dsa, algorithms, problem-solving] ---- - -# Longest Substring Without Repeating Characters - -## Problem Statement -Given a string, find the length of the longest substring without repeating characters. - -## Approach -We can use the `sliding window technique` along with a `hash map` to track the characters and their indices. - -### Steps: - -1. **Initialize**: - - Create a hash map to store the last seen index of each character. - - Initialize two pointers, `start` and `end`, to the beginning of the string. - - -2. **Iterate**: - - For each character, check if it has been seen and is in the current window. - - Update the `start` pointer if necessary. - - Update the `end`. - -3. **Return**: - - Return the maximum length found. - -## Python Implementation - -```python -class Solution: - def lengthOfLongestSubstring(self, s: str) -> int: - char_index = {} - max_length = 0 - start = 0 - - for i, char in enumerate(s): - if char in char_index and char_index[char] >= start: - start = char_index[char] + 1 - char_index[char] = i - max_length = max(max_length, i - start + 1) - - return max_length - -``` -Time Complexity: O(n)
-Space Complexity: O(min(n, m)) (where m is the size of the character set) - - \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/merge_intervals.md b/docs/DSA-Problem-Solution/merge_intervals.md deleted file mode 100644 index 6cefd883c..000000000 --- a/docs/DSA-Problem-Solution/merge_intervals.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: merge-intervals-problem -sidebar_position: 3 -title: Merge Intervals -sidebar_label: Merge Intervals -description: "This document explains the Merge Intervals problem, including its description, approach, and implementation." -tags: [dsa, algorithms, problem-solving] ---- - -# Merge Intervals - -## Problem Statement -Given a collection of `intervals`, merge all overlapping intervals. - -## Approach -To merge the intervals, we can first sort them based on the start time. Then, we can iterate through the sorted intervals and merge them as needed. - - -### Steps: - -1. **Initialize : Sort**: - - Sort the intervals by their start times. - - Initialize a list to hold the merged intervals. - -2. **Iterate**: - - For each interval, check if it overlaps with the last merged interval. - - If it does, merge them. If not, add the interval to the list. - -3. **Return**: - - Return the merged intervals. - -## Python Implementation - -```python -class Solution: - def merge(self, intervals: List[List[int]]) -> List[List[int]]: - if not intervals: - return [] - - intervals.sort(key=lambda x: x[0]) - merged = [intervals[0]] - - for i in range(1, len(intervals)): - current = intervals[i] - last_merged = merged[-1] - - if current[0] <= last_merged[1]: - last_merged[1] = max(last_merged[1], current[1]) - else: - merged.append(current) - - return merged - -``` -Time Complexity: O(n log n)
-Space Complexity: O(n) \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/odd-even-linked-list.md b/docs/DSA-Problem-Solution/odd-even-linked-list.md deleted file mode 100644 index fec20e55f..000000000 --- a/docs/DSA-Problem-Solution/odd-even-linked-list.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -id: odd-even-linked-list -sidebar_position: 4 -title: Odd Even Linked List -sidebar_label: Odd Even Linked List -description: "This document explains the Odd Even Linked List problem, including its description, approach, and implementation." -tags: [dsa, algorithms, problem-solving] ---- - -# Odd Even Linked List - -## Description - -Given a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices. Please note that the even indexed nodes should maintain their relative order. The same goes for the odd indexed nodes. - -### Note: -- The head of the odd indexed list should point to the head of the even indexed list after rearranging. - -## Approach - -To solve this problem, we can use two pointers to separate the odd and even indexed nodes while maintaining their relative order. The approach involves: -1. Initializing two pointers, `odd` and `even`, to point to the first node and the second node, respectively. -2. Using a pointer `even_head` to keep track of the head of the even indexed list. -3. Iterating through the list and rearranging the `next` pointers for odd and even nodes. -4. At the end of the iteration, connecting the last odd node to the head of the even indexed list. - -## Python Implementation - -```python -# Definition for singly-linked list. -class ListNode: - def __init__(self, val=0, next=None): - self.val = val - self.next = next - -class Solution: - def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]: - # If the list is empty or has only one node, return it as is - if not head or not head.next: - return head - - # Initialize pointers for the odd and even nodes - odd = head - even = head.next - evenHead = even # Store the head of the even list to connect later - - # Traverse the list and rearrange odd and even nodes - while even and even.next: - # Link the current odd node to the next odd node - odd.next = even.next - odd = odd.next # Move the odd pointer forward - - # Link the current even node to the next even node - even.next = odd.next - even = even.next # Move the even pointer forward - - # Connect the last odd node to the head of the even list - odd.next = evenHead - - return head -``` -Time Complexity: O(n)
-Space Complexity: O(1) \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/palindrome_linked_list.md b/docs/DSA-Problem-Solution/palindrome_linked_list.md deleted file mode 100644 index 1e4f33162..000000000 --- a/docs/DSA-Problem-Solution/palindrome_linked_list.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -id: palindrome-linked-list-problem -sidebar_position: 5 -title: Palindrome Linked List -sidebar_label: Palindrome Linked List -description: "This document explains the Palindrome Linked List problem, including its description, approach, and implementation." -tags: [dsa, algorithms, problem-solving] ---- - -# Palindrome Linked List - -## Problem Statement -Determine if a linked list is a palindrome. - -## Approach -To check if the linked list is a palindrome, we can use the fast and slow pointer technique to find the middle of the list, then reverse the second half and compare it with the first half. - -### Steps: - -1. **Find the Middle**: - - Use two pointers to find the midpoint of the list - -2. **Reverse the Second Half**: - - Reverse the second half of the list. - -3. **Compare**: - - Compare the first half and the reversed second half. - -4. **Return**: - - Return true if they are equal; otherwise, return false. - -## Python Implementation - -```python -class Solution: - def isPalindrome(self, head: Optional[ListNode]) -> bool: - if not head: - return True - - # Step 1: Find the middle - slow = fast = head - while fast and fast.next: - slow = slow.next - fast = fast.next.next - - # Step 2: Reverse the second half - prev = None - while slow: - next_node = slow.next - slow.next = prev - prev = slow - slow = next_node - - # Step 3: Compare the two halves - left, right = head, prev - while right: # Only need to compare the second half - if left.val != right.val: - return False - left = left.next - right = right.next - - return True -``` -Time Complexity: O(n)
-Space Complexity: O(1) \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/partition_equal_subset_sum.md b/docs/DSA-Problem-Solution/partition_equal_subset_sum.md deleted file mode 100644 index 91f2303dc..000000000 --- a/docs/DSA-Problem-Solution/partition_equal_subset_sum.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -id: partition-equal-subset-sum-algorithm -title: Partition Equal Subset Sum Algorithm -sidebar_label: Leetcode 416 -tags: [Leetcode, Dynamic Programming, DSA, Partition Equal Subset Sum] -description: Solve the Partition Equal Subset Sum problem using dynamic programming to check if a set can be partitioned into two subsets with equal sum. ---- - -# Partition Equal Subset Sum Algorithm (LeetCode #416) - -## Description - -The **Partition Equal Subset Sum** problem is a classic dynamic programming problem that determines if a given set can be partitioned into two subsets such that the sum of elements in both subsets is equal. - -### Problem Definition - -Given: -- An array of integers `nums`. - -Objective: -- Return true if it is possible to partition the array into two subsets with equal sum. - -### Algorithm Overview - -1. **Dynamic Programming Approach**: - - Calculate the total sum of the array. If it's odd, return false. - - Set `target = total_sum / 2`. We need to find a subset with this target sum. - - Use a DP array where `dp[j]` indicates whether a subset sum of `j` can be formed. - - Initialize `dp[0] = true` (sum of 0 can always be formed). - - For each number `num` in `nums`, update the DP array in reverse: - - For `j` from `target` down to `num`, update `dp[j] = dp[j] || dp[j - num]`. - -2. **Return** `dp[target]`, which indicates if the target sum can be formed. - -### Time Complexity - -- **Time Complexity**: O(n * target), where n is the number of elements in `nums`. -- **Space Complexity**: O(target) for the DP array. - -### C++ Implementation - -```cpp -#include -using namespace std; - -bool canPartition(vector& nums) { - int total_sum = 0; - for (int num : nums) total_sum += num; - if (total_sum % 2 != 0) return false; - - int target = total_sum / 2; - vector dp(target + 1, false); - dp[0] = true; - - for (int num : nums) { - for (int j = target; j >= num; j--) { - dp[j] = dp[j] || dp[j - num]; - } - } - - return dp[target]; -} -``` diff --git a/docs/DSA-Problem-Solution/removing-stars-from-string.md b/docs/DSA-Problem-Solution/removing-stars-from-string.md deleted file mode 100644 index 6d891ef74..000000000 --- a/docs/DSA-Problem-Solution/removing-stars-from-string.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -id: removing-stars-from-string -sidebar_position: 1 -title: Removing Stars From a String -sidebar_label: Removing Stars From a String -description: "This document explains the Removing Stars From a String problem, including its description, approach, and implementation." -tags: [dsa, algorithms, problem-solving] ---- - -# Removing Stars From a String - -## Description - -You are given a string `s`, which contains stars `*`. - -In one operation, you can: -- Choose a star in `s`. -- Remove the closest non-star character to its left, as well as remove the star itself. - -Return the string after all stars have been removed. - -### Note: -- The input will be generated such that the operation is always possible. -- It can be shown that the resulting string will always be unique. - -## Approach - -To solve this problem, we can use a **stack** to keep track of the non-star characters. We iterate through the string, and for each character: -1. If it is a non-star character, push it onto the stack. -2. If it is a star (`*`), pop the top element from the stack (i.e., remove the closest non-star character). - -Finally, the remaining elements in the stack represent the string after all stars and corresponding characters have been removed. - -## Python Implementation - -```python -class Solution: - def removeStars(self, s: str) -> str: - stack = [] - - for char in s: - if char == '*': - if stack: - stack.pop() # Remove the closest non-star character - else: - stack.append(char) - - return ''.join(stack) -``` -Time Complexity: O(n)
-Space Complexity: O(n) \ No newline at end of file diff --git a/docs/DSA-Problem-Solution/reverse-bits.md b/docs/DSA-Problem-Solution/reverse-bits.md deleted file mode 100644 index 145f51d8d..000000000 --- a/docs/DSA-Problem-Solution/reverse-bits.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -id: Reverse Bits -title: Reverse-Bits-Solution -sidebar_label: DSA Problem Solution -sidebar-position: 1 -description: The Reverse Bits problem asks you to reverse the bits of a given 32-bit unsigned integer. Essentially, you need to flip the binary representation of the number so that the least significant bit (LSB) becomes the most significant bit (MSB) and vice versa." -tags: [DSA, leetcode, problem-solving] ---- - -# Leetcode Problem-190 [Type -> easy]: - -## Description: -Reverse bits of a given 32 bits unsigned integer. - -- **Note:** -Note that in some languages, such as Java, there is no unsigned integer type. In this case, both input and output will be given as a signed integer type. They should not affect your implementation, as the integer's internal binary representation is the same, whether it is signed or unsigned. -In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 2 above, the input represents the signed integer -3 and the output represents the signed integer -1073741825. - -- **Example 1:** -Input: n = 00000010100101000001111010011100 -Output: 964176192 (00111001011110000010100101000000) -Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000. - -- **Example 2:** -Input: n = 11111111111111111111111111111101 -Output: 3221225471 (10111111111111111111111111111111) -Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111. - -## Implementation in java: - -```java -public class Solution { - // you need treat n as an unsigned value - public int reverseBits(int n) { - return Integer.reverse(n); - } - - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - while (sc.hasNextInt()) { - int n = sc.nextInt(); - Solution example = new Solution(); - int result = example.reverseBits(n); - System.out.println(result); - } - sc.close(); - } -} -``` -## Approach: -- **1. Imports and Class Declaration:** - ```java - import java.util.Scanner; - public class Solution { - ``` - > Imports the Scanner class for input. - - > Declares the Solution class. -- **2. reverseBits Method:** - ```java - public int reverseBits(int n) { - return Integer.reverse(n); - } - ``` - > This method uses the Integer.reverse(n) function, which reverses the bits of the given 32-bit integer n. -- **3. main Method:** - ```java - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - while (sc.hasNextInt()) { - int n = sc.nextInt(); - Examples example = new Examples(); - int result = example.reverseBits(n); - System.out.println(result); - } - sc.close(); - } - ``` - > **Scanner Initialization:** Creates a Scanner object sc to read input from the user. - - > **Loop for Input:** Uses while (sc.hasNextInt()) to continually read integers as long as there are any. - - > **Instance Creation and Method Call:** For each integer input, it creates an instance of the *Solution* class and calls the *reverseBits* method on it. - - > **Print Result:** Outputs the reversed bits result. - - > **Close Scanner:** Ensures the Scanner is closed after usage. - -## Submission details: - -![Submission img](https://github.com/user-attachments/assets/2183e57d-213f-435d-a51d-5c84fc8f4e7a) diff --git a/docs/DSA-Problem-Solution/reverse-linked-list.md b/docs/DSA-Problem-Solution/reverse-linked-list.md deleted file mode 100644 index da6bd87a5..000000000 --- a/docs/DSA-Problem-Solution/reverse-linked-list.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -id: reverse-linked-list -sidebar_position: 1 -title: Reverse Linked List -sidebar_label: Reverse Linked List -description: "This document explains the Reverse Linked List problem, including its description, approach, and implementation." -tags: [dsa, algorithms, problem-solving] ---- - -# Reverse Linked List - -## Description -Given the head of a singly linked list, reverse the list, and return the reversed list. - -## Approach - -To reverse the linked list, we iterate through the list and reverse the `next` pointers of each node. We use three pointers (`prev`, `current`, and `next_node`) to track and reverse the list iteratively. - -### Steps: - -1. **Initialize**: - - Set `prev` to `None` and `current` to the head of the list. - -2. **Iterate**: - - Traverse each node in the list. - - Save the next node in `next_node`. - - Reverse the pointer of `current` to point to `prev`. - - Move `prev` and `current` one step forward. - -3. **Return**: - - After the loop, `prev` points to the new head of the reversed list. - -## Python Implementation - -```python -# Definition for singly-linked list. -# class ListNode: -# def __init__(self, val=0, next=None): -# self.val = val -# self.next = next - -class Solution: - def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: - prev = None - current = head - - while current: - next_node = current.next - current.next = prev - prev = current - current = next_node - - return prev -``` -Time Complexity: O(n)
-Space Complexity: O(1) - - -## C++ Implementation [Recursive Way] - -```cpp -/** - * Definition for singly-linked list. - * struct ListNode { - * int val; - * ListNode *next; - * ListNode() : val(0), next(nullptr) {} - * ListNode(int x) : val(x), next(nullptr) {} - * ListNode(int x, ListNode *next) : val(x), next(next) {} - * }; - */ -class Solution { -public: - ListNode* reverseList(ListNode* head) { - if(head == NULL || head->next == NULL) return head; - ListNode* prev = NULL; - ListNode* newHead = reverseList(head->next); - head->next->next = head; - head->next=prev; - return newHead; - } -}; -``` -Time Complexity: O(n)
-Space Complexity: O(1) - - -## C++ Implementation [Iterative Way] - -```cpp -/** - * Definition for singly-linked list. - * struct ListNode { - * int val; - * ListNode *next; - * ListNode() : val(0), next(nullptr) {} - * ListNode(int x) : val(x), next(nullptr) {} - * ListNode(int x, ListNode *next) : val(x), next(next) {} - * }; - */ -class Solution { -public: - ListNode* reverseList(ListNode* head) { - ListNode* prev = NULL; - ListNode* curr = head; - - while(curr != NULL){ - ListNode* forward = curr->next; - curr->next = prev; - prev = curr; - curr = forward; - - } - return prev; - } -}; -``` -Time Complexity: O(n)
-Space Complexity: O(1) diff --git a/docs/DSA-Problem-Solution/two_sum.md b/docs/DSA-Problem-Solution/two_sum.md deleted file mode 100644 index 440550858..000000000 --- a/docs/DSA-Problem-Solution/two_sum.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -id: two-sum-problem -sidebar_position: 2 -title: Two Sum -sidebar_label: Two Sum -description: "This document explains the Two Sum problem, including its description, approach, and implementation." -tags: [dsa, algorithms, problem-solving] ---- - -# Two Sum - -## Problem Statement -Given an array of integers `nums` and an integer `target`, return the indices of the two numbers such that they add up to `target`. - -## Approach -To solve this problem, we can use a hash map to store the numbers and their indices. As we iterate through the list, we check if the complement (target - current number) exists in the hash map. - -### Steps: - -1. **Initialize**: - - Create an empty `hash` map. - -2. **Iterate**: - - For each number in `nums`, calculate its complement. - - Check if the complement exists in the hash map. - - If it exists, return the indices. - - Otherwise, add the current number and its index to the hash map. - -3. **Return**: - - If no solution is found, return an empty list. - -## Python Implementation - -```python -class Solution: - def twoSum(self, nums: List[int], target: int) -> List[int]: - num_map = {} - for i, num in enumerate(nums): - complement = target - num - if complement in num_map: - return [num_map[complement], i] - num_map[num] = i -``` -Time Complexity: O(n)
-Space Complexity: O(n) \ No newline at end of file diff --git a/docs/Depth_first_traversal.md b/docs/Depth_first_traversal.md deleted file mode 100644 index e422fa42a..000000000 --- a/docs/Depth_first_traversal.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: dft -title: "Depth-First Traversal (DFT)" -sidebar_label: Depth-First Traversal -description: "In this blog post, we'll explore Depth-First Traversal (DFT), a tree traversal algorithm that explores nodes by going as deep as possible before backtracking." -tags: [dsa, algorithms, tree, traversal] ---- - -### Definition: - -**Depth-First Traversal (DFT)** is a **tree traversal algorithm** that explores nodes by going as deep as possible along each branch before backtracking. Starting from the root node, it traverses as far along a branch as possible before returning to explore other branches. DFT is commonly used in scenarios requiring a systematic exploration of a tree structure, such as evaluating expressions, searching, and more. - -### Characteristics: - -- **Preorder, Inorder, and Postorder Traversals**: - - Depth-First Traversal can be categorized into three main types depending on the order of visiting the root, left, and right nodes: - - **Preorder Traversal**: Visit the root node first, then the left subtree, followed by the right subtree. - - **Inorder Traversal**: Visit the left subtree, the root node, and finally the right subtree. - - **Postorder Traversal**: Visit the left subtree, then the right subtree, and finally the root node. - -- **Recursive or Stack-Based Traversal**: - - DFT can be implemented either recursively or with an explicit stack. The recursive approach is straightforward and concise, while the stack-based approach provides an iterative solution. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(N)$** - Where `N` is the number of nodes in the tree. DFT visits each node exactly once, making it efficient for complete traversal. - -### Space Complexity: - -- **Space Complexity: $O(H)$** - In the worst case, DFT requires space proportional to the height of the tree (`H`), either due to the recursion stack in a recursive approach or an explicit stack used for iterative traversal. - -### C++ Implementation: - -Here are C++ implementations for each type of depth-first traversal: preorder, inorder, and postorder. These examples use a recursive approach for simplicity. - -```cpp -#include -using namespace std; - -struct TreeNode { - int val; - TreeNode* left; - TreeNode* right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Preorder Traversal (Root -> Left -> Right) -void preorderTraversal(TreeNode* node) { - if (node == NULL) return; - cout << node->val << " "; - preorderTraversal(node->left); - preorderTraversal(node->right); -} - -// Inorder Traversal (Left -> Root -> Right) -void inorderTraversal(TreeNode* node) { - if (node == NULL) return; - inorderTraversal(node->left); - cout << node->val << " "; - inorderTraversal(node->right); -} - -// Postorder Traversal (Left -> Right -> Root) -void postorderTraversal(TreeNode* node) { - if (node == NULL) return; - postorderTraversal(node->left); - postorderTraversal(node->right); - cout << node->val << " "; -} - -int main() { - // Creating a sample tree: - // 1 - // / \ - // 2 3 - // / \ - // 4 5 - - TreeNode* root = new TreeNode(1); - root->left = new TreeNode(2); - root->right = new TreeNode(3); - root->left->left = new TreeNode(4); - root->left->right = new TreeNode(5); - - cout << "Preorder Traversal: "; - preorderTraversal(root); - cout << endl; - - cout << "Inorder Traversal: "; - inorderTraversal(root); - cout << endl; - - cout << "Postorder Traversal: "; - postorderTraversal(root); - cout << endl; - - return 0; -} -``` diff --git a/docs/Divide and Conquer/Maximum-minimum.md b/docs/Divide and Conquer/Maximum-minimum.md deleted file mode 100644 index 09ed42333..000000000 --- a/docs/Divide and Conquer/Maximum-minimum.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -id: maximum-minimum -title: Maximum-minimum -sidebar_label: Maximum-minimum -description: "Maximum minimum finding using divide and conquer approach to reduce the number of comparisions." -tags: [dsa, algorithms, divide and conquer] ---- - -### Definition: -This C program implements a divide-and-conquer algorithm to efficiently find the minimum and maximum values in an array. The algorithm recursively divides the array into smaller subarrays, computes the minimum and maximum for each subarray, and combines the results to find the overall minimum and maximum. - - -### Problem Statement: -Given an array X[] of size n, write a program to find the maximum and minimum element in the array. Our goal would be to solve this problem using minimum number of comparisons. Use divide and conquer apporach to solve the problem. - -### Algorithm Steps: - -1. Divide the array into two halves until only one or two elements remain in each subarray. -2. Conquer by finding the minimum and maximum of these smaller subarrays. -3. Combine the results by comparing minimums and maximums from each half to find the overall minimum and maximum. - -### Steps Involved: - -1. **Input Array:** The program receives an integer array a with n elements. - -2. **Function DAC_Min_Max:** This recursive function takes three parameters: - - `a[]`: the input array of integers - - `i`: the starting index of the current subarray - - `j`: the ending index of the current subarray - This function will return a structure Data that contains both the min and max values found in the subarray. - -3. **Divide Step:** - - - Base Case: - If `i == j`, meaning the subarray has only one element, the minimum and maximum values are simply that element itself. - If `i == j - 1`, meaning the subarray has two elements, compare them to set the minimum and maximum. - - - Recursive Case: - Otherwise, the array has more than two elements, so the function divides it at the midpoint `mid = (i + j) / 2` and recursively calls `DAC_Min_Max` for each half. - -4. **Conquer Step:** For each recursive call: - - Recursively find the minimum and maximum in both halves (left and right subarrays). - -5. **Combine Step:** Compare the minimum and maximum values returned from the left and right subarrays to determine the minimum and maximum of the current subarray: - - Set result.min to the lesser of `leftResult.min` and `rightResult.min`. - - Set result.max to the greater of `leftResult.max` and `rightResult.max`. - -6. **Result Check:** After all recursive calls complete, the main function displays the minimum and maximum values found in the entire array. - -7. **Edge Case:** If the array has only one element, that element is both the minimum and maximum. - -### Time Complexity: -- The time complexity of this algorithm is `O(n)` because each level of recursion processes a smaller subset of elements in parallel. The total number of comparisons is minimized to approximately `O(3n/2)` in the worst case, making this approach more efficient than a straightforward solution. - -### Sample Input: -Enter the size of the array: 6 -Enter the elements: 92 12 7 -5 65 38 - -### Sample Output: -The maximum value is: 92 -The minimum value is: -5 - -### C++ Implementation: -```cpp -#include -using namespace std; - -// Structure to hold both minimum and maximum values -struct Data { - int min; - int max; -}; - -Data DAC_Min_Max(int a[], int i, int j) { - int mid; - Data result, leftResult, rightResult; // Declare variables to hold min/max values for subarrays - - // Case 1: If there is only one element in the array - if (i == j) { - result.max = a[i]; - result.min = a[i]; - return result; - } - // Case 2: If there are only two elements - else if (i == j - 1) { - if (a[i] < a[j]) { // Compare the two elements and set min/max accordingly - result.max = a[j]; - result.min = a[i]; - } else { - result.max = a[i]; - result.min = a[j]; - } - return result; - } - - // Case 3: More than two elements, so divide the array - mid = (i + j) / 2; - leftResult = DAC_Min_Max(a, i, mid); // Recursively find min/max in the left subarray - rightResult = DAC_Min_Max(a, mid + 1, j); // Recursively find min/max in the right subarray - - // Compare the results from left and right subarrays to find the overall min and max - result.max = (leftResult.max > rightResult.max) ? leftResult.max : rightResult.max; - result.min = (leftResult.min < rightResult.min) ? leftResult.min : rightResult.min; - return result; -} - -int main() { - int n, a[50]; - Data MinMax; // Declare a structure to hold the final min and max values - - cout << "Enter the size of the array: "; - cin >> n; - - cout << "Enter the elements: "; - for (int i = 0; i < n; i++) - cin >> a[i]; - - MinMax = DAC_Min_Max(a, 0, n - 1); - - cout << "The maximum value is: " << MinMax.max << endl; - cout << "The minimum value is: " << MinMax.min << endl; - - return 0; -} -``` diff --git a/docs/Divide and Conquer/Strassen's-Matrix-Mutiplication.md b/docs/Divide and Conquer/Strassen's-Matrix-Mutiplication.md deleted file mode 100644 index 93179e2a6..000000000 --- a/docs/Divide and Conquer/Strassen's-Matrix-Mutiplication.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: strassens-matrix-mutiplication -title: Strassen's-Matrix-Mutiplication -sidebar_label: Strassen's-Matrix-Mutiplication -description: "Strassen's matrix multiplication is an efficient algorithm that reduces the time complexity of multiplying two matrices." -tags: [dsa, algorithms, divide and conquer] ---- - -### Problem Statement: -Given 2 matrix, multiply them such that the time complexity of the calculation is O(n^2.81). You can use divide and conquer approach to achieve the time complexity. - -## Algorithm Steps - -1. **Input Matrices**: Given two `n x n` matrices, `A` and `B`. - -2. **Base Case**: - - If `n = 1` , return the product `A[0][0] x B[0][0]` . - -3. **Divide**: - - Split each matrix into four n/2 x n/2 submatrices: - -4. **Compute Products**: - - Calculate the following seven products: - 1. P1 = A11 x (B12 - B22) - 2. P2 = (A11 + A12) x B22 - 3. P3 = (A21 + A22) x B11 - 4. P4 = A22 x (B21 - B11) - 5. P5 = (A11 + A22) x (B11 + B22) - 6. P6 = (A12 - A22) x (B21 + B22) - 7. P7 = (A11 - A21) x (B11 + B12) - -5. **Combine Results**: - - Compute the four submatrices of the resulting product: - - C11 = P5 + P4 - P2 + P6 - - C12 = P1 + P2 - - C21 = P3 + P4 - - C22 = P5 + P1 - P3 - P7 - -6. **Combine Submatrices**: - - Construct the final resulting matrix `C` from the submatrices. - -7. **Output**: Return the resulting matrix `C` . - -### Time Complexity: -- The time complexity of Strassen's algorithm for matrix multiplication is `O(n^2.81)`. This is an improvement over the conventional matrix multiplication's. Strassen's algorithm reduces the number of multiplicative operations by recursively dividing matrices into smaller submatrices, making it more efficient for large matrices, though it may incur overhead from additional additions and subtractions. - -### Space Complexity: -- The space complexity of Strassen's matrix multiplication algorithm is `O(n)`, where `n` is the dimension of the matrices. This complexity arises from the additional space needed to store the temporary matrices used in the recursive calculations. While Strassen's algorithm requires fewer multiplicative operations, it still utilizes linear space to hold the intermediate results, making it more space-efficient than traditional methods, which typically require `O(n^2)` space for the resulting matrix. - -### Sample Input: - Enter the elements of the first matrix (2x2): - 5 10 - 15 20 - Enter the elements of the second matrix (2x2): - 6 8 - 9 2 - -### Sample Output: - The resultant matrix is: - 120 60 - 270 160 - - -### C++ Implementation: - -```cpp - -#include -using namespace std; - -int main() { - int matrixA[2][2], matrixB[2][2], resultMatrix[2][2]; - int p1, p2, p3, p4, p5, p6, p7; - - cout << "Enter the elements of the first matrix (2x2):\n"; - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) - cin >> matrixA[i][j]; - } - - cout << "Enter the elements of the second matrix (2x2):\n"; - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) - cin >> matrixB[i][j]; - } - - - p1 = (matrixA[0][0] + matrixA[1][1]) * (matrixB[0][0] + matrixB[1][1]); - p2 = (matrixA[1][0] + matrixA[1][1]) * matrixB[0][0]; - p3 = matrixA[0][0] * (matrixB[0][1] - matrixB[1][1]); - p4 = matrixA[1][1] * (matrixB[1][0] - matrixB[0][0]); - p5 = (matrixA[0][0] + matrixA[0][1]) * matrixB[1][1]; - p6 = (matrixA[1][0] - matrixA[0][0]) * (matrixB[0][0] + matrixB[0][1]); - p7 = (matrixA[0][1] - matrixA[1][1]) * (matrixB[1][0] + matrixB[1][1]); - - resultMatrix[0][0] = p1 + p4 - p5 + p7; - resultMatrix[0][1] = p3 + p5; - resultMatrix[1][0] = p2 + p4; - resultMatrix[1][1] = p1 - p2 + p3 + p6; - - cout << "\nThe resultant matrix is:\n"; - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) - cout << resultMatrix[i][j] << "\t"; - cout << "\n"; - } - - return 0; -} - -``` diff --git a/docs/Fenwick Tree /FenwickTree.md b/docs/Fenwick Tree /FenwickTree.md deleted file mode 100644 index ba6bfd85b..000000000 --- a/docs/Fenwick Tree /FenwickTree.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: fenwick-tree -title: "Introduction to Fenwick Tree (Binary Indexed Tree)" -sidebar_label: "Fenwick Tree" -sidebar_position: 1 -description: "Information on Fenwick Tree (Binary Indexed Tree) Algorithm" -tags: [Algorithm, Fenwick Tree, Binary Indexed Tree] ---- - -# Fenwick Tree (Binary Indexed Tree) -## Overview -The Fenwick Tree, also known as a Binary Indexed Tree (BIT), is a data structure used for efficiently calculating prefix sums and updating elements. It offers a significant performance boost when dealing with cumulative frequency tables, making it ideal for scenarios where frequent updates and prefix sum queries are required. - -## Use Cases -- **Efficient Range Queries**: Commonly used in situations where range sums and point updates are frequent. -- **Inversion Counting in Arrays**: Used in competitive programming to count inversions in arrays. -- **Data Compression**: Supports cumulative frequency counting, which helps in data compression algorithms. -- **2D Queries**: Fenwick Trees can also be extended to 2D data structures, allowing applications in grid-based problems. - -## Algorithm Details -### Key Concepts -1. **Binary Indexed Representation**: Fenwick Trees leverage binary representation for efficient sum and update operations. -2. **Operations**: - - **Update**: Modify the value of a specific element. - - **Query**: Compute the cumulative sum up to a specific index. - -### Time Complexity -- Both update and query operations are `O(log N)` where `N` is the number of elements, due to the logarithmic depth of the tree. - -## Pseudocode - -```cpp -// Function to add 'val' to index 'i' (1-based index) -function update(i, val): - while i <= n: - BITree[i] += val - i += (i & -i) - -// Function to get sum from index 1 to i (1-based index) -function getSum(i): - sum = 0 - while i > 0: - sum += BITree[i] - i -= (i & -i) - return sum -``` - -## Example Code in C++ -Here’s a C++ implementation of the Fenwick Tree: - -```cpp -#include -#include -using namespace std; - -class FenwickTree { -private: - vector BITree; - int n; - -public: - // Initialize Fenwick Tree with n elements - FenwickTree(int size) { - n = size; - BITree.resize(n + 1, 0); - } - - // Update index 'i' with value 'val' - void update(int i, int val) { - while (i <= n) { - BITree[i] += val; - i += (i & -i); - } - } - - // Get cumulative sum from index 1 to 'i' - int getSum(int i) { - int sum = 0; - while (i > 0) { - sum += BITree[i]; - i -= (i & -i); - } - return sum; - } - - // Get sum from index 'l' to 'r' - int rangeSum(int l, int r) { - return getSum(r) - getSum(l - 1); - } -}; - -int main() { - FenwickTree ft(10); - ft.update(3, 5); // Update index 3 with +5 - ft.update(5, 2); // Update index 5 with +2 - cout << "Sum from 1 to 5: " << ft.getSum(5) << endl; - cout << "Range Sum from 3 to 5: " << ft.rangeSum(3, 5) << endl; - return 0; -} -``` - -## Explanation of the Code -- Update Operation: Updates the tree from a specific index by propagating the change to subsequent indices using i += (i & -i). -- Query Operation: Accumulates the sum of elements up to a specific index by traversing backward using i -= (i & -i). -- Range Sum Query: To compute the sum between two indices l and r, the difference of sums up to r and l-1 is used. - -## Example Walkthrough -Suppose we have an array of integers and initialize the Fenwick Tree with zeroes. For each update and query operation, the tree adjusts only the necessary indices, significantly improving efficiency. - -## Real-World Example -In competitive programming and applications dealing with real-time data processing, such as live leaderboard rankings or real-time transaction data, Fenwick Trees provide a fast and memory-efficient way to maintain cumulative values. diff --git a/docs/Hashing/CollisionHandling.md b/docs/Hashing/CollisionHandling.md deleted file mode 100644 index 19aab363c..000000000 --- a/docs/Hashing/CollisionHandling.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -id: collision-handling-in-hashing -sidebar_position: 5 -title: Collision Handling in Hashing -sidebar_label: Collision Handling in Hashing -tags: [hashing, data structures] ---- - -# Collision Handling in Hashing - -## Overview -In hashing, collision handling refers to the methods used to resolve the issue when two keys hash to the same index in a hash table. Collisions are inevitable in hash tables due to the limited number of available slots compared to the potentially infinite number of input keys. - -## Methods of Collision Handling - -### 1. Chaining (Open Hashing) -- Chaining stores multiple elements in the same bucket using a data structure like a linked list. -- When a collision occurs, the new key-value pair is added to the end of the linked list at that index. -- **Advantages**: Simple to implement, no need to resize the hash table. -- **Disadvantages**: Requires extra memory for pointers, performance degrades if many elements collide at the same index. - -### 2. Open Addressing (Closed Hashing) -- In open addressing, all elements are stored within the hash table itself, and when a collision occurs, alternative slots are probed to find an empty one. -- Common probing techniques include: - - **Linear Probing**: Increment the index sequentially until an empty slot is found. - - **Quadratic Probing**: Probe at quadratic intervals (i.e., 1, 4, 9, ...). - - **Double Hashing**: Use a second hash function to determine the probe step. -- **Advantages**: No need for extra memory for pointers, can be efficient for smaller tables. -- **Disadvantages**: Can lead to clustering (for linear probing), needs good probing strategies to avoid performance degradation. - -## Example: Chaining in Python - -```python -class HashTable: - def __init__(self): - self.table = [[] for _ in range(10)] # Hash table with 10 slots - - def insert(self, key, value): - index = hash(key) % len(self.table) - for pair in self.table[index]: - if pair[0] == key: - pair[1] = value # Update if key exists - return - self.table[index].append([key, value]) # Add new key-value pair - - def search(self, key): - index = hash(key) % len(self.table) - for pair in self.table[index]: - if pair[0] == key: - return pair[1] - return None - - def delete(self, key): - index = hash(key) % len(self.table) - for i, pair in enumerate(self.table[index]): - if pair[0] == key: - del self.table[index][i] - return - - - -# Example usage -hash_table = HashTable() -hash_table.insert('apple', 1) -hash_table.insert('banana', 2) -hash_table.insert('orange', 3) -print(hash_table.search('banana')) # Output: 2 -hash_table.delete('banana') -print(hash_table.search('banana')) # Output: None - -``` - -## Example: Chaining in JavaScript - -```javascript -class HashTable { - constructor() { - this.table = Array.from({ length: 10 }, () => []); // Hash table with 10 slots - } - - hash(key) { - let hash = 0; - for (let char of key.toString()) { - hash += char.charCodeAt(0); - } - return hash % this.table.length; // Simple hash function - } - - insert(key, value) { - const index = this.hash(key); - for (let pair of this.table[index]) { - if (pair[0] === key) { - pair[1] = value; // Update if key exists - return; - } - } - this.table[index].push([key, value]); // Add new key-value pair - } - - search(key) { - const index = this.hash(key); - for (let pair of this.table[index]) { - if (pair[0] === key) { - return pair[1]; // Return the value if key is found - } - } - return null; // Key not found - } - - delete(key) { - const index = this.hash(key); - this.table[index] = this.table[index].filter(pair => pair[0] !== key); // Remove the key-value pair - } -} - -// Example usage -const hashTable = new HashTable(); -hashTable.insert('apple', 1); -hashTable.insert('banana', 2); -hashTable.insert('orange', 3); -console.log(hashTable.search('banana')); // Output: 2 -hashTable.delete('banana'); -console.log(hashTable.search('banana')); // Output: null -``` diff --git a/docs/Hashing/OperationInsertion.md b/docs/Hashing/OperationInsertion.md deleted file mode 100644 index 33f695699..000000000 --- a/docs/Hashing/OperationInsertion.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -id: insertion-in-hash-table -sidebar_position: 1 -title: Insertion in Hash Table -sidebar_label: Insertion in Hash Table -description: "Insertion involves adding a key-value pair to the hash table. If the key already exists, it may update the existing value." -tags: [hashing, data structures, insertion] ---- - -## Insertion in Hash Table - -The insertion operation in a hash table involves adding a key-value pair. Hashing is used to map the key to an index in the table. If the key already exists, the existing value can be updated. - -### Steps for Insertion - -1. **Hash the Key**: Use a hash function to convert the key into an index. -2. **Insert at the Computed Index**: Place the key-value pair at the index. If there's already data, resolve collisions via methods like chaining or open addressing. -3. **Update Value (if Key Exists)**: If the key already exists, update the associated value. - -### Time Complexity -- **Average Case**: $O(1)$ -- **Worst Case**: $O(n)$ (if many collisions occur) - -### Example Code (Python) - -```python -class HashTable: - def __init__(self): - self.table = {} - - def insert(self, key, value): - self.table[key] = value - -# Example usage -hash_table = HashTable() -hash_table.insert('apple', 10) -hash_table.insert('banana', 20) -hash_table.insert('apple', 30) # Updates value -``` - -### Conclusion - -Insertion is a fundamental operation in hash tables, allowing for efficient data storage and retrieval, especially when handling key-value pairs. diff --git a/docs/Hashing/OperationSearch.md b/docs/Hashing/OperationSearch.md deleted file mode 100644 index 8a6df85be..000000000 --- a/docs/Hashing/OperationSearch.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -id: search-in-hash-table -sidebar_position: 3 -title: Search in Hash Table -sidebar_label: Search in Hash Table -description: "Search involves retrieving the value associated with a given key in the hash table." -tags: [hashing, data structures, search] ---- - -## Search in Hash Table - -The search operation involves retrieving the value associated with a key in a hash table. Hashing ensures efficient lookups based on the key. - -### Steps for Search - -1. **Hash the Key**: Use the hash function to determine the index. -2. **Check for Key**: If the key exists at the computed index, return the corresponding value. -3. **Handle Collision**: Properly handle cases where multiple keys map to the same index. - -### Time Complexity -- **Average Case**: $O(1)$ -- **Worst Case**: $O(n)$ - -### Example Code (Python) - -```python -class HashTable: - def __init__(self): - self.table = {} - - def search(self, key): - return self.table.get(key, None) - -# Example usage -hash_table = HashTable() -hash_table.table = {'apple': 10, 'banana': 20} -print(hash_table.search('apple')) # Output: 10 -``` -### Example Code (JavaScript) - -```javascript -class HashTable { - constructor() { - this.table = {}; - } - - // Method to search for a key in the hash table - search(key) { - return this.table.hasOwnProperty(key) ? this.table[key] : null; - } -} - -// Example usage -const hashTable = new HashTable(); -hashTable.table = { apple: 10, banana: 20 }; -console.log(hashTable.search('apple')); // Output: 10 -``` - - -### Conclusion - -Search is one of the primary operations in a hash table, allowing fast retrieval of data associated with a key. diff --git a/docs/Hashing/OperationUpdate.md b/docs/Hashing/OperationUpdate.md deleted file mode 100644 index 21afa0b4e..000000000 --- a/docs/Hashing/OperationUpdate.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -id: update-in-hash-table -sidebar_position: 4 -title: Update in Hash Table -sidebar_label: Update in Hash Table -description: "Update involves modifying the value associated with an existing key in the hash table." -tags: [hashing, data structures, update] ---- - -## Update in Hash Table - -The update operation involves modifying the value associated with an existing key in a hash table. If the key is not present, it may require an insertion. - -### Steps for Update - -1. **Hash the Key**: Use a hash function to find the index. -2. **Update the Value**: Modify the value associated with the key if it exists. -3. **Handle Key Absence**: If the key does not exist, you can choose to insert it instead. - -### Time Complexity -- **Average Case**: $O(1)$ -- **Worst Case**: $O(n)$ - -### Example Code (Python) - -```python -class HashTable: - def __init__(self): - self.table = {} - - def update(self, key, value): - self.table[key] = value - -# Example usage -hash_table = HashTable() -hash_table.table = {'apple': 10, 'banana': 20} -hash_table.update('apple', 30) # Updates value -``` - -### Example Code (Javascript) - -```javascript -class HashTable { - constructor() { - this.table = {}; - } - - update(key, value) { - this.table[key] = value; - } -} - -// Example usage -const hashTable = new HashTable(); -hashTable.table = { 'apple': 10, 'banana': 20 }; -hashTable.update('apple', 30); // Updates the value for 'apple' -console.log(hashTable.table); // Output: { 'apple': 30, 'banana': 20 } -``` - -### Conclusion - -Update is critical for modifying data in hash tables, making them adaptable and suitable for dynamic applications. diff --git a/docs/Hashing/Tigerhashing.md b/docs/Hashing/Tigerhashing.md deleted file mode 100644 index 8e6601816..000000000 --- a/docs/Hashing/Tigerhashing.md +++ /dev/null @@ -1,38 +0,0 @@ -# Tiger Hashing Algorithm - -## Overview -The **Tiger Hashing Algorithm** is a cryptographic hash function developed by Ross Anderson and Eli Biham in 1995. It is optimized for 64-bit platforms and is known for its fast performance and security. Tiger is often used in applications where both speed and security are critical, such as file integrity checking, digital signatures, and password hashing. - -## Features -- **Block size**: 512 bits -- **Digest size**: 192 bits (can also produce 160 or 128-bit digests through truncation) -- **Optimized for**: 64-bit platforms -- **Security**: Resistant to most cryptographic attacks like collision and pre-image attacks (as of its time of development) -- **Speed**: Fast hash function compared to others like MD5 or SHA-1, especially on 64-bit systems - -## Algorithm Overview -The Tiger Hash function takes an input message and processes it in blocks of 512 bits to produce a 192-bit hash value. It uses three 64-bit state variables (A, B, C) and operates in three main steps: - -1. **Message Padding**: - - The input message is padded so that its length is congruent to 448 modulo 512. Padding consists of a '1' bit followed by '0' bits, and the last 64 bits represent the length of the original message. - -2. **Processing Block-by-Block**: - - The message is divided into 512-bit blocks, and each block is processed through a series of operations that update the internal state (A, B, C). - - The core of the algorithm uses a combination of XOR, bitwise shifts, and additions with a set of S-boxes (lookup tables) to mix and diffuse the input data across the state variables. - -3. **Final Transformation**: - - After processing all blocks, the final hash value is derived from the three state variables and concatenated to form the final 192-bit (or truncated) output. - -## Pseudocode - -```plaintext -Input: Message M -Output: 192-bit Hash Value -``` - -1. Pad the message M to make its length a multiple of 512 bits. -2. Initialize three 64-bit variables: A, B, and C with predefined values. -3. For each 512-bit block of the padded message: - a. Perform a series of transformations on A, B, and C using the block and S-boxes. - b. Update A, B, and C after processing each block. -4. After processing all blocks, concatenate A, B, and C to produce the final 192-bit hash. diff --git a/docs/Hashing/_category_.json b/docs/Hashing/_category_.json deleted file mode 100644 index 0fed609fd..000000000 --- a/docs/Hashing/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Hashing in DSA", - "position": 7, - "link": { - "type": "generated-index", - "description": "Hashing is a crucial technique in data structures and algorithms (DSA) that provides efficient ways to store, retrieve, and manage data. It is widely used in competitive programming to solve problems involving searching, duplicates, and efficient data access, thanks to constant-time complexity in ideal cases." - } -} diff --git a/docs/Hashing/deletion-in-hash-table.md b/docs/Hashing/deletion-in-hash-table.md deleted file mode 100644 index 127ece0f8..000000000 --- a/docs/Hashing/deletion-in-hash-table.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: deletion-in-hash-table -sidebar_position: 2 -title: Deletion in Hash Table -sidebar_label: Deletion in Hash Table -description: "Deletion involves removing a key-value pair from the hash table using the key." -tags: [hashing, data structures, deletion] ---- - -The deletion operation in a hash table involves removing a key-value pair using the key. If the key is not present, no operation is performed. - -### Steps for Deletion - -1. **Hash the Key**: Use a hash function to find the index of the key. -2. **Remove the Key-Value Pair**: Delete the key-value pair from the index if the key exists. -3. **Handle Collision**: Ensure proper handling of collisions if the table uses chaining or open addressing. - -### Time Complexity -- **Average Case**: $O(1)$ -- **Worst Case**: $O(n)$ - -### Example Code (cpp) - -```cpp -#include -#include - -class HashTable { -public: - // Constructor - HashTable() {} - - // Function to delete a key from the hash table - void deleteKey(int key) { - if (table.find(key) != table.end()) { - table.erase(key); // Erase the key if it exists - std::cout << "Key " << key << " deleted.\n"; - } else { - std::cout << "Key " << key << " not found.\n"; - } - } - - // Function to insert a key-value pair into the hash table - void insert(int key, int value) { - table[key] = value; - } - - // Function to display the hash table - void display() { - for (const auto& pair : table) { - std::cout << pair.first << ": " << pair.second << std::endl; - } - } - -private: - std::unordered_map table; // Hash table using unordered_map -}; - -int main() { - HashTable ht; - - ht.insert(1, 100); - ht.insert(2, 200); - ht.insert(3, 300); - - std::cout << "Hash Table before deletion:\n"; - ht.display(); - - ht.deleteKey(2); // Deleting key 2 - - std::cout << "Hash Table after deletion:\n"; - ht.display(); - - return 0; -} -``` - -### Example Code (java) - -```java -import java.util.HashMap; - -public class HashTable { - // HashMap to simulate the hash table - private HashMap table; - - // Constructor - public HashTable() { - table = new HashMap<>(); - } - - // Function to delete a key from the hash table - public void deleteKey(int key) { - if (table.containsKey(key)) { - table.remove(key); // Remove the key if it exists - System.out.println("Key " + key + " deleted."); - } else { - System.out.println("Key " + key + " not found."); - } - } - - // Function to insert a key-value pair into the hash table - public void insert(int key, int value) { - table.put(key, value); - } - - // Function to display the hash table - public void display() { - for (HashMap.Entry entry : table.entrySet()) { - System.out.println(entry.getKey() + ": " + entry.getValue()); - } - } - - public static void main(String[] args) { - HashTable ht = new HashTable(); - - // Inserting key-value pairs - ht.insert(1, 100); - ht.insert(2, 200); - ht.insert(3, 300); - - // Display hash table before deletion - System.out.println("Hash Table before deletion:"); - ht.display(); - - // Deleting a key - ht.deleteKey(2); - - // Display hash table after deletion - System.out.println("Hash Table after deletion:"); - ht.display(); - } -} - -# Example usage -hash_table = HashTable() -hash_table.table = {'apple': 10, 'banana': 20} -hash_table.delete('apple') -``` - -### Example Code (JavaScript) - -```javascript -class HashTable { - constructor() { - this.table = new Map(); - } - - // Function to delete a key from the hash table - deleteKey(key) { - if (this.table.has(key)) { - this.table.delete(key); // Erase the key if it exists - console.log(`Key ${key} deleted.`); - } else { - console.log(`Key ${key} not found.`); - } - } - - // Function to insert a key-value pair into the hash table - insert(key, value) { - this.table.set(key, value); - } - - // Function to display the hash table - display() { - for (const [key, value] of this.table.entries()) { - console.log(`${key}: ${value}`); - } - } -} - -// Example usage -const ht = new HashTable(); - -ht.insert(1, 100); -ht.insert(2, 200); -ht.insert(3, 300); - -console.log("Hash Table before deletion:"); -ht.display(); - -ht.deleteKey(2); // Deleting key 2 - -console.log("Hash Table after deletion:"); -ht.display(); -``` - -### Conclusion - -Deletion is essential for maintaining the dynamic nature of a hash table by removing unwanted key-value pairs. diff --git a/docs/Hashing/hashsets.md b/docs/Hashing/hashsets.md deleted file mode 100644 index 7000db35b..000000000 --- a/docs/Hashing/hashsets.md +++ /dev/null @@ -1,322 +0,0 @@ ---- -id: what-is-hashset -sidebar_position: 3 -title: What is a HashSet? -sidebar_label: What is a HashSet? -description: "A HashSet is a data structure used to store unique elements and provides efficient insertion, deletion, and search operations." -tags: [data structures, algorithms, hashset, sets, hashing, C++] ---- - -## HashSet - -A **HashSet** is a data structure that stores a collection of unique elements, ensuring no duplicates. Unlike a **HashMap**, which maps keys to values, a **HashSet** only stores the keys (elements) and guarantees uniqueness. Internally, a **HashSet** uses hashing to provide efficient operations. - -### Importance of HashSets - -1. **Unique Elements**: The main purpose of a **HashSet** is to ensure all elements are unique. If you try to add a duplicate element, the set will reject it. - -2. **Fast Lookup, Insert, and Delete**: HashSets offer average-case constant time complexity \(O(1)\) for insertion, deletion, and search operations due to the underlying hash table implementation. - -3. **Memory Efficiency**: Since a **HashSet** only stores unique elements and uses hashing to place items in a table, it optimizes memory and performance. - -4. **Unordered**: **HashSets** do not maintain any specific order of elements. If order is required, other data structures like `std::set` or `std::vector` can be used. - -### Common Applications of HashSets - -- **Duplicate Removal**: HashSets are perfect when you need to remove duplicates from a collection. -- **Membership Testing**: You can use a HashSet to quickly check whether an element exists in a collection. -- **Set Operations**: HashSets allow for efficient implementation of set operations like union, intersection, and difference. - -### HashSet vs HashMap - -Although both **HashSet** and **HashMap** use hashing internally, their key difference is that **HashSet** only stores unique elements (keys), while **HashMap** stores key-value pairs. - -### Example of HashSet Implementation in C++ - -In C++, the `unordered_set` from the Standard Template Library (STL) is commonly used for hash-based sets. Here's a simple custom **HashSet** implementation in C++ to show how it works under the hood: - -```C++ -#include -#include -#include -#include -using namespace std; - -class HashSet { -private: - static const int size = 1000; // Define the size of the hash table - vector> table; - -public: - HashSet() : table(size) {} // Initialize the hash table with empty lists - - int hash_function(const string& key) { - return hash()(key) % size; // Use the built-in hash function - } - - void add(const string& key) { - int index = hash_function(key); - for (const string& element : table[index]) { - if (element == key) { - return; // Key already exists, no need to add duplicates - } - } - table[index].push_back(key); // Add the key if it's not a duplicate - } - - bool contains(const string& key) { - int index = hash_function(key); - for (const string& element : table[index]) { - if (element == key) { - return true; // Key is found - } - } - return false; // Key is not found - } - - void remove(const string& key) { - int index = hash_function(key); - table[index].remove(key); // Remove the key if it exists - } -}; - -// Example usage -int main() { - HashSet hashSet; - hashSet.add("apple"); - cout << "Contains 'apple': " << hashSet.contains("apple") << endl; // Output: 1 (true) - hashSet.remove("apple"); - cout << "Contains 'apple': " << hashSet.contains("apple") << endl; // Output: 0 (false) - return 0; -} -``` -## Common HashSet Problems and Solutions in C++ -Below are some common problems that can be efficiently solved using HashSets. - -### 1. Finding Duplicates in an Array -Problem: Given an array, determine if it contains any duplicates. - -C++ Solution: - -```cpp -#include -#include -#include -using namespace std; - -bool contains_duplicates(const vector& nums) { - unordered_set hashSet; - for (int num : nums) { - if (hashSet.find(num) != hashSet.end()) { - return true; // Duplicate found - } - hashSet.insert(num); - } - return false; // No duplicates found -} - -int main() { - vector nums1 = {1, 2, 3, 1}; - cout << "Contains duplicates: " << contains_duplicates(nums1) << endl; // Output: 1 (true) - vector nums2 = {1, 2, 3}; - cout << "Contains duplicates: " << contains_duplicates(nums2) << endl; // Output: 0 (false) - return 0; -} -``` - -### 2. Intersection of Two Arrays -Problem: Given two arrays, return their intersection (common elements). - -C++ Solution: - -```cpp -#include -#include -#include -using namespace std; - -vector intersection(const vector& nums1, const vector& nums2) { - unordered_set set1(nums1.begin(), nums1.end()); // Store elements of nums1 in a set - vector result; - for (int num : nums2) { - if (set1.find(num) != set1.end()) { - result.push_back(num); // Add to result if found in set1 - set1.erase(num); // Avoid duplicates in result - } - } - return result; -} - -int main() { - vector nums1 = {1, 2, 2, 1}; - vector nums2 = {2, 2}; - vector result = intersection(nums1, nums2); - - cout << "Intersection: "; - for (int num : result) { - cout << num << " "; // Output: 2 - } - cout << endl; - return 0; -} -``` -### 3. Unique Email Addresses -Problem: Given a list of email addresses, return the number of unique email addresses, ignoring periods . and any portion of the address after a plus sign + in the local name. - -C++ Solution: -```cpp -#include -#include -#include -#include -using namespace std; - -string clean_email(const string& email) { - string local, domain; - bool in_domain = false; - for (char ch : email) { - if (ch == '@') { - in_domain = true; - } - if (in_domain) { - domain += ch; // Copy the domain part as is - } else if (ch == '+') { - break; // Ignore the part after '+' - } else if (ch != '.') { - local += ch; // Copy the local part, ignoring '.' - } - } - return local + domain; -} - -int unique_emails(const vector& emails) { - unordered_set uniqueSet; - for (const string& email : emails) { - uniqueSet.insert(clean_email(email)); // Insert the cleaned email - } - return uniqueSet.size(); -} - -int main() { - vector emails = { - "test.email+alex@leetcode.com", - "test.e.mail+bob@leetcode.com", - "testemail+david@lee.tcode.com" - }; - cout << "Unique emails: " << unique_emails(emails) << endl; // Output: 2 - return 0; -} -``` - -### Example of HashSet Implementation in JavaScript - - -### 1. **HashSet Implementation** - -```javascript -class HashSet { - constructor(size = 1000) { - this.size = size; - this.table = Array.from({ length: size }, () => []); - } - - hashFunction(key) { - let hash = 0; - for (const char of key) { - hash += char.charCodeAt(0); - } - return hash % this.size; - } - - add(key) { - const index = this.hashFunction(key); - if (!this.table[index].includes(key)) { - this.table[index].push(key); - } - } - - contains(key) { - const index = this.hashFunction(key); - return this.table[index].includes(key); - } - - remove(key) { - const index = this.hashFunction(key); - this.table[index] = this.table[index].filter(item => item !== key); - } -} - -// Example usage -const hashSet = new HashSet(); -hashSet.add("apple"); -console.log("Contains 'apple':", hashSet.contains("apple")); // Output: true -hashSet.remove("apple"); -console.log("Contains 'apple':", hashSet.contains("apple")); // Output: false -``` - -### 2. **Finding Duplicates in an Array** -Problem: Given an array, determine if it contains any duplicates. - -```javascript -function containsDuplicates(nums) { - const hashSet = new Set(); - for (const num of nums) { - if (hashSet.has(num)) { - return true; // Duplicate found - } - hashSet.add(num); - } - return false; // No duplicates found -} - -// Example usage -console.log(containsDuplicates([1, 2, 3, 1])); // Output: true -console.log(containsDuplicates([1, 2, 3])); // Output: false -``` - -### 3. **Intersection of Two Arrays** -Problem: Given two arrays, return their intersection (common elements). - -```javascript -function intersection(nums1, nums2) { - const set1 = new Set(nums1); - const result = []; - for (const num of nums2) { - if (set1.has(num)) { - result.push(num); - set1.delete(num); // Avoid duplicates in result - } - } - return result; -} - -// Example usage -console.log(intersection([1, 2, 2, 1], [2, 2])); // Output: [2] -``` - -### 4. **Unique Email Addresses** -Problem: Given a list of email addresses, return the number of unique email addresses, ignoring periods . and any portion of the address after a plus sign + in the local name. - -```javascript -function cleanEmail(email) { - const [local, domain] = email.split('@'); - const cleanLocal = local.split('+')[0].replace(/\./g, ''); - return `${cleanLocal}@${domain}`; -} - -function uniqueEmails(emails) { - const uniqueSet = new Set(); - for (const email of emails) { - uniqueSet.add(cleanEmail(email)); - } - return uniqueSet.size; -} - -// Example usage -const emails = [ - "test.email+alex@leetcode.com", - "test.e.mail+bob@leetcode.com", - "testemail+david@lee.tcode.com" -]; -console.log("Unique emails:", uniqueEmails(emails)); // Output: 2 -``` diff --git a/docs/Hashing/imp-of-hashing.md b/docs/Hashing/imp-of-hashing.md deleted file mode 100644 index 997d266a1..000000000 --- a/docs/Hashing/imp-of-hashing.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -id: imp-of-hashing -sidebar_position: 2 -title: Importance of Hashing -sidebar_label: Importance of Hashing -description: "Hashing is an essential technique in data structures and algorithms used to optimize data retrieval, storage, and management through efficient key-value mapping." -tags: [algorithms, hashing, data structures] ---- - -## Hashing - -Hashing is a fundamental technique in data structures and algorithms (DSA) that involves mapping data to a fixed-size value (hash code) using a hash function. This technique provides efficient ways to store, retrieve, and manage data, making it particularly useful in applications requiring quick lookups, insertions, and deletions. - -### Importance of Hashing - -1. **Fast Data Retrieval**: - - Hashing allows for average-case constant time complexity $(O(1))$ for data retrieval, making it significantly faster than linear search methods. - -2. **Efficient Memory Usage**: - - By using hash tables, data can be stored in a way that optimizes memory usage, reducing the overhead associated with other data structures like arrays and linked lists. - -3. **Handling Duplicates**: - - Hashing effectively manages duplicates in data by providing unique keys for each entry, which can be particularly useful in applications requiring uniqueness, such as counting occurrences. - -4. **Facilitating Complex Data Structures**: - - Hash maps enable the implementation of complex data structures, such as dictionaries and sets, which are fundamental in many algorithms and applications. - -### Common Applications of Hashing - -- **Caching**: - - Hashing is often used in caching solutions to store and quickly retrieve computed results, thereby improving the efficiency of repeated function calls. - -- **Database Indexing**: - - Hash tables are used in databases to index data, facilitating rapid access and retrieval based on keys. - -- **Counting Frequencies**: - - Hash maps can count the frequency of elements in a dataset, which is useful in statistics and data analysis. - -- **Anagram Detection**: - - Hashing can be employed to check for anagrams by counting character frequencies and comparing them between two strings. - -### Example of Hashing - -#### Problem: Count Frequencies of Elements - -**Using a Hash Map in Python**: - -```python -def count_frequencies(arr): - frequency_map = {} - for num in arr: - if num in frequency_map: - frequency_map[num] += 1 - else: - frequency_map[num] = 1 - return frequency_map - -# Example usage -arr = [1, 2, 2, 3, 3, 3, 4] -print(count_frequencies(arr)) # Output: {1: 1, 2: 2, 3: 3, 4: 1} -``` - -### Conclusion - -Hashing is an indispensable technique in the field of data structures and algorithms, offering significant performance improvements for data retrieval and management. Understanding hashing concepts, including hash functions and hash tables, is crucial for solving complex problems efficiently, particularly in competitive programming and algorithm design. Mastering hashing techniques enables programmers to develop optimized solutions that can handle large datasets effectively. diff --git a/docs/Hashing/what-is-hashing.md b/docs/Hashing/what-is-hashing.md deleted file mode 100644 index d45e05e1a..000000000 --- a/docs/Hashing/what-is-hashing.md +++ /dev/null @@ -1,364 +0,0 @@ ---- -id: what-is-hashing -sidebar_position: 1 -title: What is Hashing and Hash Maps? -sidebar_label: What is Hashing and Hash Maps? -description: "Hashing is a technique used to uniquely identify a specific object from a group of similar objects. Hash maps are data structures that implement this technique." -tags: [data structures, algorithms, hashing, hash maps] ---- - -## Hashing - -Hashing is a technique used in computer science to uniquely identify a specific object from a group of similar objects. It involves the transformation of input data (keys) into a fixed-size hash code using a hash function. This hash code serves as an index in a hash table where the actual data (values) is stored. - -### Importance of Hashing - -1. **Fast Data Retrieval**: Hashing allows for quick data retrieval, enabling average-case constant time complexity \(O(1)\) for search, insert, and delete operations. - -2. **Efficient Memory Usage**: Hash tables can store a large amount of data with minimal wasted memory due to their fixed size. - -3. **Collision Resolution**: Hashing provides methods for resolving collisions (when two keys hash to the same index), ensuring data integrity and retrieval accuracy. - -4. **Flexibility**: Hash maps can handle various data types as keys, making them versatile for different applications. - -### Common Applications of Hashing - -- **Database Indexing**: Hashing is often used in databases to quickly locate a data record. -- **Caching**: Web applications use hashing to cache data and improve performance. -- **Cryptography**: Hash functions are crucial in data integrity checks and password storage. -- **Counting Frequencies**: Hash maps are commonly used to count the occurrences of elements in a dataset. - -### Hash Maps - -A hash map (or hash table) is a data structure that implements an associative array abstract data type, a structure that can map keys to values. It uses a hash function to compute an index into an array of buckets or slots, from which the desired value can be found. - -#### Example of Hash Map Implementation - -Here’s a simple implementation of a hash map in Python and C++: - -**Python Implementation**: -```python -class HashMap: - def __init__(self): - self.size = 1000 - self.map = [[] for _ in range(self.size)] - - def hash_function(self, key): - return hash(key) % self.size - - def insert(self, key, value): - index = self.hash_function(key) - for pair in self.map[index]: - if pair[0] == key: - pair[1] = value - return - self.map[index].append([key, value]) - - def get(self, key): - index = self.hash_function(key) - for pair in self.map[index]: - if pair[0] == key: - return pair[1] - return None - - def delete(self, key): - index = self.hash_function(key) - for i, pair in enumerate(self.map[index]): - if pair[0] == key: - del self.map[index][i] - return - -# Example usage -hash_map = HashMap() -hash_map.insert("name", "Alice") -print(hash_map.get("name")) # Output: Alice -hash_map.delete("name") -print(hash_map.get("name")) # Output: None -``` - -**C++ Implementation**: -```C++ -#include -#include -#include -#include -using namespace std; - -class HashMap { -private: - static const int size = 1000; - vector>> map; - -public: - HashMap() : map(size) {} - - int hash_function(const string& key) { - return hash()(key) % size; - } - - void insert(const string& key, const string& value) { - int index = hash_function(key); - for (auto& pair : map[index]) { - if (pair.first == key) { - pair.second = value; - return; - } - } - map[index].emplace_back(key, value); - } - - string get(const string& key) { - int index = hash_function(key); - for (const auto& pair : map[index]) { - if (pair.first == key) { - return pair.second; - } - } - return ""; - } - - void delete_key(const string& key) { - int index = hash_function(key); - for (auto it = map[index].begin(); it != map[index].end(); ++it) { - if (it->first == key) { - map[index].erase(it); - return; - } - } - } -}; - -// Example usage -int main() { - HashMap hash_map; - hash_map.insert("name", "Alice"); - cout << hash_map.get("name") << endl; // Output: Alice - hash_map.delete_key("name"); - cout << hash_map.get("name") << endl; // Output: (empty) - return 0; -} - -``` - -**JavaScript Implementation**: - -```javascript -class HashMap { - constructor() { - this.size = 1000; - this.map = Array.from({ length: this.size }, () => []); - } - - hashFunction(key) { - let hash = 0; - for (let i = 0; i < key.length; i++) { - hash = (hash * 31 + key.charCodeAt(i)) % this.size; - } - return hash; - } - - insert(key, value) { - const index = this.hashFunction(key); - for (const pair of this.map[index]) { - if (pair[0] === key) { - pair[1] = value; - return; - } - } - this.map[index].push([key, value]); - } - - get(key) { - const index = this.hashFunction(key); - for (const pair of this.map[index]) { - if (pair[0] === key) { - return pair[1]; - } - } - return null; - } - - deleteKey(key) { - const index = this.hashFunction(key); - const bucket = this.map[index]; - for (let i = 0; i < bucket.length; i++) { - if (bucket[i][0] === key) { - bucket.splice(i, 1); - return; - } - } - } -} - -// Example usage -const hashMap = new HashMap(); -hashMap.insert("name", "Alice"); -console.log(hashMap.get("name")); // Output: Alice -hashMap.deleteKey("name"); -console.log(hashMap.get("name")); // Output: null -``` - - -### Common Hash Map Problems -Here are some problems commonly encountered when working with hash maps, along with their solutions. - -- **Two Sum Problem** -**Problem**: Given an array of integers and a target sum, find two numbers such that they add up to the target. - - - **Python Solution**: - - ``` - def two_sum(nums, target): - hashmap = {} - for i, num in enumerate(nums): - complement = target - num - if complement in hashmap: - return [hashmap[complement], i] - hashmap[num] = i - - # Example usage - print(two_sum([2, 7, 11, 15], 9)) # Output: [0, 1] - ``` - - - **C++ Solution**: - - ``` - #include - #include - #include - using namespace std; - - vector two_sum(vector& nums, int target) { - unordered_map hashmap; - for (int i = 0; i < nums.size(); i++) { - int complement = target - nums[i]; - if (hashmap.count(complement)) { - return {hashmap[complement], i}; - } - hashmap[nums[i]] = i; - } - return {}; - } - - // Example usage - int main() { - vector nums = {2, 7, 11, 15}; - vector result = two_sum(nums, 9); - for (int index : result) { - cout << index << " "; // Output: 0 1 - } - return 0; - } - - ``` - - - **JavaScript Solution**: - - ```javascript - function twoSum(nums, target) { - const hashmap = new Map(); - - for (let i = 0; i < nums.length; i++) { - const complement = target - nums[i]; - - if (hashmap.has(complement)) { - return [hashmap.get(complement), i]; - } - - hashmap.set(nums[i], i); - } - - return []; - } - - // Example usage - const nums = [2, 7, 11, 15]; - const result = twoSum(nums, 9); - console.log(result); // Output: [0, 1] - ``` - - -- **Group Anagrams** -**Problem**: Given an array of strings, group the anagrams together. - - - **Python Solution**: - - ``` - def group_anagrams(strs): - anagrams = {} - for s in strs: - key = tuple(sorted(s)) - anagrams.setdefault(key, []).append(s) - return list(anagrams.values()) - - # Example usage - print(group_anagrams(["eat", "tea", "tan", "ate", "nat", "bat"])) - # Output: [['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']] - - ``` - - - **C++ Solution**: - - ``` - #include - #include - #include - #include - using namespace std; - - vector> group_anagrams(vector& strs) { - unordered_map> anagrams; - for (const string& s : strs) { - string key = s; - sort(key.begin(), key.end()); - anagrams[key].push_back(s); - } - vector> result; - for (const auto& pair : anagrams) { - result.push_back(pair.second); - } - return result; - } - - // Example usage - int main() { - vector strs = {"eat", "tea", "tan", "ate", "nat", "bat"}; - vector> result = group_anagrams(strs); - for (const auto& group : result) { - for (const auto& word : group) { - cout << word << " "; - } - cout << endl; // Output: eat tea ate | tan nat | bat - } - return 0; - } - - ``` - - - **JavaScript Solution**: - - ```javascript - function groupAnagrams(strs) { - const anagrams = new Map(); - - for (const s of strs) { - const key = s.split('').sort().join(''); - - if (!anagrams.has(key)) { - anagrams.set(key, []); - } - anagrams.get(key).push(s); - } - - return Array.from(anagrams.values()); - } - - // Example usage - const strs = ["eat", "tea", "tan", "ate", "nat", "bat"]; - const result = groupAnagrams(strs); - console.log(result); // Output: [ [ 'eat', 'tea', 'ate' ], [ 'tan', 'nat' ], [ 'bat' ] ] - ``` - - -### Conclusion -Hashing is a fundamental concept in computer science that allows for efficient data retrieval and storage. Hash maps, which leverage hashing, provide an optimal way to manage key-value pairs. Understanding these concepts and their applications is essential for solving various algorithmic challenges, particularly in competitive programming and real-world applications. diff --git a/docs/Jump Search/Jump Search.md b/docs/Jump Search/Jump Search.md deleted file mode 100644 index 61e316f00..000000000 --- a/docs/Jump Search/Jump Search.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -id: jump-search -title: Jump Search Algorithm -sidebar_label: Jump Search -sidebar_position: 2 -description: "This post explores the use of Jump Search Algorithm. We'll provide code implementations C++." -tags: [searching, algorithms] ---- - -Jump Search is a searching algorithm used to find an element in a sorted array. It works by jumping ahead by a fixed number of steps, rather than checking each element one by one (as in linear search). Once it finds an interval where the target element might be, it performs a linear search within that interval. - -## Key Points: -1) Step Size: We select a fixed jump size, typically the square root of the array length, as a good balance between linear and binary search. -2) Process: Jump by this fixed step size until the next jump goes past the element or reaches a number greater than the target. -3) Linear Search in Interval: Once the jump overshoots or reaches the interval where the target could lie, it performs a linear search in this smaller interval. - -## Complexity: -Time Complexity: O(n) -Space Complexity: O(1) - -## Steps: -1) Choose a block size (commonly step=array sizestep=array size). -2) Jump forward by this step size until the current element is larger than or equal to the target. -3) If we find the element within the block, perform a linear search in the interval to locate the exact position of the element. - -## Implementation: - - ```C++ - - #include - #include - - using namespace std; - - int jumpSearch(int arr[], int n, int target) { - // Calculate jump size - int step = sqrt(n); - int prev = 0; - - // Find the block where the element is present - while (arr[min(step, n)-1] < target) { - prev = step; - step += sqrt(n); - if (prev >= n) - return -1; // Element is not present - } - - // Perform linear search in the found block - for (int i = prev; i < min(step, n); i++) { - if (arr[i] == target) - return i; // Return index of the target element - } - - return -1; // Element not found - } - - int main() { - int arr[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; - int n = sizeof(arr) / sizeof(arr[0]); - int target = 15; - - int result = jumpSearch(arr, n, target); - if (result != -1) - cout << "Element found at index " << result << endl; - else - cout << "Element not found in the array" << endl; - - return 0; - } -``` - -## Explanation: -1) Step Calculation: We calculate step = sqrt(n) to jump optimally through the array. -2) Jumping: We jump by the step until we reach an element larger than the target or reach the end of the array. -3) Linear Search: Once we find the interval, a linear search in the small block checks for the exact position of the target element. - -This approach is efficient for sorted arrays and falls between linear and binary search in terms of speed. diff --git a/docs/KMP searching pattern/_category_.json b/docs/KMP searching pattern/_category_.json deleted file mode 100644 index c3756603b..000000000 --- a/docs/KMP searching pattern/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "KMP searching pattern", - "position": 5, - "link": { - "type": "generated-index", - "description": "The KMP algorithm is a string searching algorithm that uses a prefix table to skip over unnecessary comparisons when searching for a pattern in a text." - } -} diff --git a/docs/KMP searching pattern/readme.md b/docs/KMP searching pattern/readme.md deleted file mode 100644 index c679d7cc1..000000000 --- a/docs/KMP searching pattern/readme.md +++ /dev/null @@ -1,354 +0,0 @@ ---- -id: kmp-searching-pattern -title: KMP Pattern Searching Algorithm - Complete Guide -sidebar_label: KMP Pattern Searching -description: A comprehensive guide to the Knuth-Morris-Pratt (KMP) string matching algorithm, including theory, analysis, and implementations in multiple languages -tags: [Algorithms, String Matching, Pattern Searching, Dynamic Programming] ---- - -# 🔍 KMP (Knuth-Morris-Pratt) Pattern Searching Algorithm - -## 📚 Introduction - -The Knuth-Morris-Pratt (KMP) algorithm is an efficient string-matching algorithm that searches for occurrences of a "word" W within a main "text string" S. Unlike naive approaches, it achieves linear time complexity by utilizing pattern information to avoid unnecessary comparisons. - -## ⭐ Key Features - -- 🚀 Time Complexity: O(n + m) where n is text length and m is pattern length -- 💾 Space Complexity: O(m) for pattern preprocessing -- 🎯 Efficient for patterns with repeating characters -- 🔄 No backtracking in the main text string - -## 🛠️ How It Works - -### Algorithm Overview - -The key insight of KMP is that when a mismatch occurs, the pattern's structure can determine where to continue the search, rather than starting over. This is achieved through two main phases: - -1. **Preprocessing Phase**: - - Create a Longest Proper Prefix which is also Suffix (LPS) array - - This array helps skip unnecessary comparisons - -2. **Searching Phase**: - - Use the LPS array to efficiently find pattern matches - - Avoid re-examining previously matched characters - -### LPS Array Explanation - -The LPS array stores the lengths of the longest proper prefix that is also a suffix for each position in the pattern. - -Example: -``` -Pattern: "AAACAAAA" -LPS: [0,1,2,0,1,2,3,3] -``` - -## 💻 Multi-Language Implementations - -### Python Implementation - -```python -class KMPMatcher: - def __init__(self, pattern: str): - """ - Initialize KMP matcher with a pattern. - - Args: - pattern: The pattern string to search for - """ - self.pattern = pattern - self.partial_match_table = self._build_partial_match_table() - - def _build_partial_match_table(self) -> list[int]: - """ - Build the partial match table (failure function) for the pattern. - - Returns: - List of integers representing the partial match values - """ - table = [0] * len(self.pattern) - length = 0 - i = 1 - - while i < len(self.pattern): - if self.pattern[i] == self.pattern[length]: - length += 1 - table[i] = length - i += 1 - else: - if length != 0: - length = table[length - 1] - else: - table[i] = 0 - i += 1 - - return table - - def search(self, text: str) -> list[int]: - """ - Find all occurrences of the pattern in the given text. - - Args: - text: The text string to search in - - Returns: - List of starting indices where the pattern was found - """ - if not self.pattern or not text: - return [] - - matches = [] - j = 0 # Pattern index - i = 0 # Text index - - while i < len(text): - if self.pattern[j] == text[i]: - i += 1 - j += 1 - - if j == len(self.pattern): - matches.append(i - j) - j = self.partial_match_table[j - 1] - else: - if j != 0: - j = self.partial_match_table[j - 1] - else: - i += 1 - - return matches -``` - -### C++ Implementation - -```cpp -#include -#include -#include - -class KMPMatcher { -private: - std::string pattern; - std::vector partial_match_table; - - std::vector buildPartialMatchTable() { - std::vector table(pattern.length(), 0); - int length = 0; - int i = 1; - - while (i < pattern.length()) { - if (pattern[i] == pattern[length]) { - ++length; - table[i] = length; - ++i; - } else { - if (length != 0) { - length = table[length - 1]; - } else { - table[i] = 0; - ++i; - } - } - } - - return table; - } - -public: - explicit KMPMatcher(std::string_view pat) - : pattern(pat) - , partial_match_table(buildPartialMatchTable()) {} - - std::vector search(std::string_view text) const { - std::vector matches; - if (pattern.empty() || text.empty()) { - return matches; - } - - int j = 0; // Pattern index - int i = 0; // Text index - - while (i < text.length()) { - if (pattern[j] == text[i]) { - ++i; - ++j; - - if (j == pattern.length()) { - matches.push_back(i - j); - j = partial_match_table[j - 1]; - } - } else { - if (j != 0) { - j = partial_match_table[j - 1]; - } else { - ++i; - } - } - } - - return matches; - } -}; -``` - -### Java Implementation - -```java -import java.util.ArrayList; -import java.util.List; - -public class KMPMatcher { - private final String pattern; - private final int[] partialMatchTable; - - public KMPMatcher(String pattern) { - this.pattern = pattern; - this.partialMatchTable = buildPartialMatchTable(); - } - - private int[] buildPartialMatchTable() { - int[] table = new int[pattern.length()]; - int length = 0; - int i = 1; - - while (i < pattern.length()) { - if (pattern.charAt(i) == pattern.charAt(length)) { - length++; - table[i] = length; - i++; - } else { - if (length != 0) { - length = table[length - 1]; - } else { - table[i] = 0; - i++; - } - } - } - - return table; - } - - public List search(String text) { - List matches = new ArrayList<>(); - - if (pattern.isEmpty() || text.isEmpty()) { - return matches; - } - - int j = 0; // Pattern index - int i = 0; // Text index - - while (i < text.length()) { - if (pattern.charAt(j) == text.charAt(i)) { - i++; - j++; - - if (j == pattern.length()) { - matches.add(i - j); - j = partialMatchTable[j - 1]; - } - } else { - if (j != 0) { - j = partialMatchTable[j - 1]; - } else { - i++; - } - } - } - - return matches; - } -} -``` - -## 🎯 Usage Examples - -### Basic Usage -```python -# Python example -matcher = KMPMatcher("ABAB") -text = "ABABCABABABD" -matches = matcher.search(text) -print(f"Pattern found at indices: {matches}") # Output: [0, 6] -``` - -### Step-by-Step Example - -Let's walk through how KMP processes a simple example: -``` -Text: ABABCABAB -Pattern: ABAB - -Step 1: Build partial match table for pattern -Pattern: A B A B -Table: [0, 0, 1, 2] - -Step 2: Search process -1. ABABCABAB (match at index 0) - ABAB - ✓✓✓✓ - -2. ABABCABAB (attempt at index 2, using partial match table) - ABAB - ✓✓✓✓ - -3. ABABCABAB (match at index 5) - ABAB - ✓✓✓✓ -``` - -## 🚨 Common Pitfalls and Solutions - -1. **Empty String Handling** - ```python - def search(self, text: str) -> list[int]: - if not self.pattern or not text: - return [] # Handle empty strings gracefully - ``` - -2. **Pattern Longer Than Text** - ```python - def search(self, text: str) -> list[int]: - if len(self.pattern) > len(text): - return [] # Pattern can't be found in shorter text - ``` - -3. **Case Sensitivity** - ```python - def case_insensitive_search(self, text: str) -> list[int]: - return self.search(text.lower()) # Convert both to same case - ``` - -## ✨ Best Practices - -1. **Input Validation** - - Always validate input strings - - Handle edge cases gracefully - - Document expected behavior - -2. **Memory Efficiency** - - Reuse partial match table for multiple searches - - Use appropriate data structures for your language - - Consider memory constraints for large texts - -3. **Performance Optimization** - - Use built-in string methods for very short patterns - - Consider streaming for large texts - - Profile your specific use case - -## 🔗 Applications - -1. **Text Editors** - - Find and replace functionality - - Search highlighting - - Code completion - -2. **Bioinformatics** - - DNA sequence matching - - Protein pattern recognition - - Genome analysis - -3. **Network Security** - - Intrusion detection - - Pattern matching in network packets - - Malware signature detection diff --git a/docs/Number theory/GCD.md b/docs/Number theory/GCD.md deleted file mode 100644 index ee18554a1..000000000 --- a/docs/Number theory/GCD.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -id: GCD -title: "GCD Algorithm" -sidebar_label: "GCD" -sidebar_position: 9 -description: "A detailed guide to understanding and implementing the GCD (Greatest Common Divisor) Algorithm in Number Theory." -tags: [gcd, number theory, competitive programming] ---- - -# GCD Algorithm in Number Theory - -## Definition: - -The **GCD (Greatest Common Divisor)** of two integers is the largest positive integer that divides both of them without leaving a remainder. The GCD is widely used in number theory and has applications in fractions, simplifying ratios, and solving problems involving divisibility. - -## Explanation: - -Given two integers `a` and `b`, the GCD can be computed efficiently using **Euclid's Algorithm**. This algorithm is based on the observation that the GCD of two numbers also divides their difference. The process continues by replacing the larger number with the remainder of dividing the two numbers, until one of the numbers becomes zero. The other number at that point is the GCD. - -### Euclid's Algorithm for GCD: - -Euclid’s algorithm states that: -$\text{gcd}(a, b) = \text{gcd}(b,a\mod b)$ - -Where `%` is the modulus operator, and the process continues until `b == 0`. - -The final value of `a` will be the GCD. - -## Code - -### Code Implementation (Python): - -```python -def gcd(a, b): - """Computes the GCD of two numbers using Euclid's Algorithm. - - Args: - a: First number. - b: Second number. - - Returns: - The greatest common divisor (GCD) of the two numbers. - """ - while b != 0: - a, b = b, a % b - return a - -# Example Usage: -a = 56 -b = 98 -result = gcd(a, b) -print(f"The GCD of {a} and {b} is {result}") -``` - -### Code Implementation (C++): - -```cpp -#include -using namespace std; - -int gcd(int a, int b) { - // Using Euclid's Algorithm to find the GCD - while (b != 0) { - int temp = b; - b = a % b; - a = temp; - } - return a; -} - -int main() { - int a = 56, b = 98; - cout << "The GCD of " << a << " and " << b << " is " << gcd(a, b) << endl; - return 0; -} -``` - -### Code Implementation (Java): - -```java -public class GCDAlgorithm { - - public static int gcd(int a, int b) { - // Using Euclid's Algorithm to find the GCD - while (b != 0) { - int temp = b; - b = a % b; - a = temp; - } - return a; - } - - public static void main(String[] args) { - int a = 56; - int b = 98; - System.out.println("The GCD of " + a + " and " + b + " is " + gcd(a, b)); - } -} -``` - -## Explanation of the Code: - -- **gcd function:** This function computes the GCD of two numbers by repeatedly applying the modulus operation until one of the numbers becomes zero. The non-zero number at that point is the GCD. - -### Example Usage: - -For the numbers `a = 56` and `b = 98`, the output will be: -``` -The GCD of 56 and 98 is 14 -``` - -## Recursive Implementation: - -Euclid's algorithm can also be implemented recursively. Here is an example of the recursive approach: - -### Recursive Code (Python): - -```python -def gcd_recursive(a, b): - """Computes the GCD of two numbers using the recursive method. - - Args: - a: First number. - b: Second number. - - Returns: - The greatest common divisor (GCD) of the two numbers. - """ - if b == 0: - return a - return gcd_recursive(b, a % b) - -# Example Usage: -a = 56 -b = 98 -result = gcd_recursive(a, b) -print(f"The GCD of {a} and {b} is {result}") -``` - -### Recursive Code (C++): - -```cpp -#include -using namespace std; - -int gcd_recursive(int a, int b) { - // Using recursive approach to find the GCD - if (b == 0) - return a; - return gcd_recursive(b, a % b); -} - -int main() { - int a = 56, b = 98; - cout << "The GCD of " << a << " and " << b << " is " << gcd_recursive(a, b) << endl; - return 0; -} -``` - -### Recursive Code (Java): - -```java -public class GCDRecursive { - - public static int gcd_recursive(int a, int b) { - // Using recursive approach to find the GCD - if (b == 0) { - return a; - } - return gcd_recursive(b, a % b); - } - - public static void main(String[] args) { - int a = 56; - int b = 98; - System.out.println("The GCD of " + a + " and " + b + " is " + gcd_recursive(a, b)); - } -} -``` - -## Applications in Competitive Programming: - -The GCD algorithm is widely used in competitive programming and number theory problems due to its efficiency in solving various problems related to divisibility and fractions. - -### Common Applications: - -1. **Simplifying Fractions**: - You can use GCD to reduce fractions to their simplest form. - -2. **LCM (Least Common Multiple)**: - GCD is often used to compute LCM. The relation between GCD and LCM is: - $\text{LCM}(a, b) = \frac{|a \cdot b|}{\text{GCD}(a, b)}$ - - -3. **Solving Diophantine Equations**: - GCD is used in algorithms related to solving linear Diophantine equations of the form `ax + by = gcd(a, b)`. - -### Example Problem: - -Given two integers `a = 56` and `b = 98`, compute their GCD using Euclid's algorithm: -``` -GCD(56, 98) = 14 -``` - -## Time Complexity: - -The time complexity of the Euclidean algorithm is `O(log(min(a, b)))`, making it highly efficient for computing GCD even for large numbers. - -## Conclusion: - -The GCD algorithm is a fundamental tool in number theory with applications in various fields like cryptography, computer algorithms, and mathematics. Euclid's algorithm provides an efficient way to compute the GCD, making it a crucial concept for competitive programmers. - diff --git a/docs/Number theory/LCM.md b/docs/Number theory/LCM.md deleted file mode 100644 index 7e70cb2a3..000000000 --- a/docs/Number theory/LCM.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -id: LCM -title: "LCM Algorithm" -sidebar_label: "LCM" -sidebar_position: 10 -description: "A detailed guide to understanding and implementing the LCM (Least Common Multiple) Algorithm in Number Theory." -tags: [lcm, number theory, competitive programming] ---- - -# LCM Algorithm in Number Theory - -## Definition: - -The **LCM (Least Common Multiple)** of two integers is the smallest positive integer that is divisible by both numbers. It is commonly used in problems involving multiple periods, cycles, or when finding a common denominator for fractions. - -## Explanation: - -The relationship between **LCM** and **GCD (Greatest Common Divisor)** is a key concept in number theory. Given two integers `a` and `b`, the LCM can be computed using the formula: -$\text{LCM}(a, b) = \frac{|a \cdot b|}{\text{GCD}(a, b)}$ - -This formula leverages the fact that the product of the LCM and GCD of two numbers is equal to the product of the numbers themselves. - -## Code - -### Code Implementation (Python): - -```python -def gcd(a, b): - """Helper function to compute the GCD using Euclid's Algorithm.""" - while b != 0: - a, b = b, a % b - return a - -def lcm(a, b): - """Computes the LCM of two numbers. - - Args: - a: First number. - b: Second number. - - Returns: - The least common multiple (LCM) of the two numbers. - """ - return abs(a * b) // gcd(a, b) - -# Example Usage: -a = 12 -b = 18 -result = lcm(a, b) -print(f"The LCM of {a} and {b} is {result}") -``` - -### Code Implementation (C++): - -```cpp -#include -using namespace std; - -int gcd(int a, int b) { - // Using Euclid's Algorithm to find the GCD - while (b != 0) { - int temp = b; - b = a % b; - a = temp; - } - return a; -} - -int lcm(int a, int b) { - // Using the relation LCM * GCD = a * b - return abs(a * b) / gcd(a, b); -} - -int main() { - int a = 12, b = 18; - cout << "The LCM of " << a << " and " << b << " is " << lcm(a, b) << endl; - return 0; -} -``` - -### Code Implementation (Java): - -```java -public class LCMAlgorithm { - - public static int gcd(int a, int b) { - // Using Euclid's Algorithm to find the GCD - while (b != 0) { - int temp = b; - b = a % b; - a = temp; - } - return a; - } - - public static int lcm(int a, int b) { - // Using the relation LCM * GCD = a * b - return Math.abs(a * b) / gcd(a, b); - } - - public static void main(String[] args) { - int a = 12; - int b = 18; - System.out.println("The LCM of " + a + " and " + b + " is " + lcm(a, b)); - } -} -``` - -## Explanation of the Code: - -- **gcd function:** A helper function that computes the GCD using Euclid's algorithm. -- **lcm function:** This function calculates the LCM by using the relationship between LCM and GCD. It returns the smallest positive integer that is divisible by both numbers. - -### Example Usage: - -For the numbers `a = 12` and `b = 18`, the output will be: -``` -The LCM of 12 and 18 is 36 -``` - -## Recursive Implementation: - -Like the GCD algorithm, the LCM can also be computed using a recursive approach to calculate the GCD. - -### Recursive Code (Python): - -```python -def gcd_recursive(a, b): - """Computes the GCD of two numbers using the recursive method.""" - if b == 0: - return a - return gcd_recursive(b, a % b) - -def lcm(a, b): - """Computes the LCM of two numbers.""" - return abs(a * b) // gcd_recursive(a, b) - -# Example Usage: -a = 12 -b = 18 -result = lcm(a, b) -print(f"The LCM of {a} and {b} is {result}") -``` - -### Recursive Code (C++): - -```cpp -#include -using namespace std; - -int gcd_recursive(int a, int b) { - // Recursive approach to find the GCD - if (b == 0) - return a; - return gcd_recursive(b, a % b); -} - -int lcm(int a, int b) { - return abs(a * b) / gcd_recursive(a, b); -} - -int main() { - int a = 12, b = 18; - cout << "The LCM of " << a << " and " << b << " is " << lcm(a, b) << endl; - return 0; -} -``` - -### Recursive Code (Java): - -```java -public class LCMRecursive { - - public static int gcd_recursive(int a, int b) { - // Recursive approach to find the GCD - if (b == 0) { - return a; - } - return gcd_recursive(b, a % b); - } - - public static int lcm(int a, int b) { - return Math.abs(a * b) / gcd_recursive(a, b); - } - - public static void main(String[] args) { - int a = 12; - int b = 18; - System.out.println("The LCM of " + a + " and " + b + " is " + lcm(a, b)); - } -} -``` - -## Applications in Competitive Programming: - -The LCM algorithm is frequently used in competitive programming and mathematics problems that involve periodicity, synchronization, or finding common multiples. - -### Common Applications: - -1. **Finding Common Denominators**: - LCM is useful in adding fractions where you need to find a common denominator. - -2. **Scheduling Problems**: - In problems involving periodic events, the LCM can be used to find the point in time when the events coincide. - -3. **LCM of Multiple Numbers**: - To compute the LCM of multiple numbers, you can apply the formula pairwise: -$\text{LCM}(a_1, a_2, \ldots, a_n) = \text{LCM}(\text{LCM}(a_1, a_2), a_3, \ldots, a_n)$ - -### Example Problem: - -Given two integers `a = 12` and `b = 18`, compute their LCM using the LCM-GCD relationship: -``` -LCM(12, 18) = 36 -``` - -## Time Complexity: - -The time complexity of the LCM algorithm depends on the GCD computation, which is `O(log(min(a, b)))`. Thus, the LCM algorithm has a time complexity of `O(log(min(a, b)))`, making it very efficient even for large numbers. - -## Conclusion: - -The LCM algorithm is a fundamental concept in number theory with a wide range of applications. Using the relation between GCD and LCM, we can efficiently compute the least common multiple of two or more numbers, making it a powerful tool for both competitive programming and practical problem-solving. - diff --git a/docs/Number theory/sieve-of-eratosthenes.md b/docs/Number theory/sieve-of-eratosthenes.md deleted file mode 100644 index 688da0c86..000000000 --- a/docs/Number theory/sieve-of-eratosthenes.md +++ /dev/null @@ -1,216 +0,0 @@ ---- -id: sieve-of-eratosthenes -title: "Sieve of Eratosthenes" -sidebar_label: "Sieve of Eratosthenes" -sidebar_position: 11 -description: "A complete guide to understanding and implementing the Sieve of Eratosthenes for finding prime numbers." -tags: [prime numbers, number theory, sieve, competitive programming] ---- - -# Sieve of Eratosthenes - -## Definition: - -The **Sieve of Eratosthenes** is an efficient algorithm for finding all prime numbers up to a given limit `n`. It works by iteratively marking the multiples of each prime starting from 2, the first prime number. The algorithm runs in `O(n log log n)` time, making it much faster than checking each number individually for primality. - -## Explanation: - -The algorithm works by maintaining an array of boolean values where each index represents a number, and the value is `True` if the number is prime and `False` if it is not. It starts with the first prime (2) and marks all of its multiples as non-prime. Then it moves to the next number, and if it's still marked as prime, it marks all of its multiples, and so on, up to the square root of `n`. - -### Steps: - -1. Create a list `is_prime` of size `n + 1`, where each index represents whether the number is prime. -2. Set all values to `True`, except for `is_prime[0]` and `is_prime[1]` (since 0 and 1 are not prime). -3. Start from the first prime number (2). For each prime number, mark all of its multiples as `False` (not prime). -4. Repeat the process for the next number that is still marked as prime. -5. The algorithm stops when all numbers up to √n have been processed. - -## Code - -### Code Implementation (Python): - -```python -def sieve_of_eratosthenes(n): - """Finds all prime numbers up to n using the Sieve of Eratosthenes. - - Args: - n: The upper limit to find primes up to. - - Returns: - A list of all prime numbers up to n. - """ - is_prime = [True] * (n + 1) - is_prime[0] = is_prime[1] = False # 0 and 1 are not primes - - for i in range(2, int(n**0.5) + 1): - if is_prime[i]: - for j in range(i * i, n + 1, i): - is_prime[j] = False - - primes = [i for i in range(2, n + 1) if is_prime[i]] - return primes - -# Example Usage: -n = 30 -primes = sieve_of_eratosthenes(n) -print(f"Prime numbers up to {n}: {primes}") -``` - -### Code Implementation (C++): - -```cpp -#include -#include -using namespace std; - -vector sieve_of_eratosthenes(int n) { - vector is_prime(n + 1, true); - is_prime[0] = is_prime[1] = false; // 0 and 1 are not prime - - for (int i = 2; i * i <= n; i++) { - if (is_prime[i]) { - for (int j = i * i; j <= n; j += i) { - is_prime[j] = false; - } - } - } - - vector primes; - for (int i = 2; i <= n; i++) { - if (is_prime[i]) { - primes.push_back(i); - } - } - - return primes; -} - -int main() { - int n = 30; - vector primes = sieve_of_eratosthenes(n); - - cout << "Prime numbers up to " << n << ": "; - for (int prime : primes) { - cout << prime << " "; - } - cout << endl; - - return 0; -} -``` - -### Code Implementation (Java): - -```java -import java.util.*; - -public class SieveOfEratosthenes { - - public static List sieve_of_eratosthenes(int n) { - boolean[] is_prime = new boolean[n + 1]; - Arrays.fill(is_prime, true); - is_prime[0] = is_prime[1] = false; // 0 and 1 are not primes - - for (int i = 2; i * i <= n; i++) { - if (is_prime[i]) { - for (int j = i * i; j <= n; j += i) { - is_prime[j] = false; - } - } - } - - List primes = new ArrayList<>(); - for (int i = 2; i <= n; i++) { - if (is_prime[i]) { - primes.add(i); - } - } - - return primes; - } - - public static void main(String[] args) { - int n = 30; - List primes = sieve_of_eratosthenes(n); - - System.out.println("Prime numbers up to " + n + ": " + primes); - } -} -``` - -## Explanation of the Code: - -- **is_prime array:** This array tracks whether each number up to `n` is prime. -- **Sieve process:** For each number `i`, if `is_prime[i]` is still `True`, mark all multiples of `i` as `False` since they are not prime. -- **Result:** After the sieve process is completed, any index `i` in the `is_prime` array that remains `True` is a prime number. - -### Example Usage: - -For `n = 30`, the output will be: -``` -Prime numbers up to 30: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] -``` - -## Optimized Version (Skipping Even Numbers): - -You can further optimize the algorithm by skipping even numbers after marking 2 as prime, thus reducing the number of iterations. - -### Optimized Code (Python): - -```python -def sieve_of_eratosthenes_optimized(n): - """Optimized Sieve that skips even numbers.""" - if n < 2: - return [] - - is_prime = [True] * (n + 1) - is_prime[0] = is_prime[1] = False - primes = [2] # Start with 2, the first prime number - - for i in range(3, int(n**0.5) + 1, 2): - if is_prime[i]: - for j in range(i * i, n + 1, i * 2): - is_prime[j] = False - - primes.extend([i for i in range(3, n + 1, 2) if is_prime[i]]) - return primes - -# Example Usage: -n = 30 -primes = sieve_of_eratosthenes_optimized(n) -print(f"Optimized prime numbers up to {n}: {primes}") -``` - -## Time Complexity: - -The time complexity of the **Sieve of Eratosthenes** is `O(n log log n)`, which is very efficient for generating prime numbers up to a large limit. This is due to the fact that each prime number marks its multiples only once. - -## Space Complexity: - -The space complexity of the algorithm is `O(n)` because it requires an array of size `n + 1` to store whether each number is prime or not. - -## Applications in Competitive Programming: - -The Sieve of Eratosthenes is one of the most commonly used algorithms for generating primes in competitive programming. It is especially useful in problems that require you to work with primes up to a large number `n`. - -### Common Applications: - -1. **Finding All Primes in a Range**: - Sieve is perfect for problems where you need to generate all primes up to a certain number, as it does so in an optimized manner. - -2. **Prime Factorization**: - By precomputing the primes, you can quickly find the prime factorization of numbers using trial division. - -3. **Finding the Number of Divisors**: - With a list of primes, you can efficiently compute the number of divisors of a number. - -### Example Problem: - -Given an integer `n = 30`, find all prime numbers up to 30. Using the Sieve of Eratosthenes: -``` -Prime numbers up to 30: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] -``` - -## Conclusion: - -The **Sieve of Eratosthenes** is a fundamental and highly efficient algorithm for finding prime numbers. It has a variety of applications in both theoretical number theory and practical competitive programming problems. Given its simplicity and speed, it's often the go-to algorithm for prime generation. diff --git a/docs/Object Oriented Programming/4-pillars-of-oops.md b/docs/Object Oriented Programming/4-pillars-of-oops.md deleted file mode 100644 index 9ed16e22b..000000000 --- a/docs/Object Oriented Programming/4-pillars-of-oops.md +++ /dev/null @@ -1,355 +0,0 @@ ---- -id: pillars-of-oops -title: "Pillars of OOP: Abstraction, Encapsulation, Inheritance, Polymorphism" -sidebar_label: Pillars of OOP -sidebar_position: 4 -description: "The four main pillars of OOP are abstraction, encapsulation, inheritance, and polymorphism. These principles provide a foundation for creating robust and reusable code in object-oriented systems." -tags: [oops, abstraction, encapsulation, inheritance, polymorphism] ---- - -# **Pillars of OOPs** - -Object-Oriented Programming (OOP) is built on four main pillars: **Abstraction**, **Encapsulation**, **Inheritance**, and **Polymorphism**. Each of these concepts plays a crucial role in creating modular, reusable, and maintainable code. - ---- - -## **1. Abstraction** - -Abstraction is the process of hiding the complex implementation details and showing only the essential features of an object. It allows developers to reduce complexity by providing a simplified interface. - -### **Key Points** -- Focuses on **what** an object does rather than **how** it does it. -- Achieved through abstract classes and interfaces. - -### **Example of Abstraction** - -
-C++ Code - -```cpp -#include -using namespace std; - -class Shape { -public: - virtual void draw() = 0; // Pure virtual function -}; - -class Circle : public Shape { -public: - void draw() { - cout << "Drawing Circle" << endl; - } -}; - -int main() { - Circle circle; - circle.draw(); // Calls the draw method - return 0; -} -``` -
- -
-Java Code - -```java -abstract class Shape { - abstract void draw(); // Abstract method -} - -class Circle extends Shape { - void draw() { - System.out.println("Drawing Circle"); - } -} - -public class Main { - public static void main(String[] args) { - Circle circle = new Circle(); - circle.draw(); // Calls the draw method - } -} -``` -
- ---- - -## **2. Encapsulation** - -Encapsulation is the bundling of data (attributes) and methods (functions) that operate on the data into a single unit called a class. It restricts direct access to some of the object's components, which is a means of preventing unintended interference and misuse. - -### **Key Points** -- Protects an object's state by restricting access to its internal data. -- Achieved using access modifiers (private, protected, public). - -### **Example of Encapsulation** - -
-C++ Code - -```cpp -#include -using namespace std; - -class BankAccount { -private: - double balance; // Private data member - -public: - BankAccount() : balance(0) {} // Constructor - - void deposit(double amount) { - balance += amount; - } - - void displayBalance() { - cout << "Balance: " << balance << endl; - } -}; - -int main() { - BankAccount account; - account.deposit(1000); - account.displayBalance(); // Displays the balance - return 0; -} -``` -
- -
-Java Code - -```java -class BankAccount { - private double balance; // Private data member - - public BankAccount() { - balance = 0; // Constructor - } - - public void deposit(double amount) { - balance += amount; - } - - public void displayBalance() { - System.out.println("Balance: " + balance); - } -} - -public class Main { - public static void main(String[] args) { - BankAccount account = new BankAccount(); - account.deposit(1000); - account.displayBalance(); // Displays the balance - } -} -``` -
- ---- - -## **3. Inheritance** - -Inheritance is a mechanism that allows one class to inherit the properties and behaviors (methods) of another class. It promotes code reusability and establishes a hierarchical relationship between classes. - -### **Key Points** -- The class that inherits is called the **derived class** or **child class**, and the class being inherited from is called the **base class** or **parent class**. -- Supports "is-a" relationship. - -### **Example of Inheritance** - -
-C++ Code - -```cpp -#include -using namespace std; - -class Animal { -public: - void eat() { - cout << "Eating..." << endl; - } -}; - -class Dog : public Animal { // Dog inherits from Animal -public: - void bark() { - cout << "Woof!" << endl; - } -}; - -int main() { - Dog dog; - dog.eat(); // Inherited method - dog.bark(); // Dog's own method - return 0; -} -``` -
- -
-Java Code - -```java -class Animal { - void eat() { - System.out.println("Eating..."); - } -} - -class Dog extends Animal { // Dog inherits from Animal - void bark() { - System.out.println("Woof!"); - } -} - -public class Main { - public static void main(String[] args) { - Dog dog = new Dog(); - dog.eat(); // Inherited method - dog.bark(); // Dog's own method - } -} -``` -
- ---- - -## **4. Polymorphism** - -Polymorphism allows methods to do different things based on the object it is acting upon. It means "many forms" and can be classified into two types: **Compile-time polymorphism** and **Runtime polymorphism**. - -### **4.1 Compile-time Polymorphism** - -Also known as **method overloading**, it occurs when multiple methods in the same class have the same name but different parameters. - -#### **Example of Compile-time Polymorphism** - -
-C++ Code - -```cpp -#include -using namespace std; - -class Math { -public: - int add(int a, int b) { - return a + b; - } - - double add(double a, double b) { - return a + b; - } -}; - -int main() { - Math math; - cout << "Int Addition: " << math.add(5, 10) << endl; // Calls int version - cout << "Double Addition: " << math.add(5.5, 10.5) << endl; // Calls double version - return 0; -} -``` -
- -
-Java Code - -```java -class Math { - int add(int a, int b) { - return a + b; - } - - double add(double a, double b) { - return a + b; - } -} - -public class Main { - public static void main(String[] args) { - Math math = new Math(); - System.out.println("Int Addition: " + math.add(5, 10)); // Calls int version - System.out.println("Double Addition: " + math.add(5.5, 10.5)); // Calls double version - } -} -``` -
- -### **4.2 Runtime Polymorphism** - -Also known as **method overriding**, it occurs when a derived class provides a specific implementation of a method that is already defined in its base class. The decision about which method to call is made at runtime. - -#### **Example of Runtime Polymorphism** - -
-C++ Code - -```cpp -#include -using namespace std; - -class Animal { -public: - virtual void sound() { // Virtual method - cout << "Animal sound" << endl; - } -}; - -class Dog : public Animal { -public: - void sound() override { // Override method - cout << "Woof!" << endl; - } -}; - -int main() { - Animal* animal = new Dog(); // Pointer to base class - animal->sound(); // Calls Dog's sound method - delete animal; - return 0; -} -``` -
- -
-Java Code - -```java -class Animal { - void sound() { // Base class method - System.out.println("Animal sound"); - } -} - -class Dog extends Animal { - void sound() { // Override method - System.out.println("Woof!"); - } -} - -public class Main { - public static void main(String[] args) { - Animal animal = new Dog(); // Reference to base class - animal.sound(); // Calls Dog's sound method - } -} -``` -
- ---- - -### Differences between Compile-time and Runtime Polymorphism - -| **Feature** | **Compile-time Polymorphism** | **Runtime Polymorphism** | -|-------------------------|---------------------------------------------|------------------------------------------| -| **Definition** | Achieved through method overloading. | Achieved through method overriding. | -| **Binding Time** | Resolved during compilation. | Resolved during runtime. | -| **Method Resolution** | The compiler determines which method to call. | The JVM determines which method to call. | -| **Performance** | Generally faster due to early binding. | Slightly slower due to late binding. | -| **Flexibility** | Less flexible as the decision is made at compile time. | More flexible as the decision is made at runtime. | -| **Example** | Overloading methods with different parameters. | Overriding a method in a derived class. | - ---- diff --git a/docs/Object Oriented Programming/ApplicationofOOPS.md b/docs/Object Oriented Programming/ApplicationofOOPS.md deleted file mode 100644 index 122c1f357..000000000 --- a/docs/Object Oriented Programming/ApplicationofOOPS.md +++ /dev/null @@ -1,156 +0,0 @@ ---- - -id: applicationsofoops -title: "Applications of OOP in Real-Time Software" -sidebar_label: Applications of OOP -sidebar_position: 1 -description: "This document explains how to use Object-Oriented Programming (OOP) concepts to build real-time software applications, focusing on an Online Banking System." -tags: [oops, applications, software] - ---- - -### Applications of OOP in Real-Time Software -**I am going to tell you how to use OOP concepts to build real-time software applications, particularly an Online Banking System. OOP helps in structuring the code, making it modular, and enhancing reusability and maintainability.** - -### OOP Concepts Used - -**Encapsulation:** Protects data by restricting direct access to it and exposing only necessary methods. -**Inheritance:** Allows the creation of a new class based on an existing class, promoting code reusability. -**Polymorphism:** Enables methods to do different things based on the object calling them. - -### Building an Online Banking System -**1. User Class** -The User class handles user registration and login functionality. - -```cpp -class User { -private: - string name; - string userID; - string password; - -public: - void registerUser(string userName, string userPassword) { - name = userName; - userID = generateUserID(); // Generate a unique user ID - password = userPassword; - // Logic to store user data in a database - } - - bool login(string userPassword) { - return password == userPassword; // Validate password - } -}; -``` - -**2. Account Class** -The Account class manages the bank account operations such as deposits and withdrawals. - -```cpp - -class Account { -private: - string accountNumber; - double balance; - string accountType; - -public: - Account(string type) : accountType(type), balance(0.0) { - accountNumber = generateAccountNumber(); // Generate a unique account number - } - - void deposit(double amount) { - balance += amount; // Add to balance - // Logic to record the transaction - } - - bool withdraw(double amount) { - if (amount <= balance) { - balance -= amount; // Deduct from balance - // Logic to record the transaction - return true; // Withdrawal successful - } - return false; // Insufficient funds - } - - double checkBalance() { - return balance; // Return current balance - } -}; -``` - -**3. Transaction Class** -The Transaction class records transaction details. - -```cpp -class Transaction { -private: - string transactionID; - double amount; - string transactionType; - string date; - -public: - void recordTransaction(string type, double amt) { - transactionType = type; - amount = amt; - date = getCurrentDate(); // Get the current date - // Logic to store transaction details - } -}; -``` - -**4. Admin Class (Optional)** -The Admin class can manage user accounts and system-level operations. - -```cpp -class Admin { -public: - void viewAllUsers() { - // Logic to retrieve and display all users - } - - void deleteUser(string userID) { - // Logic to delete a user by ID - } -}; -``` - -**Example Usage** -User Registration and Login - -```cpp -User user; -user.registerUser("Alice", "strongPassword123"); - -if (user.login("strongPassword123")) { - cout << "Login successful!" << endl; -} else { - cout << "Invalid credentials." << endl; -} -``` - -**Account Operations** - -```cpp -Account savingsAccount("Savings"); -savingsAccount.deposit(1000.0); - -if (savingsAccount.withdraw(300.0)) { - cout << "Withdrawal successful!" << endl; -} else { - cout << "Insufficient funds." << endl; -} - -cout << "Current Balance: $" << savingsAccount.checkBalance() << endl; -``` - -**Transaction Management** -```cpp -Transaction transaction; -transaction.recordTransaction("Deposit", 1000.0); -transaction.recordTransaction("Withdrawal", 300.0); -``` - -### Conclusion -By applying OOP principles, the Online Banking System can be developed in a structured manner, allowing for easy maintenance and scalability. Each class encapsulates its functionality, enhancing code reusability. You can extend this system further with features like multi-currency support, enhanced security measures, or a user-friendly interface. diff --git a/docs/Object Oriented Programming/Polymorphism.md b/docs/Object Oriented Programming/Polymorphism.md deleted file mode 100644 index f77c33152..000000000 --- a/docs/Object Oriented Programming/Polymorphism.md +++ /dev/null @@ -1,625 +0,0 @@ ---- -id: Polymorphism -title: "Polymorphism in Object-Oriented Programming" -sidebar_label: "Generate Details about Polymorphism" -description: " -Polymorphism is a core concept in object-oriented programming that allows objects of different classes to be treated as instances of the same class through a shared interface" -tags: [Polymorphism, OOPS, Java] ---- - -## Polymorphism - - -Polymorphism is a core concept in object-oriented programming that allows objects of different classes to be treated as instances of the same class through a shared interface. Derived from the Greek words "poly" (meaning "many") and "morph" (meaning "forms"), polymorphism enables a single function, method, or operator to behave differently based on the input object type. There are two primary types of polymorphism: compile-time polymorphism (or method overloading) and runtime polymorphism (or method overriding). Compile-time polymorphism is determined during program compilation, whereas runtime polymorphism is resolved during execution, making it adaptable to various object behaviors. - -Refers to the ability of OOPs programming languages to differentiate between entities with the same name efficiently. This is done by Java with the help of the signature and declaration of these entities. - -Polymorphism in Java are mainly of 2 types: - -### Overloading (Compile time Polymorphism) - -Overloading allows different methods to have the same name, but different signatures where the signature can differ by the number of input parameters or type of input parameters or both. Overloading is related to compile-time (or static) polymorphism. - -It is also known as static polymorphism. This type of polymorphism is achieved by function overloading or operator overloading. - -Method Overloading: When there are multiple functions with same name but different parameters then these functions are said to be overloaded. Functions can be overloaded by change in number of arguments or/and change in type of arguments. - -Operator Overloading: Java also provide option to overload operators. For example, we can make the operator (‘+’) for string class to concatenate two strings. We know that this is the addition operator whose task is to add two operands. So a single operator ‘+’ when placed between integer operands, adds them and when placed between string operands, concatenates them. -In java, Only “+” operator can be overloaded: - -- To add integers -- To concatenate strings - - -There are two ways to overload the method in java - -- By changing number of arguments -- By changing the data type - - - **Method Overloading: changing no. of arguments** - - -### Overriding (Runtime Polymorphism) -It is also known as Dynamic Method Dispatch. It is a process in which a function call to the overridden method is resolved at Runtime. This type of polymorphism is achieved by Method Overriding. - -Method overriding, on the other hand, occurs when a derived class has a definition for one of the member functions of the base class. That base function is said to be overridden. - -In any object-oriented programming language, Overriding is a feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its super-classes or parent classes. When a method in a subclass has the same name, same parameters or signature and same return type(or sub-type) as a method in its super-class, then the method in the subclass is said to override the method in the super-class. - -In other words, If a subclass provides the specific implementation of the method that has been declared by one of its parent class, it is known as method overriding. - -Usage -- Method overriding is used to provide the specific implementation of a method which is already provided by its superclass. -- Method overriding is used for runtime polymorphism - -Rules -- The method must have the same name as in the parent class -- The method must have the same parameter as in the parent class. -- There must be an IS-A relationship (inheritance). - -Example -```java -class Vehicle{ - //defining a method - void run(){ - System.out.println("Vehicle is running"); - } -} - -class Bike2 extends Vehicle{ - void run(){ - System.out.println("Bike is running"); - } - - public static void main(String args[]){ - Bike2 obj = new Bike2(); - obj.run(); - } -} - -``` - -``` -Output: - -Bike is running -``` - -Can we override static method? -No, a static method cannot be overridden. It can be proved by runtime polymorphism, so we will learn it later, It is because the static method is bound with class whereas instance method is bound with an object. Static belongs to the class area, and an instance belongs to the heap area. - -| Parameter | Method Overloading | Method Overriding | -|---|---|---| -| Polymorphism | Method Overloading is used to implement Compile time or static polymorphism. | Method Overriding is used to implement Runtime or dynamic polymorphism.| -| Purpose| It is used to expand the readability of the program. | It is used to give the specific implementation of the method which is already provided by its base class| -| Parameter List | Parameters of the overloaded function must be different in either number or type in case of method overloading | The number of parameters and type of each parameter must be the same in case of method overriding.| -| Number of Classes | It occurs within the same class | It is performed within two classes with an inheritance relationship.| -| Inheritance | It may or may not be required for Method Overloading | It is must for Method Overriding | -| Return Type | The return type may or may not be the same, but we have to change the parameter. | Here, the return type must be either the same or of the covariant type.| -|static, final and private methods | We can overload a static, final or private method in Method Overloading | We can not override a static, final or private method in Method Overriding| -| Bond | Static Binding Dynamic Binding | -| Speed | It is fast | It is slower | -| Signature | The signature must be different | The signature must be the same | -| Association | It is usually associated with static programs. | It is usually associated with object-oriented programs.| -| Performance Overloading gives better performance than overriding | Lesser Performance than Overloading because the binding of the overridden method is done at the runtime.| -| Access Modifier Any access modifier can be used while overloading the methods | The level of access should be either the same or with a wider scope. | -| Exceptions | May throw different exceptions. | May reduce or eliminate exceptions. But, must not throw new or broader checked exceptions but can throw narrower checked exceptions.| - -## super - -The super keyword in Java is a reference variable which is used to refer immediate parent class object. - -Whenever you create the instance of subclass, an instance of parent class is created implicitly which is referred by super reference variable. - -Usage -- **super** can be used to refer immediate parent class instance variable. -- **super** can be used to invoke immediate parent class method. -- **super()** can be used to invoke immediate parent class constructor. - -**(super) used to refer immediate parent class instance variable.** - -We can use super keyword to access the data member or field of parent class. It is used if parent class and child class have same fields. - -```java -class Animal{ - String color="white"; - } - - class Dog extends Animal{ - String color="black"; - void printColor(){ - System.out.println(color);//prints color of Dog class - System.out.println(super.color);//prints color of Animal class - } - } - - class TestSuper1 { - public static void main(String args[]){ - Dog d=new Dog(); - d.printColor(); - } -} -``` - -``` -Output: - -black -white -``` - -In the above example, Animal and Dog both classes have a common property color. If we print color property, it will print the color of current class by default. To access the parent property, we need to use super keyword. - -**(super) can be used to invoke parent class method** - -The super keyword can also be used to invoke parent class method. It should be used if subclass contains the same method as parent class. In other words, it is used if method is overridden. - -```java -class Animal{ - void eat(){System.out.println("eating...");} -} - -class Dog extends Animal{ - void eat(){System.out.println("eating bread...");} - void bark(){System.out.println("barking...");} - void work(){ - super.eat(); - bark(); - } - -} - -class TestSuper2{ - public static void main(String args[]){ - Dog d=new Dog(); - d.work(); - } -} -``` - -``` -Output: - -eating... -barking... -``` - -In the above example Animal and Dog both classes have eat() method if we call eat() method from Dog class, it will call the eat() method of Dog class by default because priority is given to local. - -To call the parent class method, we need to use super keyword. - -**(super) is used to invoke parent class constructor.** - -```java -class Animal{ - Animal(){System.out.println("animal is created");} -} - -class Dog extends Animal{ - Dog(){ - super(); - System.out.println("dog is created"); - } -} - -class TestSuper3{ - public static void main(String args[]){ - Dog d = new Dog(); - } -} - -``` - -``` -Output: - -animal is created -dog is created -``` - -```IMPORTANT``` => super() is added in each class constructor automatically by compiler if there is no super() or this(). - -Real example -```java -class Person{ - int id; - String name; - - Person(int id,String name){ - this.id=id; - this.name=name; - } -} -class Emp extends Person{ - float salary; - Emp(int id,String name,float salary){ - super(id,name);//reusing parent constructor - this.salary = salary; - } - void display(){ - System.out.println(id + " " + name + " " + salary); - } -} - -class TestSuper5{ - public static void main(String[] args){ - Emp e1 = new Emp(1,"alejo",45000f); - e1.display(); - } -} - -``` - -``` -Output: - -1 alejo 45000 -``` - -## Instance initializer block - -Instance Initializer block is used to initialize the instance data member. It run each time when object of the class is created. -The initialization of the instance variable can be done directly but there can be performed extra operations while initializing the instance variable in the instance initializer block. - -Example -```java -class Bike{ - int speed; - - Bike(){ - System.out.println("speed is " + speed); - } - - { - speed=100; - } - - public static void main(String args[]){ - Bike7 bike1=new Bike(); - Bike7 bike2=new Bike(); - } -} - -``` - -``` -Output: - -speed is 100 -speed is 100 -``` - - -There are three places in java where you can perform operations: -- method -- constructor -- block - -What is invoked first, instance initializer block or constructor? - -```java -class Bike{ - int speed; - - Bike(){ - System.out.println("constructor is invoked"); - } - - { - System.out.println("instance initializer block invoked"); - } - - public static void main(String args[]){ - Bike bike1=new Bike(); - Bike bike2=new Bike(); - } -} - -``` - -``` -Output: - -instance initializer block invoked -constructor is invoked -instance initializer block invoked -constructor is invoked -``` - -In the above example, it seems that instance initializer block is firstly invoked but NO. Instance initializer block is invoked at the time of object creation. The java compiler copies the instance initializer block in the constructor after the first statement super(). So firstly, constructor is invoked - -```Important``` => The java compiler copies the code of instance initializer block in every constructor. - -```java -class X{ - - X(){ - System.out.println("constructor"); - } - - { - System.out.println("instance initializer block invoked"); - } -} -``` - -compiler - -```java -class X{ - - X(){ - super(); - { - System.out.println("instance initializer block invoked"); - } - System.out.println("constructor"); - } -} -``` - -**Rules** - -- There are mainly three rules for the instance initializer block. They are as follows: -- The instance initializer block is created when instance of the class is created. -- The instance initializer block is invoked after the parent class constructor is invoked (i.e. after super() constructor call). -- The instance initializer block comes in the order in which they appear. - -Example: Program of instance initializer block that is invoked after super() - -```java -class A{ - A(){ - System.out.println("parent class constructor invoked"); - } -} - -class B2 extends A{ - B2(){ - super(); - System.out.println("child class constructor invoked"); - } - - { - System.out.println("instance initializer block is invoked"); - } - - public static void main(String args[]){ - B2 b=new B2(); - } -} - -``` - -``` -Output: - -parent class constructor invoked -instance initializer block is invoked -child class constructor invoked -``` - -## final - -The final keyword in java is used to restrict the user. The java final keyword can be used in many context. Final can be: - -- variable -- method -- class - -The final keyword can be applied with the variables, a final variable that have no value it is called blank final variable or uninitialized final variable. It can be initialized in the constructor only. The blank final variable can be static also which will be initialized in the static block only. We will have detailed learning of these. Let's first learn the basics of final keyword. - -**final variable** - -If you make any variable as final, you cannot change the value of final variable(It will be constant). - - -Example - -```java -class Car{ - final int speedLimit = 90; //final variable - void run(){ - speedLimit=400; - } - public static void main(String args[]){ - Car obj=new Car(); - obj.run(); - } -} - -``` - -``` -Output: - -Compile Time Error -``` - -**final method** - -If you make any method as final, you cannot override it. - -```java -class Car{ - final void run(){ - System.out.println("running"); - } -} - -class Honda extends Car{ - void run(){ - System.out.println("running safely"); - } - - public static void main(String args[]){ - Honda honda= new Honda(); - honda.run(); - } -} -``` - -``` -Output: - -Compile Time Error -``` - -**final class** - -If you make any class as final, you cannot extend it. - -```java -final class Car{} - -class Honda extends Car{ - void run(){ - System.out.println("running safely"); - } - - public static void main(String args[]){ - Honda honda= new Honda(); - honda.run(); - } -} - -``` - -``` -Output: - -Compile Time Error -``` - -## Runtime Polymorphism - -Runtime polymorphism or Dynamic Method Dispatch is a process in which a call to an overridden method is resolved at runtime rather than compile-time. - -In this process, an overridden method is called through the reference variable of a superclass. The determination of the method to be called is based on the object being referred to by the reference variable. - -Let's first understand the upcasting before Runtime Polymorphism. - -Upcasting -If the reference variable of Parent class refers to the object of Child class, it is known as upcasting - -```java -class A{ - -} - -class B extends A{ - -} - -A a =new B(); //upcasting -``` - -Example runtime polymorphism - -```java -class Bike{ - void run(){ - System.out.println("running"); - } -} - -class Splendor extends Bike{ - void run(){ - System.out.println("running safely"); - } - - public static void main(String args[]){ - Bike b = new Splendor(); //upcasting - b.run(); - } -} - -``` - -``` -Output: - -running safely -``` - -Example 2 runtime polymorphism - -```java -class Shape{ - void draw(){ - System.out.println("drawing"); - } -} - -class Rectangle extends Shape{ - void draw(){ - System.out.println("drawing rectangle"); - } -} - -class Circle extends Shape{ - void draw(){ - System.out.println("drawing circle"); - } -} - -class Triangle extends Shape{ - void draw(){ - System.out.println("drawing triangle"); - } -} - -class TestPolymorphism2{ - public static void main(String args[]){ - Shape s; - s = new Rectangle(); - s.draw(); - s = new Circle(); - s.draw(); - s = new Triangle(); - s.draw(); - } -} - -``` - -``` -Output: - -drawing rectangle -drawing circle -drawing triangle -``` - -Example polymorphism with multilevel inheritance - -```java -class Animal{ - void eat(){ - System.out.println("eating"); - } -} - -class Dog extends Animal{ - void eat(){ - System.out.println("eating fruits"); - } -} - -class BabyDog extends Dog{ - void eat(){ - System.out.println("drinking milk"); - } - - public static void main(String args[]){ - Animal a1,a2,a3; - a1 = new Animal(); - a2 = new Dog(); - a3 = new BabyDog(); - a1.eat(); - a2.eat(); - a3.eat(); - } -} -``` diff --git a/docs/Object Oriented Programming/_category_.json b/docs/Object Oriented Programming/_category_.json deleted file mode 100644 index e08a14d81..000000000 --- a/docs/Object Oriented Programming/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Object-Oriented Programming (OOPs) Concepts", - "position": 8, - "link": { - "type": "generated-index", - "description": "Object-Oriented Programming (OOPs) is a programming paradigm based on the concept of objects, which can contain data and code. OOPs promotes the principles of encapsulation, inheritance, polymorphism, and abstraction. It is widely used in modern software development to create modular, reusable, and scalable code, making it easier to maintain and extend applications." - } -} \ No newline at end of file diff --git a/docs/Object Oriented Programming/abstraction.md b/docs/Object Oriented Programming/abstraction.md deleted file mode 100644 index 620d8aa48..000000000 --- a/docs/Object Oriented Programming/abstraction.md +++ /dev/null @@ -1,399 +0,0 @@ ---- -id: abstraction -title: "Abstraction in Object-Oriented Programming" -sidebar_label: "Generate Details about Abstraction" -description: "Abstraction in Java is the process of hiding unnecessary implementation details from the user, focusing on exposing only the essential functionalities" -tags: [Abstraaction, OOPS, Java] ---- - - - -- In simple terms, abstraction “displays” only the relevant attributes of objects and “hides” the unnecessary details. - -- It is the process of hiding internal implementation details from the user and providing only necessary functionality. It removes all non-essential items and shows only important ones to users. - -For example, when we are driving a car, we are only concerned about the basics, such as starting/stopping the car, accelerating/breaking, etc. We are not concerned about how the actual start/stop mechanism or acceleration/brake process works internally. We are just not interested in those details. - -In other words, Abstraction in Java is a technique by which we can hide the data that is not required to a user - -Abstraction forces to use Inheritance - -Example - -In our daily lives, we all use an ATM for cash withdrawals, money transfers, retrieving min-statements, etc. But we don't know internally what things are happening inside ATM when you insert an ATM card for performing any kind of operations. - -## Abstraction in Java - -There are two ways to achieve abstraction in Java. They are as follows: -* 1. Abstract class (0 to 100%) -* 2. Interface (100%) - -### Advantages - - **1**. It reduces the complexity of viewing things. - **2**. Avoids code duplication and increases reusability. - **3**. Helps to increase the security of an application or program as only important details are provided to the user. - **4**. Programmers can implement abstract methods to perform different tasks depending on the need. - - - -### Abstract Class in Java - -An abstract class is a class, that is declared with the `abstract` keyword. It is just like a normal class but has two differences. - -* 1. We cannot create an object of this class. Only objects of its non-abstract (or concrete) sub-classes can be created. - - * 2. It can have zero or more abstract methods which are not allowed in a non-abstract class (concrete class). - -Key points: -* 1. The abstract is a non-access modifier in java which is applicable for classes, interfaces, methods, and inner classes. It represents an incomplete class which depends on subclasses for its implementation. Creating a subclass is compulsory for abstract classes. -- 2. A non-abstract class is sometimes called a concrete class. -- 3. An abstract concept does not apply to variables. - -:::tip -An abstract class can have a data member, abstract method, method body (non-abstract method), constructor, and even main() method. -::: - -### Abstract Method in Java -A method which is declared with abstract modifier and has no implementation (means no body) is called an abstract method in java. It does not contain any body. It has simply a signature declaration followed by a semicolon. It has the following general form as given below. - -Syntax: -```java - abstract type MethodName(arguments); // No body
-``` -For example: -```java - abstract void msg(); // No body.
-``` -Since the abstract method does not contain any body. Therefore, it is also known as an incomplete method in java. -A non-abstract class cannot have an abstract method whether it is inherited or declared. In Java. - -Key points: -- 1. The abstract method cannot be static. -- 2. It cannot be private because the abstract method must be implemented in the subclass. If we declare it as private, we cannot implement it from outside the class. -- 3. A concrete method is a method which has always the body. It is also called a complete method in java. - - -- Declares the existence of methods but not the implementation of those. -- An abstract class defines behaviours that can vary due to polymorphism and that each explicit class that inherits from it must implement depending on its specific need. -- You cannot have an instance of an abstract class -- For a class to be abstract at least one of its methods must be abstract (this is the difference between a conventional class and an abstract class) -- An abstract class cannot be instantiated but it can be inherited (Objects cannot be created directly with new) -- Its use depends on the application of the concept of Inheritance -- The first concrete subclass that inherits from an abstract class must implement all the superclass's methods -- An abstract method does not define how it will behave since this logic is put in the classes that will implement the method - -An abstract class forces you to use inheritance - - - -Example Abstract class - -```java -abstract class Car{ - abstract void run(); -} - -class Honda extends Car{ - void run(){ - System.out.println("running safely"); - } - - public static void main(String args[]){ - Bike obj = new Honda4(); - obj.run(); - } -} -``` - -Another example - -```java -//Example of an abstract class that has abstract and non-abstract methods -abstract class Car{ - Bike(){System.out.println("car is created");} - abstract void run(); - void changeGear(){ - System.out.println("gear changed"); - } -} -//Creating a Child class which inherits Abstract class -class Honda extends Car{ - void run(){ - System.out.println("running safely"); -} -} -//Creating a Test class which calls abstract and non-abstract methods -class TestAbstraction2{ - public static void main(String args[]){ - Bike obj = new Honda(); - obj.run(); - obj.changeGear(); - } -} - -//RESULT -bike is created -running safely -gear changed -``` - -## Interface - -Another way to achieve abstraction in Java is with interfaces. - -The interface in Java is a mechanism to achieve abstraction. There can be only abstract methods in the Java interface, not a method body. It is used to achieve abstraction and multiple inheritance in Java. - -- It is an abstract class, that is, it cannot be instantiated -- Since Java 8, we can have default and static methods in an interface. -- Since Java 9, we can have private methods in an interface. -- It has a list of methods that have no definition. So the methods are abstract (they have no functionality) -- Java interface is a collection of abstract methods - -An ```interface``` is a completely "abstract class" that is used to group related methods with empty bodies: - -Example: - -```java -// Interface -interface Animal { - public void sound(); // interface method (does not have a body) - public void sleep(); // interface method (does not have a body) -} - -// Cat "implements" the Animal interface -class Cat implements Animal { - public void sound() { - // The body of sound() is provided here - System.out.println("The cat says: Miau"); - } - public void sleep() { - // The body of sleep() is provided here - System.out.println("Zzz"); - } -} - -class Main { - public static void main(String[] args) { - Cat myCat = new Cat(); // Create a Cat object - myCat.animalSound(); - myCat.sleep(); - } -} -``` - - - -### Multiple Interfaces - -Example: - -```java -interface FirstInterface { - public void myMethod(); // interface method -} - -interface SecondInterface { - public void myOtherMethod(); // interface method -} - -class DemoClass implements FirstInterface, SecondInterface { - public void myMethod() { - System.out.println("Some text.."); - } - public void myOtherMethod() { - System.out.println("Some other text..."); - } -} - -class Main { - public static void main(String[] args) { - DemoClass myObj = new DemoClass(); - myObj.myMethod(); - myObj.myOtherMethod(); - } -} -``` - -**About Information:** -- Like abstract classes, interfaces cannot be used to create objects (in the example above, it is not possible to create an "Animal" object in the MyMainClass) -- Interface methods do not have a body - the body is provided by the "implement" class -- On implementation of an interface, you must override all of its methods -- Interface methods are by default ```abstract``` and ```public``` -- Interface attributes are by default ```public```, ```static``` and ```final``` -- An interface cannot contain a constructor (as it cannot be used to create objects) - -**Why And When To Use Interfaces?** - - - To achieve security - hide certain details and only show the important details of an object (interface). - - Java does not support "multiple inheritance" (a class can only inherit from one superclass). However, it can be achieved with interfaces, because the class can implement multiple interfaces. Note: To implement multiple interfaces, separate them with a comma (see example below). - - It can be used to achieve loose coupling. - - - - -## The relationship between classes and interfaces - -As shown in the figure given below, a class extends another class, an interface extends another interface, but a class implements an interface. - - -

- -

- -Example - -```java -interface Bank{ -float rateOfInterest(); -} -class SBI implements Bank{ -public float rateOfInterest(){return 9.15f;} -} -class PNB implements Bank{ -public float rateOfInterest(){return 9.7f;} -} -class TestInterface2{ -public static void main(String[] args){ -Bank b=new SBI(); -System.out.println("ROI: "+b.rateOfInterest()); -}} -``` - - - -## Multiple inheritance in Java by interface - -If a class implements multiple interfaces, or an interface extends multiple interfaces, it is known as multiple inheritance. - -

- -

- -:::tip -Multiple inheritance is not supported through class in Java, but it is possible by an interface. -::: - -As we have explained in the inheritance chapter, multiple inheritance is not supported in the case of class because of ambiguity. However, it is supported in case of an interface because there is no ambiguity. It is because its implementation is provided by the implementation class. For example: - -```java -interface Printable{ -void print(); -} -interface Showable{ -void print(); -} - -class TestInterface3 implements Printable, Showable{ -public void print(){System.out.println("Hello");} -public static void main(String args[]){ -TestInterface3 obj = new TestInterface3(); -obj.print(); - } -} -``` - - - -## Interface inheritance - -A class implements an interface, but one interface extends another interface. - -```java -interface Printable{ -void print(); -} -interface Showable extends Printable{ -void show(); -} -class TestInterface4 implements Showable{ -public void print(){System.out.println("Hello");} -public void show(){System.out.println("Welcome");} - -public static void main(String args[]){ -TestInterface4 obj = new TestInterface4(); -obj.print(); -obj.show(); - } -} -``` - - - -## Default Method in Interface - -```java -interface Drawable{ -void draw(); -default void msg(){System.out.println("default method");} -} -class Rectangle implements Drawable{ -public void draw(){System.out.println("drawing rectangle");} -} -class TestInterfaceDefault{ -public static void main(String args[]){ -Drawable d=new Rectangle(); -d.draw(); -d.msg(); -}} - -// RESULT -drawing rectangle -default method -``` - - - -## Static Method in Interface - -Since Java 8, we can have static methods in the interface - -```java -interface Drawable{ -void draw(); -static int cube(int x){return x*x*x;} -} -class Rectangle implements Drawable{ -public void draw(){System.out.println("drawing rectangle");} -} - -class TestInterfaceStatic{ -public static void main(String args[]){ -Drawable d=new Rectangle(); -d.draw(); -System.out.println(Drawable.cube(3)); -}} -``` - - - -## Difference between abstract class and interface - -The main difference between interface and abstract class is that an interface provides an encapsulation mechanism for method protocols without forcing the user to use inheritance. - -However, there are many differences between abstract class and interface that are given below. - -| Abstract class | Interface| -|---|---| -| Abstract class can have abstract and non-abstract methods. | Interface can have only abstract methods. Since Java 8, it can have default and static methods also.| -| Abstract class doesn't support multiple inheritance. | Interface supports multiple inheritance.| -| Abstract class can have final, non-final, static and non-static variables. | Interface has only static and final variables.| -| Abstract class can provide the implementation of an interface. | Interface can't provide the implementation of an abstract class.| -| The abstract keyword is used to declare an abstract class. | The interface keyword is used to declare an interface.| -| An abstract class can extend another Java class and implement multiple Java interfaces. | An interface can extend another Java interface only.| -| An abstract class can be extended using the keyword "extends". | An interface can be implemented using the keyword "implements".| -| A Java abstract class can have class members like private, protected, etc. | Members of a Java interface are public by default.| -| An abstract class can inherit from a single class (abstract or not) | Interface can extend several interfaces at the same time. | -| An abstract class can have methods that are or are not abstract | Interfaces can only and exclusively define abstract methods or a default method | -| In abstract classes the word abstract is mandatory to define an abstract method (as well as the class) | When you define an interface, this word is optional since it is inferred in the concept of interface.| -| Abstract classes, unlike interfaces, can have constructors, and default method implementations and can only be inherited once from these. | Although in java 8, default implementations are allowed, they cannot contain constructors. In the case of interfaces, if you can implement multiple of these | -| Abstract classes are more used for base-type objects. It is like the parent in the hierarchy in a set of objects that share the same parent. | The interfaces are known as a contract. This is because they force you to implement their methods, which ensures all business logic that every object that implements it will have access to the methods defined in it. | -| Abstract think more about objects | Interface think more about implementation | - -| parameters | Abstract class | Interface | -|---|---|---| -| keyword used | abstract | interface | -| Type of variable | static and non-static | static | -| Access modifiers | All access modifiers | Only public acces modifiers | -| speed | Fast | Slow | -| When to used | To avoid independence | For future Enhancement | diff --git a/docs/Object Oriented Programming/car.png b/docs/Object Oriented Programming/car.png deleted file mode 100644 index 9b6d9ac0a8d5ead420f7d9cc47df1b9e4ba1f1b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27324 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
  • =$~qIW{t^w;M6?_4FRRT*0~!Z(LB`Irx)NKpXlZJJ{ywK*x> zU2%OM>r&&&&--jY#@2sclkLNK)(0Y{RI|9fDQI}8&_8^e>Xf;r(Rf{=^He%4!{5jk zbpQ1cm?dM9smtIH)7fRleqb*3L!RJ0z` zDp=7rM;#7|_kA4cI0wC6t>zO@_}c#BYYfD;4PGH|LoG%ie(3X>@UqKT7*mFj*Gxtk zhxBIjn&qY4cP;_jk2PjYM(j-rkNWpcB^C$0WFl0nwLIm>amNqtR8KqJ)a_D2b=CND zXtC>_qrful3nVkllPC+oOCK2ffwV|?cAdN8ou70Tinx~d9~N2J4zoBxg`7jyD)<=b ztty45Nsilzbt)P3wLWvglj? zY{YTU{tVg9JSVgu@D0>8Bj-6tXY;Itgk4M;xQr3+;2GIbD#eW7>!;t-$Pp>)2Uz)A z53W4fFKO&4-w&D-QH*7WI}x{mP-^U+OS#m1`IIM{S^ z8|hrx0;|4F`F5pj&$%w%^<2Z}795uHBX=xdJ*UiUC3!)AU6Vz1ksF$2gkNx0=sjtO z$`i`71HZ9`QmCCK3`5>gDkn)B1B%IeoP(vAJ0>;b-b+$s7SEzLNx`f;s@eWtS z-ZzPYe|oqKrfzP@GVgh(k`!Zh2ge&}=Qq_cQiQ~pYD7wzWt)sN4?6J_VT!F`pN)_o zRGS;=>gKW5mK9!eYCPTZZGOO8~uZ?&AZecCTvH;d6+NYi>ecf?48rzvkvmSv=z zJMZAgPU&6W7ZdP}R!0v3nr zYH1&ZqH89#*l`$T9U|AYDeMK+h%3sf5}urVoC$qCHb(oggI~rd5(RH$+a&+N+*}Io zP1-9!`Sps+RJ#pL`jlAZrGHw*^_F5lkuC0e6RP4U1;fTVyK^4ePSl)0k!{wg8i|@3 zWVj*yyBO9Bo$E{H?>*&)IqKeH{us6}Ri1nnNls_Vxd$^|xWW+K<|2OwO82>rC%CBXT=%8vlb&p2rY z{Zq$hg77F4#l`=OkAO@7Va_Q0qvW07usxYqkoV76h7OKH)IknFyni8Fzy&|dbprUt zugwV}94xvc%|*CBsX`fS6r53ds6XT5;6p1}c17f$)ba=%*GpbdRX#XF5iu13GY -C++ Code - -```cpp -class Car { -private: - string model; - int year; - -public: - // Constructor - Car(string m, int y) : model(m), year(y) {} - - // Method to display car details - void display() { - cout << "Model: " << model << ", Year: " << year << endl; - } -}; -``` - - -
    -Java Code - -```java -class Car { - private String model; - private int year; - - // Constructor - Car(String m, int y) { - model = m; - year = y; - } - - // Method to display car details - void display() { - System.out.println("Model: " + model + ", Year: " + year); - } -} -``` -
    - ---- - -## **What is an Object?** - -An **object** is an instance of a class. When you create an object, you create a specific instance of a class with its own unique set of attributes. Objects interact with one another and can have their own state and behavior. - -### **Creating Objects** - -
    -C++ Code - -```cpp -int main() { - Car myCar("Toyota", 2020); - myCar.display(); // Output: Model: Toyota, Year: 2020 - return 0; -} -``` -
    - -
    -Java Code - -```java -public class Main { - public static void main(String[] args) { - Car myCar = new Car("Toyota", 2020); - myCar.display(); // Output: Model: Toyota, Year: 2020 - } -} -``` -
    - ---- - -## **Key Differences Between Classes and Objects:** -- **Definition**: A class is a blueprint; an object is an instance of that blueprint. -- **Memory**: Class is a logical entity; an object is a physical entity in memory. -- **Instantiation**: Classes need to be instantiated to create objects. - -![Class and Object Diagram](car.png) -*Diagram illustrating the relationship between classes and objects in OOP.* - ---- - -## **Conclusion** - -Classes and objects are the cornerstones of OOP, enabling developers to create modular, reusable, and maintainable code. Understanding these concepts is essential for mastering object-oriented design and programming. - ---- diff --git a/docs/Object Oriented Programming/constructors-destructors.md b/docs/Object Oriented Programming/constructors-destructors.md deleted file mode 100644 index 24a0b8f66..000000000 --- a/docs/Object Oriented Programming/constructors-destructors.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: constructors-and-destructors -title: Constructors and Destructors in OOP -sidebar_label: Constructors and Destructors -sidebar_position: 3 -description: "Constructors and destructors are special methods in OOP that handle object initialization and cleanup. Constructors set up the initial state, while destructors handle object destruction and resource management." -tags: [oops, constructors, destructors] ---- - -# **Constructors and Destructors** - -Constructors and destructors are **special member functions** in object-oriented programming (OOP) that are automatically called when an object is created or destroyed, respectively. They are essential for initializing and cleaning up resources used by objects. - ---- - -## **1. What is a Constructor?** - -A **constructor** is a special function that initializes an object when it is created. It has the same name as the class and does not have a return type. Constructors can take parameters to initialize object attributes. - -### **Types of Constructors** -- **Default Constructor**: A constructor that does not take any parameters. -- **Parameterized Constructor**: A constructor that takes parameters to set initial values for the object. - -### **Example of Constructors** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Rectangle { -private: - int width, height; - -public: - // Default Constructor - Rectangle() { - width = 0; - height = 0; - } - - // Parameterized Constructor - Rectangle(int w, int h) { - width = w; - height = h; - } - - void display() { - cout << "Width: " << width << ", Height: " << height << endl; - } -}; - -int main() { - Rectangle rect1; // Default constructor - Rectangle rect2(10, 5); // Parameterized constructor - - rect1.display(); - rect2.display(); - return 0; -} -``` -
    - -
    -Java Code - -```java -class Rectangle { - private int width, height; - - // Default Constructor - Rectangle() { - width = 0; - height = 0; - } - - // Parameterized Constructor - Rectangle(int w, int h) { - width = w; - height = h; - } - - void display() { - System.out.println("Width: " + width + ", Height: " + height); - } -} - -public class Main { - public static void main(String[] args) { - Rectangle rect1 = new Rectangle(); // Default constructor - Rectangle rect2 = new Rectangle(10, 5); // Parameterized constructor - - rect1.display(); - rect2.display(); - } -} -``` -
    - ---- - -## **2. What is a Destructor?** - -A **destructor** is a special function that is called when an object is destroyed. It has the same name as the class but is preceded by a tilde (~) in C++. Destructors are used to release resources allocated to the object, such as memory or file handles. - -### **Example of Destructors** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Rectangle { -private: - int width, height; - -public: - Rectangle(int w, int h) : width(w), height(h) { - cout << "Constructor called!" << endl; - } - - ~Rectangle() { - cout << "Destructor called!" << endl; - } - - void display() { - cout << "Width: " << width << ", Height: " << height << endl; - } -}; - -int main() { - Rectangle rect(10, 5); - rect.display(); - return 0; // Destructor is called automatically here -} -``` -
    - -
    -Java Code - -```java -class Rectangle { - private int width, height; - - Rectangle(int w, int h) { - width = w; - height = h; - System.out.println("Constructor called!"); - } - - // Finalize method acts as a destructor in Java - protected void finalize() { - System.out.println("Destructor called!"); - } - - void display() { - System.out.println("Width: " + width + ", Height: " + height); - } -} - -public class Main { - public static void main(String[] args) { - Rectangle rect = new Rectangle(10, 5); - rect.display(); - rect = null; // Request garbage collection - System.gc(); // Calling garbage collector - } -} -``` -
    - ---- - -## **3. Importance of Constructors and Destructors** - -- **Resource Management**: Constructors are used to allocate resources, while destructors are used to release them. This ensures that resources are properly managed and prevents memory leaks. -- **Initialization**: Constructors allow for setting initial values for object attributes, providing a clear and consistent way to create objects. - ---- \ No newline at end of file diff --git a/docs/Object Oriented Programming/interfaces-vs-abstract-classes.md b/docs/Object Oriented Programming/interfaces-vs-abstract-classes.md deleted file mode 100644 index bd7b9b3ab..000000000 --- a/docs/Object Oriented Programming/interfaces-vs-abstract-classes.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: interface-vs-abstract-class -title: Interface vs Abstract Class in OOP -sidebar_label: Interface vs Abstract Class -sidebar_position: 5 -description: "An interface defines a contract for behavior, whereas an abstract class provides partial implementation. Both are used to achieve abstraction but differ in their design and use cases." -tags: [oops, interface, abstract-class] ---- - -# **Interface vs Abstract Classes** - -In object-oriented programming, both **interfaces** and **abstract classes** are used to achieve abstraction, allowing you to define methods that must be implemented by derived classes. However, they serve different purposes and have distinct characteristics. - ---- - -## **1. What is an Abstract Class?** - -An **abstract class** is a class that cannot be instantiated on its own and is meant to be subclassed. It can contain both abstract methods (without implementation) and concrete methods (with implementation). Abstract classes are used to provide a common base for derived classes. - -### **Key Features of Abstract Classes** -- Can have both abstract and concrete methods. -- Can have member variables. -- Can provide a default implementation for some methods. - -### **Example of Abstract Class** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Animal { -public: - // Abstract method - virtual void sound() = 0; // Pure virtual function - - void sleep() { - cout << "Sleeping..." << endl; - } -}; - -class Dog : public Animal { -public: - void sound() { - cout << "Woof!" << endl; - } -}; - -int main() { - Dog dog; - dog.sound(); // Calls the sound method - dog.sleep(); // Calls the sleep method from the Animal class - return 0; -} -``` -
    - -
    -Java Code - -```java -abstract class Animal { - // Abstract method - abstract void sound(); - - void sleep() { - System.out.println("Sleeping..."); - } -} - -class Dog extends Animal { - void sound() { - System.out.println("Woof!"); - } -} - -public class Main { - public static void main(String[] args) { - Dog dog = new Dog(); - dog.sound(); // Calls the sound method - dog.sleep(); // Calls the sleep method from the Animal class - } -} -``` -
    - ---- -## **2. What is an Interface?** - -An **interface** is a contract that defines a set of methods that implementing classes must provide. It cannot contain any implementation itself (in languages like Java) and is used to achieve multiple inheritance. - -### **Key Features of Interfaces** -- Can only contain abstract methods (Java 8 and above allows default methods). -- Cannot have member variables (only constants). -- Supports multiple inheritance. - -### **Example of Interface** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class IAnimal { -public: - virtual void sound() = 0; // Pure virtual function -}; - -class Cat : public IAnimal { -public: - void sound() { - cout << "Meow!" << endl; - } -}; - -int main() { - Cat cat; - cat.sound(); // Calls the sound method - return 0; -} -``` -
    - -
    -Java Code - -```java -interface IAnimal { - void sound(); // Abstract method -} - -class Cat implements IAnimal { - public void sound() { - System.out.println("Meow!"); - } -} - -public class Main { - public static void main(String[] args) { - Cat cat = new Cat(); - cat.sound(); // Calls the sound method - } -} -``` -
    - ---- - -## **3. Key Differences Between Abstract Classes and Interfaces** - -| Feature | Abstract Class | Interface | -|------------------------------|----------------------------------------|---------------------------------------------| -| **Instantiation** | Cannot be instantiated | Cannot be instantiated | -| **Method Implementation** | Can have both abstract and concrete methods | Can only have abstract methods (until Java 8) | -| **Inheritance** | Can extend only one abstract class | Can implement multiple interfaces | -| **Access Modifiers** | Can use any access modifier | All methods are public by default | -| **Member Variables** | Can have member variables | Cannot have member variables | - ---- \ No newline at end of file diff --git a/docs/Object Oriented Programming/intro-to-oops.md b/docs/Object Oriented Programming/intro-to-oops.md deleted file mode 100644 index 6e5e81e5a..000000000 --- a/docs/Object Oriented Programming/intro-to-oops.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: intro-to-oops -title: Introduction to Object-Oriented Programming (OOP) -sidebar_label: Introduction to OOP -sidebar_position: 1 -description: "Object-Oriented Programming (OOP) is a programming paradigm based on the concept of objects, which can contain data and code to manipulate that data. It promotes concepts like encapsulation, inheritance, and polymorphism." -tags: [oops, object-oriented-programming] ---- - -# **Introduction to Object-Oriented Programming (OOPs)** - -Object-Oriented Programming (OOPs) is a **programming paradigm** that organizes software design around data, or objects, rather than functions and logic. It helps in breaking down complex problems into smaller, manageable units by representing real-world entities as objects. - -## **Key Concepts of OOPs** - -OOPs is built on four main pillars: -1. **Encapsulation** -2. **Abstraction** -3. **Inheritance** -4. **Polymorphism** - -![OOPs concepts](intro.png) - -These core concepts help developers create software that is more modular, reusable, and scalable. We will explore these in detail in the following sections. - ---- - -## **Advantages of OOPs over Procedure-Oriented Programming** - -Object-oriented programming (OOP) offers several key advantages over procedural programming: - -- **Code Reusability**: OOP promotes code reusability by using objects and classes. This leads to less duplication and more efficient development, as you can create reusable components that can be leveraged in different parts of your application. - -- **Enhanced Code Organization**: OOP provides a clear and logical structure, making the code easier to understand, maintain, and debug. By organizing code into objects, related functionalities are grouped together. - -- **Support for DRY Principle**: OOP supports the DRY (Don’t Repeat Yourself) principle, encouraging the minimization of code repetition. This leads to cleaner, more maintainable code, as common functionalities are placed in a single location and reused, reducing redundancy. - -- **Faster Development**: OOP enables faster development by reusing existing code and creating modular components. This allows for quicker and more efficient application development, as developers can build upon already existing codebases. - ---- - -## **Why OOPs is Important?** - -OOPs mirrors real-world entities and their interactions, making it a natural way to structure code for many applications. This approach is widely used in designing software systems that require high levels of flexibility and extensibility, such as video games, graphical user interfaces (GUIs), and complex enterprise applications. - ---- - -The next sections will delve deeper into each of these principles and other related concepts like **Classes and Objects**, **Constructors**, **Interfaces**, and **Real-World Examples**. diff --git a/docs/Object Oriented Programming/intro.png b/docs/Object Oriented Programming/intro.png deleted file mode 100644 index eaee68aaaa3060a62852953d98aa4acf464918d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174906 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

    lBCyxMACJYN= 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 diff --git a/docs/Object Oriented Programming/real-world-examples.md b/docs/Object Oriented Programming/real-world-examples.md deleted file mode 100644 index 624412c66..000000000 --- a/docs/Object Oriented Programming/real-world-examples.md +++ /dev/null @@ -1,299 +0,0 @@ ---- -id: real-world-examples -title: Real-World Examples of OOP -sidebar_label: Real World Examples -sidebar_position: 6 -description: "OOP concepts are widely used in real-world applications. This section showcases practical examples of OOP concepts are applied in various industries." -tags: [oops, real-world, examples] ---- - -# **Real-World Examples of Object-Oriented Programming** - -Object-Oriented Programming (OOP) concepts are widely used in software development, allowing for more modular, maintainable, and reusable code. Below are some real-world examples of how OOP principles are applied. - -## **1. E-commerce Application** - -In an e-commerce application, we can represent various entities such as **Product**, **Customer**, and **Order** using classes. - -### **Classes Definition** -- **Product**: Represents an item available for sale. -- **Customer**: Represents a user who can purchase products. -- **Order**: Represents a transaction made by a customer. - -### **Example Classes** - -

    -C++ Code - -```cpp -class Product { -private: - string name; - double price; - -public: - Product(string n, double p) : name(n), price(p) {} - void display() { - cout << "Product: " << name << ", Price: " << price << endl; - } -}; - -class Customer { -private: - string name; - string email; - -public: - Customer(string n, string e) : name(n), email(e) {} - void display() { - cout << "Customer: " << name << ", Email: " << email << endl; - } -}; - -class Order { -private: - Product product; - Customer customer; - -public: - Order(Product p, Customer c) : product(p), customer(c) {} - void display() { - cout << "Order Details:\n"; - product.display(); - customer.display(); - } -}; -``` -
    - -
    -Java Code - -```java -class Product { - private String name; - private double price; - - Product(String n, double p) { - name = n; - price = p; - } - - void display() { - System.out.println("Product: " + name + ", Price: " + price); - } -} - -class Customer { - private String name; - private String email; - - Customer(String n, String e) { - name = n; - email = e; - } - - void display() { - System.out.println("Customer: " + name + ", Email: " + email); - } -} - -class Order { - private Product product; - private Customer customer; - - Order(Product p, Customer c) { - product = p; - customer = c; - } - - void display() { - System.out.println("Order Details:"); - product.display(); - customer.display(); - } -} -``` -
    - -### **Creating Instances** - -
    -C++ Code - -```cpp -int main() { - Product myProduct("Laptop", 999.99); - Customer myCustomer("John Doe", "john@example.com"); - Order myOrder(myProduct, myCustomer); - myOrder.display(); - return 0; -} -``` -
    - -
    -Java Code - -```java -public class Main { - public static void main(String[] args) { - Product myProduct = new Product("Laptop", 999.99); - Customer myCustomer = new Customer("John Doe", "john@example.com"); - Order myOrder = new Order(myProduct, myCustomer); - myOrder.display(); - } -} -``` -
    - ---- - -## **2. Banking System** - -In a banking system, classes can be created to represent **Account**, **Customer**, and **Transaction**. - -### **Classes Definition** -- **Account**: Represents a bank account with methods for depositing and withdrawing money. -- **Customer**: Represents a customer who owns the account. -- **Transaction**: Represents a transaction made on the account. - -### **Example Classes** - -
    -C++ Code - -```cpp -class Account { -private: - double balance; - -public: - Account(double initialBalance) : balance(initialBalance) {} - - void deposit(double amount) { - balance += amount; - cout << "Deposited: " << amount << ", New Balance: " << balance << endl; - } - - void withdraw(double amount) { - if (amount <= balance) { - balance -= amount; - cout << "Withdrawn: " << amount << ", Remaining Balance: " << balance << endl; - } else { - cout << "Insufficient funds!" << endl; - } - } -}; - -class Customer { -private: - string name; - -public: - Customer(string n) : name(n) {} - void display() { - cout << "Customer: " << name << endl; - } -}; - -class Transaction { -private: - Account account; - double amount; - -public: - Transaction(Account a, double amt) : account(a), amount(amt) {} - void execute() { - // Transaction logic can be implemented here - } -}; -``` -
    - -
    -Java Code - -```java -class Account { - private double balance; - - Account(double initialBalance) { - balance = initialBalance; - } - - void deposit(double amount) { - balance += amount; - System.out.println("Deposited: " + amount + ", New Balance: " + balance); - } - - void withdraw(double amount) { - if (amount <= balance) { - balance -= amount; - System.out.println("Withdrawn: " + amount + ", Remaining Balance: " + balance); - } else { - System.out.println("Insufficient funds!"); - } - } -} - -class Customer { - private String name; - - Customer(String n) { - name = n; - } - - void display() { - System.out.println("Customer: " + name); - } -} - -class Transaction { - private Account account; - private double amount; - - Transaction(Account a, double amt) { - account = a; - amount = amt; - } - - void execute() { - // Transaction logic can be implemented here - } -} -``` -
    - -### **Creating Instances** - -
    -C++ Code - -```cpp -int main() { - Account myAccount(1000.00); - myAccount.deposit(500); - myAccount.withdraw(200); - myAccount.withdraw(1500); // Insufficient funds - return 0; -} -``` -
    - -
    -Java Code - -```java -public class Main { - public static void main(String[] args) { - Account myAccount = new Account(1000.00); - myAccount.deposit(500); - myAccount.withdraw(200); - myAccount.withdraw(1500); // Insufficient funds - } -} -``` -
    - ---- \ No newline at end of file diff --git a/docs/Object Oriented Programming/typesOfInheritance.md b/docs/Object Oriented Programming/typesOfInheritance.md deleted file mode 100644 index bfd590921..000000000 --- a/docs/Object Oriented Programming/typesOfInheritance.md +++ /dev/null @@ -1,118 +0,0 @@ ---- - -id: inheritance -title: "Types of Inheritance in OOP" -sidebar_label: Types of Inheritance -sidebar_position: 3 -description: "Inheritance is a mechanism in OOP that allows one class to inherit the properties and behaviors of another class, promoting code reusability." -tags: [oops, inheritance, classes] - ---- - -# **Types of Inheritance in Object-Oriented Programming** - -Inheritance is a key concept in Object-Oriented Programming (OOP) that allows one class (child or derived class) to inherit attributes and methods from another class (parent or base class). This promotes code reusability and establishes a relationship between classes. - -## **Types of Inheritance** - -1. **Single Inheritance**: A child class inherits from one parent class. -2. **Multiple Inheritance**: A child class inherits from multiple parent classes. -3. **Multilevel Inheritance**: A child class inherits from a parent class, which in turn inherits from another parent class. -4. **Hierarchical Inheritance**: Multiple child classes inherit from a single parent class. -5. **Hybrid Inheritance**: A combination of two or more types of inheritance. - -### **1. Single Inheritance** - -In single inheritance, a class inherits from one parent class. - -```cpp -class Animal { -public: - void sound() { - cout << "Animal makes a sound" << endl; - } -}; - -class Dog : public Animal { -public: - void bark() { - cout << "Dog barks" << endl; - } -}; -``` - -### 2. Multiple Inheritance - -In multiple inheritance, a class inherits from more than one parent class. (Note: Not supported directly in Java, but can be achieved through interfaces.) - - -```cpp -class Flyer { -public: - void fly() { - cout << "Flying" << endl; - } -}; - -class Swimmer { -public: - void swim() { - cout << "Swimming" << endl; - } -}; - -class Duck : public Flyer, public Swimmer { -}; -``` - -### **3. Multilevel Inheritance** -In multilevel inheritance, a class inherits from a parent class, which is also a derived class of another parent class. - -```cpp -class Animal { -public: - void eat() { - cout << "Eating" << endl; - } -}; - -class Dog : public Animal { -public: - void bark() { - cout << "Barking" << endl; - } -}; - -class Puppy : public Dog { -public: - void weep() { - cout << "Weeping" << endl; - } -}; -``` - -### **4. Hierarchical Inheritance** -In hierarchical inheritance, multiple child classes inherit from a single parent class. - -```cpp -class Animal { -public: - void eat() { - cout << "Eating" << endl; - } -}; - -class Dog : public Animal { -public: - void bark() { - cout << "Barking" << endl; - } -}; - -class Cat : public Animal { -public: - void meow() { - cout << "Meowing" << endl; - } -}; -``` diff --git a/docs/Queue/Blocked-queue.png b/docs/Queue/Blocked-queue.png deleted file mode 100644 index e82a642f207a52f3a5748a0675f08dfec52c293a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21608 zcmeGDbx>SE_XY^#Zi71kg1fuBy9Ad2gS&fhmk`_~c!1#U65QS0-F1ie{nhu?Zq@#^ zTeY=vtET9=HQc`4eY($cp7WdtWko4u1bhTAFfe2pX>nCBFvxT;FmQ4>7|*gdLp#OW55f@SS zFgRO-^}*EGhP~XlPqg7|=Teo1Yk$c9qTLmWB_WK7cv$*zL+_q!-B6of>`?qeA5%n` zCjXXLRumO&+MB6$spEqy16t$?r43s2`laXP`;ED|g@qf}iyxo;`p_yw_j6yz& zs8=}-CZ^He!$!dup$%O*ad8*7LMDc)&UY^)TxKxZU&Ek#F0`LN%`Yv5mrG&nXPe*; zI+`i=wvGr7A0Hni@sIX3@xDQQd&KU4?JFp;>J7-Ta2w;w46UhpHy3^()W z06*w|Rp^)MZa*DcVV0WejH%O1fCM+20VVz-#cju{=52i*lsEv0eU6JOul zu$c70!6=YDYY@67|Ie~Uiv0ZlTK^B81KEA-w#JAOB5NS9Yr05|#rxjoyScfS^$OFG zQpTE@R8%E2V+x|(Rb2R?JWZcar4C}fDsr0qekH}fHqV>*oSZlSxuntU;ncbgS-u(z z5Zx7xhykdRiH*sXWVDiJ%bcN*y}9&9I%9@-rDHJX_kD})>Yu34&QX$f-aAoQJ%m}S z`o`q1AS-sE{4~z+SZwyVdBT1zy3QWDxON2hx^mwvY9pK?&7?0X>iKmkk{xQ8Y9|VZ z5-JVrZHF>Bf2SMfqPD3b6_f4@6)}&R6SLVu)Tac8==PfIPF+)Z&1hke@pmgJ;Daau zS@8eaTLsW#zWpzk-R>ltds+rC=8*`t*1oOEw8Mldza!AeWxaV8r@sv2tFY(a0w_e2 z?z>23>!}SRS@n_(^6RK>BqGoyhD{_(^L@idVtb|Mq*uA0CG~vo=GJu*nStn2X-1P@ zkH7HhOs=Xm!QLc~^`6`qz>3e`63SRH#YSF-Q~TpkXe8aE=a-8=>0us)Z!riDE_BF=6UGEO{SNUdXH7RvTS@F&NG*Uz;==U&e(-YfynhHwM5V<=pAM&DKWj1Lf%|u5D}lY{ulz1M zNr^G53hrk-LE3Sgn^|M)bH3D8cfk%CzD@YD|G3TD6=vYH!~jFjZwOWu%x$hG`%`wr zG!kBkjnEa=^TAPvqvOlG)X4*eHphQa9$(C$&b8dzjm z4ihnxyp+b!@mlgQ9gH8$oxr}5`fYb2(YM3|n{cVR0WjAS`TzDwzzkaF@9yc7Hsw-T z^?&NMt(0xYd%LegQvJU}V<+nv&E5?ZrUId8f5m&I@Hw*%naNU%s|*(w?I{n>DbuKL z7wgGeXGQ&Ig~y45DC=dgigLDgPN}XI8wSOnAm6LsSok~MX!w8L@vbwK3kMk^*~#RD zMo0?biqn2){QCL+R(!bZr3!y_=v0h{du#Sh^LI(Bn!%v=@l$te4)I+%>||Pr8mVH0 z|H_^Vko^~I*g}K4A{Bxjm>fD`sX58Hl+UqHOtN@+N1j0S!LUd6K#wcd`_aK0V-aCE zFlvZ`wi}Abh!d7b@!20Q38=rAc!NkGJ>- z5bK11biriH7UoA`^$~KW9nPsDUApc5{DzX8PV6{Uqi&x+;JqkEl@#>I{QDr0pUbdm zFkT@DUTJuW-W>3tGAA*JM9OKLDp{ExIAJ6!NI`3e;q?3%>?SjKR&Qe#;i&QABs)7CV9 zhn!Eb>&_lPSLeg?8?T3iMcJ%hFz8)#--vNv_k_*hvX=y5k{~LO<*M*?<;t7|BN&qw zuzdC7AHbC#8hs*o@7Q7CZ`h$2W#ElOkf4W={2KnG=OC@mDez4aB})(weye~*d*eqz z$VZPi?Ecosv;eisrO&vt0&jY==^%>FRX3QxpD96t z<(nnkzmE#yZ(+o}y>wN*vy~U7jlH@G#r+`nfdic}7TVUvKbj*%0>Yw9f10)t_%FL4 zv(M{!czBS~K$bz2?4qp_GgQLILi47=zr6GC*iQYia3;u~=mx)C|E^r}l5aRleqyhPjMS;7x{X}#4Eyj^t$Mv<-?dcMR@AK`| zJbIRpS39w#r6n8+%Kdz1_R2S8tr5}Hw$}^o5M4+6xY9>89T=qbqX6W)nAVzNa~!vM zoZLwh%XX-2GPDHnc4p=_Aukw7^2f)gjB_iSRRIhpl5t6mAzY3;*w`O|WPJva+5jUCR<6?q6HKntf&F2dQ_Hdtg^E6g2dQ{Ne6L`Xp7?6a;D6wr zd<4;nA~*br5c{wsKASwW1*)Zfu4owf&fR419>n|}Xc?TgJr&<-+v;&*XV+YJ24b>D zQeUeI9}+doCFJFi@(T(CNCXqI$W=_3x?c=CCvrV&j3z&4Bp0uR22-yxzVSmwqFv+$pa+^-UoK1jWo3e=^~n9lb;KQ8bg6Ec~h!m z-`EjYI*~OrZZ7xNJyQ+sBpqfsnwUHZS?gFA$M|YW4|RRM=|m3)=rUV8_Tru$p!zqD zIuBTScjbB#SL!yR%oHmP9?z8v#F)S+@a8Z!jAUfS>M=gt!o;uhy}!R_E7KrX3fU|& zyIicVvAuaHfg7yvlJ$W`yuGKuOK7kj%*bA9k$g)r*yOn5XF8drXl&gbnAvG$XNi0Z zSlB!+yuz)xLowW;?M+`p-TswHM5eqRD-`#P$e4m+nT^g)weti(&8>3f$=qPJ5N z-l*F!)_m5$&BY>BbKtwF@p&NkI0K@jixzKJ^%8gEj$M&D=>f}LAPfm#5s7)t2f6}< zOzcF-5;=z5FxcblX#gr2lp!NcP28(~FK5~ItXdV?fsGq}1V5>iBvTmm`AI(`-^0$I z%Sc{@E?!7V$X?)azoRAXl{U1Q(u97@;p6_&T+|yYaelw<$+UAP$CuAwalZ-Dp2Q6j zEPXKXx~4dEB$JM$w&V+_7_cG~!H0l+CKI#7d9b*_=EGcu3XXb)D<*0kxmLDl^dfWc z?oP%7)XNM`v=VYVd@&!-JmNv;b3fO6J$LWy-AgfyjgCeVmz4Bs8M9)?pLiXNGyjC6 zZ@i`LU&3U!gf-SsAD=hb9^VFJnzq8M9nT)}E7F6dP^x-iYUQA0sq};{K91~!CEj#= zYA+@pwInF$^R!Hj#D!cIUc|grb^DH}MPdr@Vi;Cx_&&a^zU?S9U4;>}?@_M)J(uD4 z_aLX$S7hhZ>fLq%#W;X0#KAb7SR%f8=YNSf1|H!4uRA1;8@>-)$+~t|vvT_1K~5xB zvmB2e#9JJmHWLMu!z>N1cXi%R3`q62IxPN?N;O1Rg_uboP7PJ$C5PDUbPCODMcMnU z_o|!-+bXTbFy^f?s~TukT~l`py)@!k9@`A8zgGdtP|%M1+J}ezKcGAht(aPNY9VA2h-Qbt84&C(2pOu z|9Lb2eYeIgvyC9E!H&LZE4Ivcaz}+>{U)v*aQ;aRTKApb;p&ARjQUQzPC)hu>F5?@ zcS>Z*BugSrEWbF{`u-BWqswAFDEUfx_`C&EuZ3@^uIa37ro849t|HNrLG!hI zE3lyOtmR9r;e*pqJZZMdPPWH3eB1r9wa4>Ou|NTv9M!`Ot1!qL?poV5;>9LcE=~eP zi_U40BAW5s`%op7Ov%t+^8rOFU8E2NOEmkx_U-jgzmiJBwO~Hn`r`W^KKVB>&ISxe zUR>FBdwow&H-2EuRqiJhH4~0sfeF!#1?$8t#8*>F!W5&=ca=QE^n;r|%uD>|DgF}_ zLs956ZdUof(P{qCi?GP?op)Y0^YGw?y#t}yeCLrf>vaC~wUf}{FOl$h7~wsC2I6B+21fXbzLuVTkDVb- zOz+moVfCX!4BQCDzi%Za`XLtt1pE&a$WY(ibtY}b2kv_wE+0-kAAje;D|B+>-EI$H z69M$mruSqDPyVrLgKQn-l7F7$&7+Dk#Sn)s_b=+yp&2Hdn^^SIR*ZV$qn>HU;WuJr zL7bJ;5%!>(eH&s)o7{fhJFHdBWDQ-5;ll_usc>TZ8@a#z)T6rChuKJv)V@8C?=Mb& zY?ZvTH>R{%`O2ZKRs*m`IM_NnJ-C`3N3F@v$F&QYCAKnbZ(8gj&qowRNS)pkQeDt? zivxua`8N`jGh)Awg9utze~k35mXtoj*`Gc_5^vnWtTVEa(%x&z%eNwGg}F;KnW1tL zc@Z;Vr{vF?50FF!r3Cis0cW`5*?e4hVADQ@0EZ)X+-+yBJ=R{pzw@ugu#I#m{zK2`9k zXvE+#>P%|kmU)Nx?tJIxSKP!$UL?P%HUdu2?Yod=xOS5Jrf`V`09=Ivp+a|_2>#Mp z0W2aS%(Rg4gnZC5-a>(}GXr0a9)|>2v5?*&9b|@kA3L+-wi0$pr8Q}ClmC6u>d$q4 z#A>4PrF^e?32LIc!(OGGceEa6U!B|Y8$D*lYaFa&5vsSE*`FtO|`1O>2f?AD^GnL#oHZ3Sb+{v03bo>|H76^>sO2q%xx0F zZB+dzLMP`J8rCQzhbUW2AtkQ2e1>h$#HD^Vs$Xsmwtum&GI{!)&8;ma(x_Q2PMqi0 z*DV;M5baV3SkpYtL1%5nzttZPoLQzP^Oe1~M>92EcUIz3Qevg*Ud3ox-v66e$M!`- zQ$MtSgK?nZ#e%fKkbZag{-!;>_f+^SPY0?9Mx<0r^f!NNUM=lktw0MJQBuqO z6_+XkonjOQ@)Po;)Shw-W&t1$5%2_JH}ru>={T?`FrU#a=o0)4 zcmD6wa#3;awPO%AUNf&?(0>_GZ9q90ZZz^%K#8qq@7{HZq-a}ZY|=AVpR?E?!d!yFRX8RLu@~O_r>CEp~0mGI`fY^4gzxzqrW}vui}g*2Nmee;{wQ z!r%<|U1`Z#F!p`YtcgS2Dk()7Ga=z)nluFw9#(W9Umeb9rN}<(6AayI-$k*ZA2~Hr z)rCd(r|;LgQ-9=D>Sb?bYRj4DYb`V4%cw$i)9QNlQE;zHuq&T^PqfCv&QouB!ojUP zcbE;(YCQrggQ1~ke((=hT>0|I|0=lMi)lJ*B zf2jOhY{<(;uoUNdxV4t-i`Mdn*48nJeQ%wue{Xp+LA-65M9>In59JIcC^_QPthZhJ z54?QtxqR=DpEKjEZl=i6?j5;f^K%r-@I}0Yjxrx%uwH_JRNg`nR9*s+A0tgfToQe~ z8uf4_Hl4^y2OvL4$u{n-`7(w%SwfzG&j-K57b6+!5BF-eE^`n=ki74z-Si+cs`udi zx_1cky}8v$dYh=JcEq=d>y1(m4;{v}7u_dY0FtZnBLnWvJK?~HJS_ashJ%B{c%#Et zyAC*2mE0SKYWi@#rrqqcXIV_b?GPYRiyR+86*$r3`PXiZS3XCOs9dW`(#3^6Nw&xx zVXApyax$PuF2&^jbZKaG^mcx_eb)zH9YXGbD$jH2d5@&If|Szf)G`S z_VnxK>M^#T`Z^<2%4;JCF9HuPl!)_%gGG1H!-xNrD! zQ7WWErJc6Q^ZTWc7OGxl2Pt zvjVpDT!&~L(Fo*Wg2RwOY^5Dsirj`!%j9Yu5rJH?k;=LW{pbhwNR*bb#1khWyY8kY zOqWtokfPspSQBD$GUTFK4TK@l3k2eI2VkV4>o{F6iMMW&`VCN+7`0%Mr+px$Z7L&v z@yK$BhZ|*7qnJ{T$9Y5PP5?)CKt{NI8bRR+G#RRQm^V8{=wA0 zqZ>>iaZ=qv3u|_6glj{0<@&Dm_@@KUT!Bn=c6tLyAS<`tCDlwiVG2Gyi_+pb2>oSmDtsw@2|1bU{m zaN9eI5+^IPGSonWQCcw!6fED!qGq~Fv34v+QkhGfhskHmh=YNoh<1vLox9Z->bX1N zBw1wt3Gqg_8)VR75{hL)gm{x|B(udz&-5+qZjNWDmKKnYiZxMBD9gDlJv2Nl>gy|j zj*cFmlmyBwT_e*F${OFaKdg&=(nt3bQM12UGRCqOwkC>;3JZ-MFSkG((Zf2qKD9ir zxcFH%1VRWn@6}di5{<-Vd?QTNj1{tv<_sl0&$HmVz+bc|Sx#e%GjPI+2~o|b#>d-9 zZx5yiSep_CksvvQqRRgHzZfS7LcOo#h}F43fdbfn%IwLNY(Qk}m8IvCet z_3M|0{^*2Z4GMN?L0@benlz(Eav8VwlVUqY`e-urEJ+dqS;@J-;|_e)3nhi|2ljRF zn~_Amm8l1R;q)Q1i?|46EMq0C9Kl{uL2k8(Dnfe%VDI`wnC85j$zgQ(tlJU{A~^2C+&uDpZE=b zWW?PlMSHL#T|wLM7Hgl#i{t{!d&pdE$(`Ifo|Ik>=V$O4 zE?b}Au^wX@O^6ZDbIJ%%7q8)|tmej_0@8@v-I){q{g=n#CKB!c6~dpxQWlaKb5puo z?s28VzPf)MUI5*EJHl^b>#4)PZ$_UoH_8+vd2h7)^+(L2^)DE`c=Q-NXbR`c`#`2E zg?4=Snwcx<3yaGG!MLq+X>uD4k{xG&un--SNR+z*Rk&Hk=u36|Ci$!H1n=xqT<JbsGYvXY4Ks%ZSurhYjLEe9u!S96nN??RBKghL zd`)jPj6sm)T26oM+efI-Llfiz^uHHh^oUjybim{#UiO3+teh2s3fVnHEhx=vEm;82GW6xR^=fb2AC)H6 zKq#4>a%;K#ufI+ifl-rVkxfTbIi&F%s$7Yv>^C%ug+uVp0^nvcLqUpd`}qnJxw9RQ zg;hIjxKlg-HZ@sx89j9(XN)@x6WmJKoK70Nda(1IRBOjc<5;;8(@0A8bfdM3K8Hh^j6hh<<8eI2e{@aJpm$2A8_e^PY|^-| zBY)w_^aox^GWvQ!FkgqHO}+w;%x2*0dd!t0IWzYci0)bNh(MTAe; z%&SO0DWrnef=Zn4x)uI4ZgtGUH_=;RN>a#o{|w6RMoR;Tpd2WXss_6?7QhWwaI#Zl z07_yc`z(VlO4*;!!!<)lXAKaoDmx#fhdQ42=8W?0drpo0tYJ)rbTjD_6= zEVN%?5D75gpOPC?dXMqinvdSk8Rq_v?Z9o}OQRKm=D~$zkRAOy_oY%3*AqfC3Q2&- z6xU|*?aO6cwE82LUvw2++?NrXD@GY{mviaj)EGRr{fZ!SCnwhJot>=sbeSt@lY32E(TI`+ z4EX`kA8;I?r{7Ef#r!;aGyrT~7{_$!#dNE9Lqn9PR%p8uy9)cdJk=Fcz`JF*kf$)I zhT-b^2c!?nxoz9b8@hOwi@Ti#xEto^;A@bfY3IGwt6ASn6X(}uzSJrI0xSw5v1sFP zWugtrBVaMUWT)`Zo*g?65wl#1vm-~3%~&@|!q3rA<8Z7MEJq(OvNXw8lHhW(poBsp zPjxaJy>UtHHAe0|uM$ih;P|d_gy$Usg-dnM5xaLw#(Q!>0OJbycMi>+06KV>9i#8m zXAUhD)y+2fi+PijU)UYc$THnd8Arro>Y*(NIM(ic2-&cVGbo@Ub4RAcP9aqh{aVp-6Z?E-xJ}>|OHyds4}| z!kO$`bZ6918A73!`X(GA4HtfrBAM2JX;-PlW7JP2XQUKOO2ydZ3 z9FQOe$)cV`fEyL&u$H)Hp%q>REmQ8-&qsW*2lw-=w3hLuCD#CAkKg$WJHmV2DS|8!Idd9_a zDmqAZ8C9dT(?YblS5*%m(>(6oDn^gnXhlhL882H65ALFd3LkvH;Mq0d(=cgSH4E&e zfmlrYD%psvS&YG1(toW}lRYox+K_oqrp}kHyzm$D<%VQXVPw!`^>0m+&5~JubU&65 zf568|Euk4BEPgue)OKCg{p-R<-%*KpdpkbXyl86Kd+1R)C>)`xG+iBDahyqxbL=w~ z%W6iU%y_Ekr3VEDi7=x{5c?%61>>~bvO!=nTS?0>AT}o7O|*!ejPsaRZ|z8OHTCPS z3`gf{+a`uP#nB-&aQ4-Z-_I0}Z5|kYB`Ga!?};mC!6UW+QknR2MLvgkz25*4W$=*M zdi7w!lof{LT4^GnL_T_+{3~C9(H^6irY-z+dWLvcrKGJs<-PV9FdyAI;G4Xpq{l|(_oh(ns=QU=6Ou$RHC7yBrG6eQy@*q5s^ZrVeVyQmLIEro{m$N8#PZT2 z`I0XLg0uZMRP$s+H5yhkQ*SsYxZ&>r3}yyXY;%e`iB7N}s&x!N7V0#G%lKDdnL6zR zm?$X7KjmBr{bY~pF`Sz5{aU#Do~XV|#UIjSL8vBRuc8K-{23(r2boYtJ-A->wy2}! zyv!KS3Sj)@wT@ zx>O!K#x-eMnB7m@X&yeTW)NObkED9ZVWwlvLw0sor*SiayhkjpmDE*Bk?3;JtIx`P zxEN?(pcPn}Ijm(#pAY1s-pJ=qFkha(JJl%Fv)03PU4XS`r(kIq%9&|*|Qd291OD5Kys)-9=i zj>JrsVCG6^DjZO zCLp<}plN+cr+L#U!AgPf$3FoJ4KX?CIs+DgGx#NMwDiRu7Dhdv7 zZm4`U5*cY9yjH{ixSg+1P9iwD=Bw zx!}@Ws5k|eSlL@FCDfG>mSUo@6sP^`fiZjOmfr23JW%t^sfxNT1%#?H9M$y5PF>}$ z*7xC?>~>~6wkD|_`9G}b1@FQ4zY9f%%^Qa4)@tsQm~d0NHe=18zkHdUG1Oc(68aiO zMJlZocG^<;n9q#(l*~Jufoe3Chf`C+N$|}sr1;@1;?MA3=G#buD3Phs>iMdHk&K)! z-9b%bjVH+pn#{1q+ML0im5u($NRuWkCjjs+93@gr9ZcC|xX)XPi+oTo%<2a4egBQX zFom&KXJP@-4&c=8sc9~*`e>w=$c}CtYtvT$gz7O3E!`CpZT&wr5@wSR>OFxWxC7zAcaUkngM^iB>c z@qSD|7nh^(K$DmR{R_CP?#9JmB1(`Ic)eYl>NkW>yMsef|I z|L62YS7DQ%^ujU7#|D%HD5m`Q+Aj2}Pr$~$l4!sZGz6ewr!^-h(Qx=ZTs8lvi=P{0a3`7 zu8nUI!vpO@^oBw8dn+}i-O*i_G)?hB8T77UxGmV_u-&r|s)49LG{?3o; zhHI__lR9?$Qtm{@>3M%6X;Vcf9>T8@ym#c$bfUhBIRk0Q>kr&pho$KGt%!qMxe`3^ zTVPS|nkX5Ie&9#G0=4?BWX_k$@OFgPT+Fa?{ zL>fW~lLg_OXDv*>%}&d0Q^c*=2B&KS(nShj9)(gv$!@eZ6XnlFfHfnvW}Hppz2tfW zVbGNW3;LsK*0AI3ro{SQ^OWldyYv3eEdnF@N)!tc%20!I9`c&>DYY{?dsECb9H5b; zJ~olQ1N$~~YuX*S3QFAQ{+=Kz16jH$XGAMw#Sh{G!~ZmsC=o42lLtN+={!(fIaIr3 zjqj{F@DM0lj1O)-i*eK6%LJJ*Y3^4J%){XH^j7uNG44$1LM>$v0HJ8+D#2gB|DjCc zI_(a8?j2&`>N>_IVBq?~SuNCZWTirW{t`feCX=9L6l`#W>|)1F$Wg*UB%(PcvfIF3 zpY2UEBU}}WJ|Thc1(FKasiHKqcdkV9&ZrQUt_4;6wyKlP0Lgn&{kaOCXf_W<`;YP2 zOibU77I_}T5^BrwAuB%&P?*v(V1u*|NOz``u)E= za)*Vua%n5sRP+6kMb1`Hiovzdzboe;SkwW!sTb+y8obfU&Pc=C?j@jRfz`IP@vD1p5|(G5!ZQU3eTs z{=~O@(etJJ;0cb=%b-*)??$29NQQk!M4aIBknW6Z@r-d#FnlVT1fKicYNHLEW` zDJWMk)yWD8%OgGy@)xrS`c`CKh9tcPsHghK4IOVjGga*bAw?FAPZ> zE4ixaK(3ODKXr!NRt8br=2KA4&d3j}MQTx-nw`FCL2>b0Avk2@yWp|vYG!+d@}wlp z+w--R7lL|@&tjojQtBj9xF}yh)qM+rI}Arb?jiE4=Sr^!^$k{=zNxTPPtIlIdE<7& z5b&^Vc=9%+u{NGj5phr<4aIOS-VHESv%s zsaTfUnoNEL2?T{<(kzqtE@t{+o~)egIzS6&k<4*DMGWWUPT z-W`(uA;WQ?3_eC5T#X-^X|wLr(YM_)@F#HN`qqE6zko_;vhYAfH3!fnI9OPF@aYK& z3G4Wu`OJv$lA!p|LlxoT7^&i1KU`cM^n!dTWA$0-=;*^JV(E<-mN%e9ie+^*EFhl=AmyFc?cr84LskY&R)LHy&S$a`bk%!KPmPvWbu7==Y9eHU1dHo5pQ`@< z01o9<5UK(D=npB=HU}(S(qAL0VcGs8EC~zn0B@oqzY>z*`cGNWiPEF?qZZBr-D@&*aHI$S)`@FAvJeF$^Pw zD*=@$rE*wfgCw`P%5`T`V-wz!>=|QCck{XefzGFkHK4rl1vaBzINhHn2=`S-*zN7@ zwt5%A&+#QNF#{Wrqp%rztgG7hk7Q|mBbZ|PWY2UB42aV+GFXgzp!7WVe%T5Fa~^V+ zW@m%{{iG_e-{|l-E-eOawe_(~o*4}0BJ%YAq^EgvK9_R{2bX;%6dDnGvlmsUZ?)N3 zU?EYR_7`YM4Q!X|;OVsf+#-dt+b**M>vb-Y8X^pR(f+dt|Ht$NSG?&i2A90)IO|s@ zKv^7j5JUnM&3r1We6Igdm6Vipfk+64qoNcq>m#2XS9ZSas59PlP?>@OGtj`pycX|s z67=2ILi+l||6A}?T3Oj&xMFwXlkIZysl_}X2r?h+&3!Ut2D-_Ea@*N6N4GwZSy@@g z3s1f)7$A0T+o?G|Gc&p`80zrO%bp?29x0s&HE7?zJ9mkN1vJm9J6&52pTYgqhd703 zjA-8FyCe?8|LUoqM%B@qyL6>zBl5Fg{QnH)h5oI`%--KFlPXZ9%cxwz8dTH@a^nhg zYXM-4Q-x5IoAKFtQEp{7bYv-*GGkFO40?V>k8g z0xxf={!xH_T`hs%eDeE55x98@hT>F%3$LzG14r(Zd8j@+yV4AO`%t*=wv|X!J2>*a zc}*6Tz4FPsQ@AZ>#1Yj6Dvft)mYb4yD|teMk&{7V6R3{wQ%?xW(O%7}DS2A^wE3KS=Bf4VHI;5`Fpn8Y?B8cxO|ar1)wpj48vLBv$?ur2#AMA-QFFmL zU-Jk19sVtK-jmi2WzwU#(P=r>L~APS@pK5nXRSokCS~H%N)_Sx@o0RB3zf}cTwG6& z5VQfqXJ^$vmmH)N#74xX?*b{n!<(HC$XHp?Ws9l^YEV+;y%W-W>E4x1B=+!#5)z2T znC%GepnnI$KuXx}6a+<8D+BoUiQ2R(FmWIIK|Ks)>p_xIXHOHeGT*Nm>BqLRvK zi(jWx=`OqCGDR{qdoq)N@5nJQXc$u7wl{nT;-_1c?Klfy@S49^Bz&HunA?awo(kx$% zo?nNhcTxdxNp4a^R%89toC~=UtES#S>z2&B5^EY!M>&eJEJpiEQ0kuKYA-M4@+FJJ zSfw5^B7w~Rt72DEyf8Pu*5;cp)6R#Re+ao^xLc!pjoW!XYP#RMz$Du_io8;WU;b*E z7gi{AKe;dfrZd1Xm3}TO)sN3EoGA3%su?aF=T3{(qW`R+*VrHiS_<3fn=N9r2qZHn zFVS?(cx)}sr_mmc4oOTRiP_A4UtNA0&sknBXn}*ppcZo z(l-$x>N@y@q5)oe! zYW7~?s$#R<*8rrBp*Lv5otm1$<#8%(yl+&ae%-8!5Ka<27LQQp*pj}pv#F{T1F!=o z+z0~2RY-Qyhy$4`0e((g-&yIL5ciG6$a9eoLk+qmXEmz^)34=E%l?VF`GU)yF;c5b zLeUm-MM3w2GSF%o;E|Pg)yuI)x<@cJr8FV3IN+f>M=WLZ~bC9GZ0|fy-e6b1OB?tQct~X%*@1iz~|EtOU85M|m35 zc}dBRt(z_!`7Oq<4O({CCyRku+wZ8HzY3OV!hW04bkJ4>^fE&P^}y!GX&w)32Gp97 zCu^nUBDP^-^dWXcm0@lqV+xb-U@e413VpSj<9XRPUixdsj2|;JG$br79sYSNhll$` zy}dk;^YIa2P|62%b_(q}88&Wz-xk!EEa?SJ37;-`*s33roKs`oxC8m`uW?<6;p}~$ zzojD4L&20X=0eNT?}jQCg9`qB*URPyYgoQpG^in3DRU<+KW9eCATZVnC6gw-W3S8m z}&Ui-Zsct9*xsS6*(iR(2ro*YZOTmj9kN4GrkYo-4-Yf-;eYIQ>; zX)#kd(k54W~1 zwrJRnmqFVQ>E?Ozma>H9pwkf1@Fqy;AX(r%DlUJi74>xDQ0Ih*lD-Rvm=i#wZ$G%$ zg*)*c$?}z4(;zf?e@y$EE~NV|do=b46wR)MZ*_4=30!k?Gczs{sHWzD=aBJC7sq#! zpQw?XgbyS~Qmce#j_zrfDa|H#FYb6N#5umowG2`?L-pS^)_+fVECV9Xr_lFuQDh`6 z%_4gTE2sU$btS(#Q?WLyVZx@)EeT0)$rX{+hO zhB)rZh^Xa@0xvb1=w)Y*j#Z|ru?#WU{sX}DZN@=E7HBMonHyVrWOb*rx-)fDu;FdN zhv2uc$UgR%TxAgbhUNvuQ**aitgU(rsrkz%?iZQ(pNb)gB7PM87(l+hO?S-?o=5k4 zf=7#Q6!~*6ms5F4HEp-J73sJxC<2Xx+hKnh$oTELLnH4N zHMJtlJ<%Z8Mc_27B^GVZ3alE5d-i*jE@jRw9=ZJ~=EF1Nzcu5X3~QO1+QJX(`!OHp zqZLmHlP1^Hoem8AczRsOdwML{l(H!uN8fT{a?+J&{&v4*WC|{e=B+yE(p?EBs=Wzz zi)DKe2rfca=cUOIPH+#&JztHnG0Tev@WvS+aDh{4_{jD2Gf1$_YQ+wtTQHHh@?#HG z95j71>@)OM=+}5>oW*47!{I@!>E90(YYS0#!owVgAS@Z}OV;7yE#{9L^j7K?{`i91 zk2piy&U~}pCzh6Dl12dy`IDr-7SgbPr2V4j%-Cvozx~Izl>=i9eY|6V1Bn*n#=R}+ zDMSzE7exBT-$u&A7yYasT~WT~#$HYMA^lZ5Ro*F^FUPE@o0v@RVngG;Fmc3sQES71 zrmt@k9*&!}kET{ag{gvl<iYJ{5$bhu9poI3|5O=1tWwTqJZ#-m zG&%}9mCMtb=T&cmeZc#dj-p z4lWUf9-x-Lz^w`21m|~y=u|HL<4xvU39oCzOP`bz2hUl!=reZ2&J%v59WjNHzr;E#7rNPO&rJRpJ6 zecALcHSvns;20g=x3^VW+Y=X7=X85Kvzo`IgzaRK2S`YK>L+xr(2k-NKFCaa53{k9z7~iGaxL1 zVA|)=y-dcYM~ke3zTQ0pI>XMcOdY!v?f;KiAaJT}J>b$xS?JI3Une^b;W5FiZdVd}2e&+dVoT4P?UL9OQ? zNZ6^49CXH|yM7?uz>IQqY}~xE<1*Fr5W0=QjpOrrgKiAH6-i&Av0cP-)OIscICAs( zh6VSrxx&IB9cE-E6`qEaZjdLgp|93j?+&~mgN+xd&Sh?bGKFfQ4gRY_q%gcA{jOT-}|3qscF z*rMUL08wXhLS^A%IkC>VgUk8q&Ykr|1L=jx7tA=3DkSl0M)0-Qq)TUwy!CZ@SqdxN zSflc9@L^X7w@A|BiStUMbo*K%q3Fh7PUP`p4z-d;3qEjAegR>p;ydWV_vH{W*uYoLkWQKnpTEsX2FueRP)xXzoj z3)k=bT20hSJ@^oL=z3P%EHXxs#AVd_JBpz)#-K3_*ShdHZ?w3(558>ai~yC;FODBx zhvF>2?S%XXso*vMw)Zc%R!VN$r6J7jM)^5N_<`)hQdG1vC!#vp8lo1YTf|tYvd%wu zdGEBAx~tXc^V{W+7n?ynqKlABgX9ACqFP0I{A4g=C||)u%D(h@v?etO-Z_;dk$t88 zMP}4u%(n-Z2OvHE(q}zKHHO+mh*eUrkvFRoI}loRxj#O5)i=Mf^U?60L)|%8z-Q1U z6niTEYa|w5jUnBZfebjDrwrVxx(aJEqw?c^#?Rh(q9$H?Mk7Wac{M&5@#t)T-a|Pe zt5RIdiUHQ76s%ST4>O6heRG{86mtCbJ3#L|j@z`_gRMm8% z6xYwu28lw6*Q?@7NLX1!x!p!IG-yJNC@bNpmBx7IXPsFEFKLGNx^-EthgYGt2Us+| z&5kDz|MX5V*7^xom~1|qb}TWOl&tx`baUqaP;Y-6=QhUJM`O!ABWu>1C1e|;ZX!Fy zWQmDL#+a<(VlZe>vP4q0$WoTEMV9Q6wXsIFVxqA|uI2lgzTf-!{`&p(e*b~wCIiL^7ky*uvXmG7ryRG;En zjFRGSHB&?u$%z`c1T1X49a#9us5DnF@+cfH7WF*Bz`Wkm!m$}FcC(of&`W*J(g3z< z(1~j12xNN29>%M*b9mw=!Grs5qjYItRWC}}mbm;4r*(ez=zu4(U`p}o8lT0iO8I~x z{n6z;J22JX+zV4Q(@mb2v_iti47Ji^G|(i6vqyyHoI=u?Y?IHs?K+T$ksE%3>+{r! zg+h_CNElW6|JXF9$ogj`3qi$J4+ST)gv{9k26`+5BIa zj%qhH=e%brDTCD8T;BK@k-lyc#yiSg>v~}~L|Ls|!*Z0Bc29&ks*tNE)dgZ6BR;MW zHLcM0yn<~wvLV+2t6{bx_$cCji}h*d(-ISUJQs>XO7a9S{nz$tR2UMIyHxVFyz3Mv#B32p!I9iyQo}Jd1_?ocisJ2`55Gr&e#o4ljuk9t2mh9t z4lhv=tFN&NS)a(Xo7;K<+^`S&$0u(1=s*_KTNT54ZH@+I@aO7BN(xp&t!idpadrT=F(lF^UGbMQkouY|M zMIf@SHD+Lv&%EQ#H#O1-f}xjaEfaHRuUlnu}N;8=ZGPWOSpb zwU!&V5$c?agl8ABqi73j5|=9~@w~Q+O-Z%>N2g{J+{uohu@r>jwBi{-YI`Vuc!DI; z<#p2y@a>nfF%xV0-k3&x;O(c-5 zYPbJgx@1;G8IFUp*c1VrxFS_t68U3w+%4@i!B21Q^dzgX34~ur}M(2F~8JaVnMVCh_p~sVl{P%2{ znS*dk#n(NvnZ~cK>rm1bTN4@ZV;b|$0Bk3>51!>w+^B9UsI10H+S-mi`!ENss5x{U z+?IUI3O;@-K)EF+Y9e$$aLTsyLn!krT9ByH_fTdUuUkC-O*?cNP6T{PLML_z6OTom zigmW6Lbfee+xA_L+t0ko=_-lkbHPNNuy_FT_1Yv02!BqR?3LV850|v9MLFyDhSq6I z@nv?}Tn*dfXl&Tc$;hhZ2$|MV(XBb#R;^{0K1nG#sGGxOnOhtw>h?cYn0e&$x!=&q z)%RM2JHG78%Yh2zuilNa)Y)?f3UB3=cIA!e89FM}&0}8dnhf<*`rcQ^cjB(iIs1K< zFRP)91MW@n;llf@-}*1)Um$gKub2N}X}plREN-{cq1Iz}qwcwAL2Axt02o|9cv>H5 zM?gBXK+tJ{3Y{^MtmmKgGr zLqn!>v%Pl3(lv4Y0f_tpt9Y45t_GGc3u-q?HkHT&W;*L@ltuM#b@$_zoK9aWLL zKZ0Cf+Ws5!9mK@M&h7^iP2{&r{tkn;1LF8y5e+dMEg9>O0hdjuLQf5Qc^mAlkwMK; zy1{x^4H3HRdX z7SZC3;s`J;DH@RTlbO*ff+K!8rM|Gr{1 zGhGe4=q*^c#0VKhA%>MWnvlWIV&THvlllT5FMyUGa*HJ=x)`+1cyE$0eQB*8stADU z0>lxzpnyQ^EBv6%CatdCHpx(CJUTi`&hZD0`582@6Hkyh_3{ZxZOiL{?Vfj~uN>~j zL2mqz8pkj~Sg1)Z7EMsN=zQD=?{$UO^=J>E=gIkfs=%_3{+}g3$G+~ek4j8_e0lD) z5CU3AF?eAfZ@==pEO;-j#&4jz1Zz6XE5P^gPnm+z4}3;<^a;98>C7%baB=yROy!SPPF1xp7xawQ!y^{`NsXN87f(wV z@JHx}a&2>niEl<&y2WT&UllR;%pL5>ApSub8Yw?A8X~}3l%aXZNbdZDpTwHu>lPN= zI6prZWr4vr0X{Mvq1Bk*A9R{&ZibZ8>7dQUp5>`prKiDESsw**!2j|yT-hJXxj*|K zJp*NJ%>!U~;Ibd>*n02b3Ggj?v;hg{nD~Eei}qjJyI%%r0||wNQgoYu<%ue3(eMLb zdMLScwxK6sFy94|20~2@5K-s{Npr{7obbe;tuJ$BwKG8R1N}m+$aa7aPiKx237U-r)sBhY=DNQd~Xj+AJ^&L22**{5Bq6=Q2OJ_6~OZacnS^q zY_u|qeU6iU+LEE-3iS2%Jey#2b9bjhPG@hvZ}G1E1SVZr$R1YD-hBp83Kf8f4c(UF zj#Za))r2yB*?jxk7?)P|hrg#;;o9}uf6d<7+FHNN)=(-X=!JO*Mm>vLR5XzVCKZ@? zqi@OkFZu2*QB_GYnOsy-vb8Et6{tp_V`8I$y%+5Dt4P&8eA}KrIg*;13J9LGd?i?Z z4IYhtQd{W#M*Q#em{dyC`W2gh94JX&(0>}-`R_S{4)iW(pbv`rg6;zDpbVFcuAs`1 H&XNBDnAF|e diff --git a/docs/Queue/Circular-queue.png b/docs/Queue/Circular-queue.png deleted file mode 100644 index 1694fb223d6a667d805fed2e0386541060325bff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6430 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 diff --git a/docs/Queue/Priority-queue.png b/docs/Queue/Priority-queue.png deleted file mode 100644 index f1cf00be72e48f9ffc23f1c107e38fa335cd5146..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83594 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%0AfQ#L_oSyRiyW> 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 Ziau1_{kJcUDfhMj<>BpKeeqh-zW{Cwlal}d diff --git a/docs/Queue/Problem-Practice.md b/docs/Queue/Problem-Practice.md deleted file mode 100644 index dbdcc7acb..000000000 --- a/docs/Queue/Problem-Practice.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -id: Practice-Problems-on-queue -title: Queue Practice Problems -sidebar_label: Queue Practice Problems -sidebar_position: 9 -Description: Here are some practice problems for queuing data structure divided into topic and width. -tags: [DSA, algorithms, Queue, dsa] ---- - -### Basic Queue Problems: - -- [Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/description) -- [Stack using two Queues](https://www.geeksforgeeks.org/problems/stack-using-two-queues/1) -- [Queue Reversal](https://www.geeksforgeeks.org/problems/queue-reversal/1) -- [Flatten Nested List Iterator](https://leetcode.com/problems/flatten-nested-list-iterator/description/) - -### Circular Queue Problems: - -- [Design Circular Queue](https://leetcode.com/problems/design-circular-queue/description/) -- [Design Circular Deque](https://leetcode.com/problems/design-circular-deque/description/) -- [Maximum Sum Circular Subarray](https://leetcode.com/problems/maximum-sum-circular-subarray/description/) - -### Priority Queue Problems: - -- [K Closest Points to Origin](https://leetcode.com/problems/k-closest-points-to-origin/description/) -- [Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/description/) -- [Path with Maximum Probability](https://leetcode.com/problems/path-with-maximum-probability/description/) -- [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/description/) -- [Find Median from Data Stream](https://leetcode.com/problems/find-median-from-data-stream/description/) - -### Deque (Double-Ended Queue) Problems: - -- [Deque Implementations](https://www.geeksforgeeks.org/problems/deque-implementations/1) -- [Palindrome Check Using Deque](https://leetcode.com/problems/valid-palindrome/description/) -- [Shortest Subarray with Sum at Least K](https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/description/) -- [Design Front Middle Back Queue](https://leetcode.com/problems/design-front-middle-back-queue/description/) -- [First negative in every window of size k](https://www.geeksforgeeks.org/problems/first-negative-integer-in-every-window-of-size-k3345/1) -- [Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/description/) - -### Easy - -- [Stack using two queues](https://www.geeksforgeeks.org/problems/stack-using-two-queues/1?page=1&category=Queue&sortBy=difficulty) -- [Queue using stack](https://www.geeksforgeeks.org/problems/queue-using-stack/1?page=1&category=Queue&sortBy=difficulty) -- [Reverse First K elements of Queue](https://www.geeksforgeeks.org/problems/reverse-first-k-elements-of-queue/1?page=1&category=Queue&sortBy=difficulty) -- [Generate Binary Numbers](https://www.geeksforgeeks.org/problems/generate-binary-numbers-1587115620/1?page=1&category=Queue&sortBy=difficulty) -- [Minimum Cost of ropes](https://www.geeksforgeeks.org/problems/minimum-cost-of-ropes-1587115620/1?page=1&category=Queue&sortBy=difficulty) - -### Medium - -- [IPL 2021 - Match Day 2](https://www.geeksforgeeks.org/problems/ipl-2021-match-day-2--141634/1?page=1&category=Queue&sortBy=difficulty) -- [First negative in every window of size k](https://www.geeksforgeeks.org/problems/first-negative-integer-in-every-window-of-size-k3345/1?page=1&category=Queue&sortBy=difficulty) -- [Print Binary Tree levels in sorted order - ](https://www.geeksforgeeks.org/problems/print-binary-tree-levels-in-sorted-order3241/1?page=2&category=Queue&sortBy=difficulty) -- [Restricted Pacman](https://www.geeksforgeeks.org/problems/restricted-pacman--141631/1?page=2&category=Queue&sortBy=difficulty) -- [Count the Reversals](https://www.geeksforgeeks.org/problems/count-the-reversals0401/1?page=2&category=Queue&sortBy=difficulty) - -### Hard - -- [LRU Cache](https://www.geeksforgeeks.org/problems/lru-cache/1?page=2&category=Queue&sortBy=difficulty) -- [Steps by Knight](https://www.geeksforgeeks.org/problems/steps-by-knight5927/1?page=2&category=Queue&sortBy=difficulty) -- [Complete Binary Tree](https://www.geeksforgeeks.org/problems/complete-binary-tree/1?page=2&category=Queue&sortBy=difficulty) -- [Card Rotation](https://www.geeksforgeeks.org/problems/card-rotation5834/1?page=2&category=Queue&sortBy=difficulty) -- [Police and Thieves](https://www.geeksforgeeks.org/problems/police-and-thieves--141631/1?page=2&category=Queue&sortBy=difficulty) diff --git a/docs/Queue/Two-Stack-Queue.md b/docs/Queue/Two-Stack-Queue.md deleted file mode 100644 index 24763c19f..000000000 --- a/docs/Queue/Two-Stack-Queue.md +++ /dev/null @@ -1,203 +0,0 @@ ---- -id: two-stack-queue -title: Two-Stack Queue Implementation -sidebar_label: Two-Stack Queue -sidebar_position: 10 -description: A guide to implementing a queue using two stacks with a lazy transfer approach for efficient operations. -tags: [data structure, queue, stack] ---- - -# Two-Stack Queue Implementation - -This project implements a queue data structure using two stacks with a lazy transfer approach. The implementation provides O(1) amortized time complexity for both enqueue and dequeue operations. - -## Algorithm Overview - -The implementation uses two stacks: -- `inStack`: Used for enqueueing elements -- `outStack`: Used for dequeueing elements - -### Key Operations - -1. **Enqueue**: Push elements directly onto `inStack` - O(1) -2. **Dequeue**: - - If `outStack` is empty, transfer all elements from `inStack` to `outStack` - - Pop and return the top element from `outStack` - - Amortized O(1) - -## Implementation - -```c -#include -#include -#include - -#define MAX_SIZE 100 - -typedef struct { - int items[MAX_SIZE]; - int top; -} Stack; - -typedef struct { - Stack* inStack; - Stack* outStack; -} Queue; - -// Stack operations -void initStack(Stack* s) { - s->top = -1; -} - -bool isEmpty(Stack* s) { - return s->top == -1; -} - -bool isFull(Stack* s) { - return s->top == MAX_SIZE - 1; -} - -void push(Stack* s, int value) { - if (!isFull(s)) { - s->items[++s->top] = value; - } -} - -int pop(Stack* s) { - if (!isEmpty(s)) { - return s->items[s->top--]; - } - return -1; // Error value -} - -Queue* createQueue() { - Queue* q = (Queue*)malloc(sizeof(Queue)); - q->inStack = (Stack*)malloc(sizeof(Stack)); - q->outStack = (Stack*)malloc(sizeof(Stack)); - initStack(q->inStack); - initStack(q->outStack); - return q; -} - -void enqueue(Queue* q, int value) { - push(q->inStack, value); -} - -int dequeue(Queue* q) { - if (isEmpty(q->outStack)) { - // Transfer elements from inStack to outStack - while (!isEmpty(q->inStack)) { - push(q->outStack, pop(q->inStack)); - } - } - return pop(q->outStack); -} - -bool isQueueEmpty(Queue* q) { - return isEmpty(q->inStack) && isEmpty(q->outStack); -} - -void destroyQueue(Queue* q) { - free(q->inStack); - free(q->outStack); - free(q); -} -``` - -## Usage Example - -```c -int main() { - Queue* q = createQueue(); - - enqueue(q, 1); - enqueue(q, 2); - enqueue(q, 3); - - printf("%d\n", dequeue(q)); // Output: 1 - printf("%d\n", dequeue(q)); // Output: 2 - - enqueue(q, 4); - - printf("%d\n", dequeue(q)); // Output: 3 - printf("%d\n", dequeue(q)); // Output: 4 - - destroyQueue(q); - return 0; -} -``` -### Complexity - -- **Time Complexity**: - - **Enqueue**: $O(1)$ - - **Dequeue**: Amortized $O(1)$ -- **Space Complexity**: $O(n)$, where $n$ is the number of elements in the queue. - -### Example - -Consider a queue with the following operations: - -1. **Enqueue 1** -2. **Enqueue 2** -3. **Dequeue** -4. **Enqueue 3** -5. **Dequeue** - -**Operations Breakdown**: - -- **Enqueue 1**: - - `inStack`: [1] - - `outStack`: [] - -- **Enqueue 2**: - - `inStack`: [1, 2] - - `outStack`: [] - -- **Dequeue**: - - Transfer elements from `inStack` to `outStack`: - - `inStack`: [] - - `outStack`: [2, 1] - - Pop from `outStack`: 1 - - Result: - - `inStack`: [] - - `outStack`: [2] - -- **Enqueue 3**: - - `inStack`: [3] - - `outStack`: [2] - -- **Dequeue**: - - Pop from `outStack`: 2 - - Result: - - `inStack`: [3] - - `outStack`: [] - -### Conclusion - -Implementing a queue using two stacks is an efficient way to achieve the FIFO behavior with LIFO structures. This approach ensures that both the **enqueue** and **dequeue** operations have an amortized constant time complexity, making it suitable for applications where performance and resource management are critical. - -## Flowchart - -```mermaid -flowchart TD - A[Start] --> B{Operation Type} - - B -->|Enqueue| C[Push to inStack] - C --> D[Done] - - B -->|Dequeue| E{outStack Empty?} - E -->|Yes| F[Transfer all elements from inStack to outStack] - E -->|No| G[Pop from outStack] - F --> G - G --> D - - subgraph Transfer Process - H[Pop from inStack] --> I[Push to outStack] - I --> J{inStack Empty?} - J -->|No| H - J -->|Yes| K[Transfer Complete] - end - - D --> K - K --> L[End] -``` \ No newline at end of file diff --git a/docs/Queue/_category_.json b/docs/Queue/_category_.json deleted file mode 100644 index 9eae28be6..000000000 --- a/docs/Queue/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Queue", - "position": 10, - "link": { - "type": "generated-index", - "description": "Learn the most important and widely used concepts of Queue." - } - } \ No newline at end of file diff --git a/docs/Queue/blocked-queue.md b/docs/Queue/blocked-queue.md deleted file mode 100644 index e58583639..000000000 --- a/docs/Queue/blocked-queue.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -id: blocked-queue-in-dsa -title: Blocked Queue Data Structure -sidebar_label: Blocked Queue -sidebar_position: 1 -description: "A blocked queue is a linear data structure that operates on the First In First Out (FIFO) principle but includes mechanisms to block and unblock threads when the queue is empty or full. This is particularly useful in concurrent programming." -tags: [dsa, data-structures, BlockedQueue] ---- - -### Introduction to Blocked Queue - -A **blocked queue** is a linear data structure that follows the First In First Out (FIFO) principle, similar to a regular queue. However, it includes mechanisms to block and unblock threads when the queue is empty or full. This is particularly useful in concurrent programming where multiple threads may need to access the queue simultaneously. - -![alt text](Blocked-queue.png) - -### Blocked Queue Operations - -1. **Enqueue**: Add an element to the back of the queue. -2. **Dequeue**: Remove the element from the front of the queue. -3. **Peek**: Retrieve the element at the front of the queue without removing it. -4. **isEmpty**: Check if the queue is empty. -5. **isFull**: Check if the queue is full. -6. **Size**: Get the number of elements in the queue. - -### Pseudocode - -#### Basic Operations - -1. **Enqueue**: - - ```text - function enqueue(blockedQueue, element): - if isFull(blockedQueue): - blockThread() // Block the thread until space is available - blockedQueue.rear = (blockedQueue.rear + 1) % blockedQueue.size - blockedQueue.elements[blockedQueue.rear] = element - unblockThread() // Unblock any waiting threads - ``` - -2. **Dequeue**: - - ```text - function dequeue(blockedQueue): - if isEmpty(blockedQueue): - blockThread() // Block the thread until an element is available - frontElement = blockedQueue.elements[blockedQueue.front] - blockedQueue.front = (blockedQueue.front + 1) % blockedQueue.size - unblockThread() // Unblock any waiting threads - return frontElement - ``` - -3. **Peek**: - - ```text - function peek(blockedQueue): - if isEmpty(blockedQueue): - return "Queue is empty" - return blockedQueue.elements[blockedQueue.front] - ``` - -4. **isEmpty**: - - ```text - function isEmpty(blockedQueue): - return blockedQueue.front == blockedQueue.rear - ``` - -5. **isFull**: - - ```text - function isFull(blockedQueue): - return (blockedQueue.rear + 1) % blockedQueue.size == blockedQueue.front - ``` - -6. **Size**: - - ```text - function size(blockedQueue): - return (blockedQueue.rear - blockedQueue.front + blockedQueue.size) % blockedQueue.size - ``` - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -import threading - -class BlockedQueue: - def __init__(self, size): - self.size = size - self.elements = [None] * size - self.front = 0 - self.rear = 0 - self.lock = threading.Lock() - self.not_empty = threading.Condition(self.lock) - self.not_full = threading.Condition(self.lock) - - def enqueue(self, element): - with self.not_full: - while self.is_full(): - self.not_full.wait() - self.rear = (self.rear + 1) % self.size - self.elements[self.rear] = element - self.not_empty.notify() - - def dequeue(self): - with self.not_empty: - while self.is_empty(): - self.not_empty.wait() - frontElement = self.elements[self.front] - self.front = (self.front + 1) % self.size - self.not_full.notify() - return frontElement - - def peek(self): - with self.lock: - if self.is_empty(): - return "Queue is empty" - return self.elements[self.front] - - def is_empty(self): - return self.front == self.rear - - def is_full(self): - return (self.rear + 1) % self.size == self.front - - def size(self): - return (self.rear - self.front + self.size) % self.size - -# Example usage -bq = BlockedQueue(5) -bq.enqueue(10) -bq.enqueue(20) -print(bq.dequeue()) # Output: 10 -print(bq.peek()) # Output: 20 -print(bq.is_empty()) # Output: False -print(bq.size()) # Output: 1 -``` - -#### C++ Implementation - -```cpp -#include -#include -#include -using namespace std; - -class BlockedQueue { -private: - int *elements; - int front, rear, size; - mutex mtx; - condition_variable not_empty, not_full; - -public: - BlockedQueue(int size) { - this->size = size; - elements = new int[size]; - front = rear = 0; - } - - void enqueue(int element) { - unique_lock lock(mtx); - not_full.wait(lock, [this] { return !is_full(); }); - rear = (rear + 1) % size; - elements[rear] = element; - not_empty.notify_one(); - } - - int dequeue() { - unique_lock lock(mtx); - not_empty.wait(lock, [this] { return !is_empty(); }); - int frontElement = elements[front]; - front = (front + 1) % size; - not_full.notify_one(); - return frontElement; - } - - int peek() { - lock_guard lock(mtx); - if (is_empty()) { - cout << "Queue is empty" << endl; - return -1; // Indicating empty - } - return elements[front]; - } - - bool is_empty() { - return front == rear; - } - - bool is_full() { - return (rear + 1) % size == front; - } - - int size_of_queue() { - return (rear - front + size) % size; - } - - ~BlockedQueue() { - delete[] elements; - } -}; - -// Example usage -int main() { - BlockedQueue bq(5); - bq.enqueue(10); - bq.enqueue(20); - cout << bq.dequeue() << endl; // Output: 10 - cout << bq.peek() << endl; // Output: 20 - cout << boolalpha << bq.is_empty() << endl; // Output: false - cout << bq.size_of_queue() << endl; // Output: 1 - return 0; -} -``` - -#### Java Implementation - -```java -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -public class BlockedQueue { - private int[] elements; - private int front, rear, size; - private final Lock lock = new ReentrantLock(); - private final Condition notEmpty = lock.newCondition(); - private final Condition notFull = lock.newCondition(); - - public BlockedQueue(int size) { - this.size = size; - elements = new int[size]; - front = rear = 0; - } - - public void enqueue(int element) { - lock.lock(); - try { - while (is_full()) { - notFull.await(); - } - rear = (rear + 1) % size; - elements[rear] = element; - notEmpty.signal(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } finally { - lock.unlock(); - } - } - - public int dequeue() { - lock.lock(); - try { - while (is_empty()) { - notEmpty.await(); - } - int frontElement = elements[front]; - front = (front + 1) % size; - notFull.signal(); - return frontElement; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return -1; // Indicating underflow - } finally { - lock.unlock(); - } - } - - public int peek() { - lock.lock(); - try { - if (is_empty()) { - System.out.println("Queue is empty"); - return -1; // Indicating empty - } - return elements[front]; - } finally { - lock.unlock(); - } - } - - public boolean is_empty() { - return front == rear; - } - - public boolean is_full() { - return (rear + 1) % size == front; - } - - public int size_of_queue() { - return (rear - front + size) % size; - } - - public static void main(String[] args) { - BlockedQueue bq = new BlockedQueue(5); - bq.enqueue(10); - bq.enqueue(20); - System.out.println(bq.dequeue()); // Output: 10 - System.out.println(bq.peek()); // Output: 20 - System.out.println(bq.is_empty()); // Output: false - System.out.println(bq.size_of_queue()); // Output: 1 - } -} -``` - -### Complexity --**Time Complexity**: - - - Enqueue: $O(1)$ - - Dequeue: $O(1)$ - - Peek: $O(1)$ - - isEmpty: $O(1)$ - - isFull: $O(1)$ - - Size: $O(1)$ --**Space Complexity**: $O(n)$, where $n$ is the number of elements that can be stored in the blocked queue. - -### Example - -Consider a blocked queue with the following operations: - -1. Enqueue 10 -2. Enqueue 20 -3. Dequeue -4. Peek -5. Check if empty -6. Get size - -**Operations**: - -- Enqueue 10: Queue becomes [10, _, _, _, _] -- Enqueue 20: Queue becomes [10, 20, _, _, _] -- Dequeue: Removes 10, Queue becomes [_, 20, _, _, _] -- Peek: Returns 20, Queue remains [_, 20, _, _, _] -- isEmpty: Returns false -- Size: Returns 1 - -### Conclusion - -A blocked queue is an efficient data structure that improves the utilization of space and provides thread safety in concurrent programming scenarios. It is widely used in applications such as producer-consumer problems, task scheduling, and resource management. Understanding and implementing a blocked queue can significantly enhance performance and synchronization in multi-threaded environments. \ No newline at end of file diff --git a/docs/Queue/check-palindrome-using-dequeue.md b/docs/Queue/check-palindrome-using-dequeue.md deleted file mode 100644 index 740e3554f..000000000 --- a/docs/Queue/check-palindrome-using-dequeue.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: check-palindrome-using-deque -title: "Check Palindrome Using Deque" -sidebar_label: "Palindrome Check with Deque" -sidebar_position: 9 -description: "A guide to checking if a string is a palindrome using a deque data structure for efficient operations." -tags: [data structure, deque, palindrome] ---- - -# Check Palindrome Using Deque - -A palindrome is a string that reads the same forwards and backwards. This guide explains how to check if a string is a palindrome using a **deque** (double-ended queue) data structure, which allows for efficient operations at both ends. - -## Introduction - -Using a deque to check for palindromes leverages its ability to add or remove elements from both ends in constant time. This makes it a suitable choice for the task, as we can compare characters from the front and back of the string until we reach the center. - -![](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwWr4bJaQGsjcIJzTxYf_KG-rUl7g8lpQWlw&s) - -## Steps to Check Palindrome - -1. **Add** each character of the string to the deque. -2. **Remove and compare** characters from both ends of the deque until the middle is reached. -3. If all pairs match, the string is a palindrome; otherwise, it is not. - -## Implementation - -### Python Code - -```cpp - -#include -#include -#include -using namespace std; - -bool isPalindrome(const string& s) { - deque d; - - // Load the deque with each character from the string - for (char ch : s) { - d.push_back(ch); - } - - // Compare characters from both ends - while (d.size() > 1) { - if (d.front() != d.back()) { - return false; // Not a palindrome if characters don't match - } - d.pop_front(); // Remove the front character - d.pop_back(); // Remove the back character - } - - return true; // All pairs matched, so it is a palindrome -} - -int main() { - string str1 = "radar"; - cout << str1 << " is a palindrome: " << (isPalindrome(str1) ? "True" : "False") << endl; - - string str2 = "hello"; - cout << str2 << " is a palindrome: " << (isPalindrome(str2) ? "True" : "False") << endl; - - return 0; -} -``` -## Complexity -### Time Complexity: -is_palindrome: -𝑂(𝑛) -O(n), where 𝑛 is the length of the string (since each character is dequeued once from both ends). -### Space Complexity: 𝑂(𝑛) -O(n), where 𝑛 is the number of characters in the deque. - -## Explanation of Code - -Initialize a deque with the characters of the string. -Use a while loop to repeatedly remove characters from the front and back of the deque. -Return False if any character pair doesn't match; otherwise, return True when the loop completes. - -## Applications -The palindrome check has applications in string processing, data validation, and computer science algorithms. Deques provide an efficient way to check for palindromes with minimal memory overhead. \ No newline at end of file diff --git a/docs/Queue/circular-queue.md b/docs/Queue/circular-queue.md deleted file mode 100644 index 11a49a27f..000000000 --- a/docs/Queue/circular-queue.md +++ /dev/null @@ -1,397 +0,0 @@ ---- -id: circular-queue-in-dsa -title: Circular Queue Data Structure -sidebar_label: Circular Queue -sidebar_position: 3 -description: "A circular queue is a linear data structure that operates on the First In First Out (FIFO) principle but utilizes a circular arrangement for its storage. This allows for efficient use of space and reduces the overhead associated with traditional linear queues." -tags: [dsa, data-structures, CircularQueue] ---- - -### Introduction to Circular Queue - -A circular queue is a linear data structure that follows the First In First Out (FIFO) principle, similar to a regular queue. However, in a circular queue, the last position is connected back to the first position to form a circle. This circular arrangement allows for efficient use of space, as it enables the queue to utilize any free space created by dequeue operations without shifting elements. - -![alt text](Circular-queue.png) - -### Circular Queue Operations - -1. **Enqueue**: Add an element to the back of the queue. -2. **Dequeue**: Remove the element from the front of the queue. -3. **Peek**: Retrieve the element at the front of the queue without removing it. -4. **isEmpty**: Check if the queue is empty. -5. **isFull**: Check if the queue is full. -6. **Size**: Get the number of elements in the queue. - -### Pseudocode - -#### Basic Operations - -1. **Enqueue**: - - ```text - function enqueue(circularQueue, element): - if isFull(circularQueue): - return "Queue Overflow" - circularQueue.rear = (circularQueue.rear + 1) % circularQueue.size - circularQueue.elements[circularQueue.rear] = element - ``` - -2. **Dequeue**: - - ```text - function dequeue(circularQueue): - if isEmpty(circularQueue): - return "Queue Underflow" - frontElement = circularQueue.elements[circularQueue.front] - circularQueue.front = (circularQueue.front + 1) % circularQueue.size - return frontElement - ``` - -3. **Peek**: - - ```text - function peek(circularQueue): - if isEmpty(circularQueue): - return "Queue is empty" - return circularQueue.elements[circularQueue.front] - ``` - -4. **isEmpty**: - - ```text - function isEmpty(circularQueue): - return circularQueue.front == circularQueue.rear - ``` - -5. **isFull**: - - ```text - function isFull(circularQueue): - return (circularQueue.rear + 1) % circularQueue.size == circularQueue.front - ``` - -6. **Size**: - - ```text - function size(circularQueue): - return (circularQueue.rear - circularQueue.front + circularQueue.size) % circularQueue.size - ``` - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -class CircularQueue: - def __init__(self, size): - self.size = size - self.elements = [None] * size - self.front = 0 - self.rear = 0 - - def enqueue(self, element): - if self.is_full(): - return "Queue Overflow" - self.rear = (self.rear + 1) % self.size - self.elements[self.rear] = element - - def dequeue(self): - if self.is_empty(): - return "Queue Underflow" - frontElement = self.elements[self.front] - self.front = (self.front + 1) % self.size - return frontElement - - def peek(self): - if self.is_empty(): - return "Queue is empty" - return self.elements[self.front] - - def is_empty(self): - return self.front == self.rear - - def is_full(self): - return (self.rear + 1) % self.size == self.front - - def size(self): - return (self.rear - self.front + self.size) % self.size - -# Example usage -cq = CircularQueue(5) -cq.enqueue(10) -cq.enqueue(20) -print(cq.dequeue()) # Output: 10 -print(cq.peek()) # Output: 20 -print(cq.is_empty()) # Output: False -print(cq.size()) # Output: 1 -``` - -#### C++ Implementation - -```cpp -#include -using namespace std; - -class CircularQueue { -private: - int *elements; - int front, rear, size; - -public: - CircularQueue(int size) { - this->size = size; - elements = new int[size]; - front = rear = 0; - } - - void enqueue(int element) { - if (is_full()) { - cout << "Queue Overflow" << endl; - return; - } - rear = (rear + 1) % size; - elements[rear] = element; - } - - int dequeue() { - if (is_empty()) { - cout << "Queue Underflow" << endl; - return -1; // Indicating underflow - } - int frontElement = elements[front]; - front = (front + 1) % size; - return frontElement; - } - - int peek() { - if (is_empty()) { - cout << "Queue is empty" << endl; - return -1; // Indicating empty - } - return elements[front]; - } - - bool is_empty() { - return front == rear; - } - - bool is_full() { - return (rear + 1) % size == front; - } - - int size_of_queue() { - return (rear - front + size) % size; - } - - ~CircularQueue() { - delete[] elements; - } -}; - -// Example usage -int main() { - CircularQueue cq(5); - cq.enqueue(10); - cq.enqueue(20); - cout << cq.dequeue() << endl; // Output: 10 - cout << cq.peek() << endl; // Output: 20 - cout << boolalpha << cq.is_empty() << endl; // Output: false - cout << cq.size_of_queue() << endl; // Output: 1 - return 0; -} -``` - -#### Java Implementation - -```java -public class CircularQueue { - private int[] elements; - private int front, rear, size; - - public CircularQueue(int size) { - this.size = size; - elements = new int[size]; - front = rear = 0; - } - - public void enqueue(int element) { - if (is_full()) { - System.out.println("Queue Overflow"); - return; - } - rear = (rear + 1) % size; - elements[rear] = element; - } - - public int dequeue() { - if (is_empty()) { - System.out.println("Queue Underflow"); - return -1; // Indicating underflow - } - int frontElement = elements[front]; - front = (front + 1) % size; - return frontElement; - } - - public int peek() { - if (is_empty()) { - System.out.println("Queue is empty"); - return -1; // Indicating empty - } - return elements[front]; - } - - public boolean is_empty() { - return front == rear; - } - - public boolean is_full() { - return (rear + 1) % size == front; - } - - public int size_of_queue() { - return (rear - front + size) % size; - } - - // Example usage - public static void main(String[] args) { - CircularQueue cq = new CircularQueue(5); - cq.enqueue(10); - cq.enqueue(20); - System.out.println(cq.dequeue()); // Output: 10 - System.out.println(cq.peek()); // Output: 20 - System.out.println(cq.is_empty()); // Output: false - System.out.println(cq.size_of_queue()); // Output: 1 - } -} -``` - - -#### C Implementation - -```C -#include - -#define SIZE 5 - -int items[SIZE]; -int front = -1, rear = -1; - -// Check if the queue is full -int isFull() { - return (front == (rear + 1) % SIZE) || (front == 0 && rear == SIZE - 1); -} - -// Check if the queue is empty -int isEmpty() { - return front == -1; -} - -// Add an element to the queue -void enQueue(int element) { - if (isFull()) { - printf("\nQueue is full!!\n"); - } else { - if (isEmpty()) { - front = 0; - } - rear = (rear + 1) % SIZE; - items[rear] = element; - printf("\nInserted -> %d", element); - } -} - -// Remove an element from the queue -int deQueue() { - if (isEmpty()) { - printf("\nQueue is empty!!\n"); - return -1; - } else { - int element = items[front]; - if (front == rear) { // Queue has only one element - front = -1; - rear = -1; - } else { - front = (front + 1) % SIZE; - } - printf("\nDeleted element -> %d\n", element); - return element; - } -} - -// Display the elements in the queue -void display() { - if (isEmpty()) { - printf("\nEmpty Queue\n"); - } else { - printf("\nFront -> %d\n", front); - printf("Items -> "); - for (int i = front; i != rear; i = (i + 1) % SIZE) { - printf("%d ", items[i]); - } - printf("%d ", items[rear]); // Print the last element - printf("\nRear -> %d\n", rear); - } -} - -int main() { - deQueue(); // Attempt to dequeue from an empty queue - - enQueue(1); - enQueue(2); - enQueue(3); - enQueue(4); - enQueue(5); - - enQueue(6); // Attempt to enqueue into a full queue - - display(); // Display the queue - - deQueue(); // Dequeue one element - display(); // Display the queue again - - enQueue(7); // Enqueue one element to test circular queue functionality - display(); // Display the queue - - enQueue(8); // Attempt to enqueue into a full queue - - return 0; -} - -``` -### Complexity - -- **Time Complexity**: - - - Enqueue: $O(1)$ - - Dequeue: $O(1)$ - - Peek: $O(1)$ - - isEmpty: $O(1)$ - - isFull: $O(1)$ - - Size: $O(1)$ - -- **Space Complexity**: $O(n)$, where $n$ is the number of elements that can be stored in the circular queue. - -### Example - -Consider a circular queue with the following operations: - -1. Enqueue 10 -2. Enqueue 20 -3. Dequeue -4. Peek -5. Check if empty -6. Get size - -**Operations**: - -- Enqueue 10: Queue becomes [10, _, _, _, _] -- Enqueue 20: Queue becomes [10, 20, _, _, _] -- Dequeue: Removes 10, Queue becomes [_, 20, _, _, _] -- Peek: Returns 20, Queue remains [_, 20, _, _, _] -- isEmpty: Returns false -- Size: Returns 1 - -### Conclusion - -A circular queue is an efficient data structure that improves the utilization of space in scenarios where a standard linear queue might lead to wasted memory due to the shifting of elements. It is widely used in applications such as CPU scheduling, resource sharing, and buffering tasks in operating systems. Understanding and implementing a circular queue can significantly enhance performance and memory management in various algorithms and systems. diff --git a/docs/Queue/concurrent-queue.md b/docs/Queue/concurrent-queue.md deleted file mode 100644 index 7c9a5260c..000000000 --- a/docs/Queue/concurrent-queue.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: concurrent-queue-data-structure -title: "Concurrent Queue Data Structure" -sidebar_label: "Concurrent Queue" -sidebar_position: 8 -description: "A comprehensive guide to using the concurrent queue data structure for safe multithreading operations." -tags: [data structure, concurrency, multithreading] ---- - -# Concurrent Queue Data Structure - -A concurrent queue is a thread-safe data structure designed for safe access by multiple threads. It allows efficient queue operations while ensuring data integrity and preventing race conditions. - -## Introduction - -A concurrent queue follows the First In First Out (FIFO) principle, allowing multiple threads to perform enqueue and dequeue operations safely without explicit locks. This makes it ideal for multithreading environments. - -![](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQWItU6BP0_HnsEQmw-ofD-LWef-uGJSoNvJQ&s) - -## Operations - -1. **Enqueue**: Add an element to the back of the queue. -2. **Dequeue**: Remove the element from the front of the queue. -3. **Peek**: Retrieve the element at the front of the queue without removing it. -4. **isEmpty**: Check if the queue is empty. -5. **isFull**: Check if the queue is full. -6. **Size**: Get the number of elements in the queue. - -## Implementation - -### Python Code - -```python -import threading - -class ConcurrentQueue: - def __init__(self, size): - self.size = size - self.elements = [None] * size - self.front = 0 - self.rear = 0 - self.lock = threading.Lock() - - def enqueue(self, element): - with self.lock: - if self.is_full(): - return "Queue Overflow" - self.rear = (self.rear + 1) % self.size - self.elements[self.rear] = element - - def dequeue(self): - with self.lock: - if self.is_empty(): - return "Queue Underflow" - frontElement = self.elements[self.front] - self.front = (self.front + 1) % self.size - return frontElement - - def peek(self): - with self.lock: - if self.is_empty(): - return "Queue is empty" - return self.elements[self.front] - - def is_empty(self): - with self.lock: - return self.front == self.rear - - def is_full(self): - with self.lock: - return (self.rear + 1) % self.size == self.front - - def size_of_queue(self): - with self.lock: - return (self.rear - self.front + self.size) % self.size - -# Example usage -if __name__ == "__main__": - cq = ConcurrentQueue(5) - cq.enqueue(10) - cq.enqueue(20) - print(cq.dequeue()) # Output: 10 - print(cq.peek()) # Output: 20 - print(cq.is_empty()) # Output: False - print(cq.size_of_queue()) # Output: 1 -``` - -## Complexity - -- **Time Complexity**: - - **Enqueue**: \(O(1)\) - - **Dequeue**: \(O(1)\) - - **Peek**: \(O(1)\) - - **isEmpty**: \(O(1)\) - - **isFull**: \(O(1)\) - - **Size**: \(O(1)\) - -- **Space Complexity**: \(O(n)\), where \(n\) is the maximum number of elements that can be stored in the queue. - -## Conclusion - -The concurrent queue is an efficient data structure that simplifies multithreading operations by automatically managing synchronization. It is particularly useful in scenarios such as task scheduling, producer-consumer problems, and buffering tasks in concurrent systems. By ensuring thread safety and minimizing the need for explicit locks, it enhances performance and simplifies the design of concurrent applications. - diff --git a/docs/Queue/design-circular-Dueque.md b/docs/Queue/design-circular-Dueque.md deleted file mode 100644 index 249220e3a..000000000 --- a/docs/Queue/design-circular-Dueque.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -id: circular-deque-dsa -title: Circular Deque Data Structure -sidebar_label: Circular Deque -sidebar_position: 6 -description: "A circular deque is a double-ended queue data structure that connects the rear and front ends to form a circular structure, allowing insertion and deletion from both ends. This structure is ideal for scenarios requiring dynamic insertion and deletion at both ends." -tags: [dsa, data-structures, Circular Deque] ---- - - - -## Introduction to Circular Deque -A circular deque (double-ended queue) is an advanced linear data structure that extends the concept of a circular queue by allowing insertion and deletion of elements from both the front and rear ends. This structure offers flexibility for applications that require dynamic additions and removals at both ends, such as real-time task scheduling, caching, and managing resource pools efficiently. - -## Circular Deque Operations -#### InsertFront: Add an element to the front of the deque. -#### InsertRear: Add an element to the rear of the deque. -#### DeleteFront: Remove an element from the front of the deque. -#### DeleteRear: Remove an element from the rear of the deque. -#### PeekFront: Retrieve the front element without removing it. -#### PeekRear: Retrieve the rear element without removing it. -#### isEmpty: Check if the deque is empty. -#### isFull: Check if the deque is full. - - -```cpp -#include -using namespace std; - -class CircularDeque { -private: - int *elements; - int front, rear, size, capacity; - -public: - CircularDeque(int capacity) { - this->capacity = capacity; - elements = new int[capacity]; - front = -1; - rear = 0; - size = 0; - } - - bool insertFront(int element) { - if (is_full()) { - cout << "Deque Overflow" << endl; - return false; - } - front = (front == -1) ? 0 : (front - 1 + capacity) % capacity; - elements[front] = element; - size++; - return true; - } - - bool insertRear(int element) { - if (is_full()) { - cout << "Deque Overflow" << endl; - return false; - } - rear = (rear + 1) % capacity; - elements[rear] = element; - size++; - return true; - } - - int deleteFront() { - if (is_empty()) { - cout << "Deque Underflow" << endl; - return -1; - } - int frontElement = elements[front]; - front = (front + 1) % capacity; - size--; - return frontElement; - } - - int deleteRear() { - if (is_empty()) { - cout << "Deque Underflow" << endl; - return -1; - } - int rearElement = elements[rear]; - rear = (rear - 1 + capacity) % capacity; - size--; - return rearElement; - } - - int peekFront() { - if (is_empty()) { - cout << "Deque is empty" << endl; - return -1; - } - return elements[front]; - } - - int peekRear() { - if (is_empty()) { - cout << "Deque is empty" << endl; - return -1; - } - return elements[rear]; - } - - bool is_empty() { - return size == 0; - } - - bool is_full() { - return size == capacity; - } - - ~CircularDeque() { - delete[] elements; - } -}; - -// Example usage -int main() { - CircularDeque deque(5); - deque.insertFront(10); - deque.insertRear(20); - cout << deque.peekFront() << endl; // Output: 10 - cout << deque.peekRear() << endl; // Output: 20 - deque.deleteFront(); - cout << deque.is_empty() << endl; // Output: false - deque.deleteRear(); - cout << deque.is_empty() << endl; // Output: true - return 0; -} -``` -## Complexity Analysis - -### Time Complexity: - -InsertFront: $O(1)$ -InsertRear: $O(1)$ -DeleteFront: $O(1)$ -DeleteRear: $O(1)$ -PeekFront and PeekRear: $O(1)$ -isEmpty and isFull: $O(1)$ - -### Space Complexity: -$O(n)$, where $n$ is the maximum number of elements in the deque (capacity). \ No newline at end of file diff --git a/docs/Queue/design-circular-Queue.md b/docs/Queue/design-circular-Queue.md deleted file mode 100644 index a98734e6b..000000000 --- a/docs/Queue/design-circular-Queue.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: circular-queue-dsa -title: Circular Queue Data Structure -sidebar_label: Circular Queue -sidebar_position: 5 -description: "A circular queue is a linear data structure that connects the rear and front ends to form a circular structure. This makes it efficient for resource management and suitable for scenarios where data needs to be processed in a round-robin fashion." -tags: [dsa, data-structures, Circular Queue] ---- - -### Introduction to Circular Queue - -A **circular queue** is a linear data structure that connects the last position to the first to form a circular structure. Unlike a standard queue, a circular queue efficiently reuses memory by connecting the rear end back to the front, making it ideal for applications like CPU scheduling, managing shared resources, and handling real-time data streams. - - -### Circular Queue Operations - -1. **Enqueue**: Add an element to the rear of the queue. -2. **Dequeue**: Remove an element from the front of the queue. -3. **PeekFront**: Retrieve the element at the front without removing it. -4. **PeekRear**: Retrieve the element at the rear without removing it. -5. **isEmpty**: Check if the queue is empty. -6. **isFull**: Check if the queue is full. - -### Pseudocode for Basic Operations - -#### Enqueue - -```cpp -#include -using namespace std; - -class CircularQueue { -private: - int *elements; - int front, rear, size; - -public: - CircularQueue(int size) { - this->size = size; - elements = new int[size]; - front = rear = 0; - } - - void enqueue(int element) { - if (is_full()) { - cout << "Queue Overflow" << endl; - return; - } - rear = (rear + 1) % size; - elements[rear] = element; - } - - int dequeue() { - if (is_empty()) { - cout << "Queue Underflow" << endl; - return -1; - } - int frontElement = elements[front]; - front = (front + 1) % size; - return frontElement; - } - - int peek_front() { - if (is_empty()) { - cout << "Queue is empty" << endl; - return -1; - } - return elements[front]; - } - - int peek_rear() { - if (is_empty()) { - cout << "Queue is empty" << endl; - return -1; - } - return elements[rear]; - } - - bool is_empty() { - return front == rear; - } - - bool is_full() { - return (rear + 1) % size == front; - } - - ~CircularQueue() { - delete[] elements; - } -}; - -// Example usage -int main() { - CircularQueue cq(5); - cq.enqueue(10); - cq.enqueue(20); - cout << cq.dequeue() << endl; // Output: 10 - cout << cq.peek_rear() << endl; // Output: 20 - cout << boolalpha << cq.is_empty() << endl; // Output: false - return 0; -} -``` - -## Complexity Analysis -### Time Complexity: -Enqueue: $O(1)$ -Dequeue: $O(1)$ -PeekFront and PeekRear: $O(1)$ -isEmpty and isFull: $O(1)$ -Space Complexity: $O(n)$, where $n$ is the maximum number of elements in the queue. - -## Conclusion -A circular queue is an efficient and space-optimized data structure useful for managing resources in a round-robin fashion, such as in task scheduling, memory buffering, and real-time data handling. Its circular design enables effective memory usage, making it a preferred choice in resource-constrained environments. \ No newline at end of file diff --git a/docs/Queue/double-ended-queue.md b/docs/Queue/double-ended-queue.md deleted file mode 100644 index d85981187..000000000 --- a/docs/Queue/double-ended-queue.md +++ /dev/null @@ -1,387 +0,0 @@ ---- -id: deque-in-dsa -title: Double-Ended Queue (Deque) Data Structure -sidebar_label: Double-Ended Queue (Deque) -sidebar_position: 4 -description: "A double-ended queue (Deque) is a linear data structure that allows insertion and deletion of elements from both ends—front and rear. This makes it a versatile data structure with efficient operations for many applications." -tags: [dsa, data-structures, Deque] ---- -### Introduction to Double-Ended Queue (Deque) - -A **double-ended queue (Deque)** is a linear data structure similar to a queue but allows insertions and deletions from both ends—front and rear. This flexibility makes deques useful in situations where both ends of the data need to be accessed, and they can efficiently handle tasks such as maintaining sequences of items or managing resources. - -![alt text](doubleendedqueue.png) - -### Double-Ended Queue Operations - -1. **InsertFront**: Add an element to the front of the deque. -2. **InsertRear**: Add an element to the rear of the deque. -3. **DeleteFront**: Remove the element from the front of the deque. -4. **DeleteRear**: Remove the element from the rear of the deque. -5. **PeekFront**: Retrieve the element at the front of the deque without removing it. -6. **PeekRear**: Retrieve the element at the rear of the deque without removing it. -7. **isEmpty**: Check if the deque is empty. -8. **isFull**: Check if the deque is full. - -### Pseudocode - -#### Basic Operations - -1. **InsertFront**: - - ```text - function insertFront(deque, element): - if isFull(deque): - return "Deque Overflow" - deque.front = (deque.front - 1 + deque.size) % deque.size - deque.elements[deque.front] = element - ``` - -2. **InsertRear**: - - ```text - function insertRear(deque, element): - if isFull(deque): - return "Deque Overflow" - deque.rear = (deque.rear + 1) % deque.size - deque.elements[deque.rear] = element - ``` - -3. **DeleteFront**: - - ```text - function deleteFront(deque): - if isEmpty(deque): - return "Deque Underflow" - frontElement = deque.elements[deque.front] - deque.front = (deque.front + 1) % deque.size - return frontElement - ``` - -4. **DeleteRear**: - - ```text - function deleteRear(deque): - if isEmpty(deque): - return "Deque Underflow" - rearElement = deque.elements[deque.rear] - deque.rear = (deque.rear - 1 + deque.size) % deque.size - return rearElement - ``` - -5. **PeekFront**: - - ```text - function peekFront(deque): - if isEmpty(deque): - return "Deque is empty" - return deque.elements[deque.front] - ``` - -6. **PeekRear**: - - ```text - function peekRear(deque): - if isEmpty(deque): - return "Deque is empty" - return deque.elements[deque.rear] - ``` - -7. **isEmpty**: - - ```text - function isEmpty(deque): - return deque.front == deque.rear - ``` - -8. **isFull**: - - ```text - function isFull(deque): - return (deque.rear + 1) % deque.size == deque.front - ``` - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -class Deque: - def __init__(self, size): - self.size = size - self.elements = [None] * size - self.front = 0 - self.rear = 0 - - def insert_front(self, element): - if self.is_full(): - return "Deque Overflow" - self.front = (self.front - 1 + self.size) % self.size - self.elements[self.front] = element - - def insert_rear(self, element): - if self.is_full(): - return "Deque Overflow" - self.rear = (self.rear + 1) % self.size - self.elements[self.rear] = element - - def delete_front(self): - if self.is_empty(): - return "Deque Underflow" - frontElement = self.elements[self.front] - self.front = (self.front + 1) % self.size - return frontElement - - def delete_rear(self): - if self.is_empty(): - return "Deque Underflow" - rearElement = self.elements[self.rear] - self.rear = (self.rear - 1 + self.size) % self.size - return rearElement - - def peek_front(self): - if self.is_empty(): - return "Deque is empty" - return self.elements[self.front] - - def peek_rear(self): - if self.is_empty(): - return "Deque is empty" - return self.elements[self.rear] - - def is_empty(self): - return self.front == self.rear - - def is_full(self): - return (self.rear + 1) % self.size == self.front - -# Example usage -dq = Deque(5) -dq.insert_front(10) -dq.insert_rear(20) -print(dq.delete_front()) # Output: 10 -print(dq.peek_rear()) # Output: 20 -print(dq.is_empty()) # Output: False -``` - -#### C++ Implementation - -```cpp -#include -using namespace std; - -class Deque { -private: - int *elements; - int front, rear, size; - -public: - Deque(int size) { - this->size = size; - elements = new int[size]; - front = rear = 0; - } - - void insert_front(int element) { - if (is_full()) { - cout << "Deque Overflow" << endl; - return; - } - front = (front - 1 + size) % size; - elements[front] = element; - } - - void insert_rear(int element) { - if (is_full()) { - cout << "Deque Overflow" << endl; - return; - } - rear = (rear + 1) % size; - elements[rear] = element; - } - - int delete_front() { - if (is_empty()) { - cout << "Deque Underflow" << endl; - return -1; // Indicating underflow - } - int frontElement = elements[front]; - front = (front + 1) % size; - return frontElement; - } - - int delete_rear() { - if (is_empty()) { - cout << "Deque Underflow" << endl; - return -1; // Indicating underflow - } - int rearElement = elements[rear]; - rear = (rear - 1 + size) % size; - return rearElement; - } - - int peek_front() { - if (is_empty()) { - cout << "Deque is empty" << endl; - return -1; // Indicating empty - } - return elements[front]; - } - - int peek_rear() { - if (is_empty()) { - cout << "Deque is empty" << endl; - return -1; // Indicating empty - } - return elements[rear]; - } - - bool is_empty() { - return front == rear; - } - - bool is_full() { - return (rear + 1) % size == front; - } - - ~Deque() { - delete[] elements; - } -}; - -// Example usage -int main() { - Deque dq(5); - dq.insert_front(10); - dq.insert_rear(20); - cout << dq.delete_front() << endl; // Output: 10 - cout << dq.peek_rear() << endl; // Output: 20 - cout << boolalpha << dq.is_empty() << endl; // Output: false - return 0; -} -``` - -#### Java Implementation - -```java -public class Deque { - private int[] elements; - private int front, rear, size; - - public Deque(int size) { - this.size = size; - elements = new int[size]; - front = rear = 0; - } - - public void insert_front(int element) { - if (is_full()) { - System.out.println("Deque Overflow"); - return; - } - front = (front - 1 + size) % size; - elements[front] = element; - } - - public void insert_rear(int element) { - if (is_full()) { - System.out.println("Deque Overflow"); - return; - } - rear = (rear + 1) % size; - elements[rear] = element; - } - - public int delete_front() { - if (is_empty()) { - System.out.println("Deque Underflow"); - return -1; // Indicating underflow - } - int frontElement = elements[front]; - front = (front + 1) % size; - return frontElement; - } - - public int delete_rear() { - if (is_empty()) { - System.out.println("Deque Underflow"); - return -1; // Indicating underflow - } - int rearElement = elements[rear]; - rear = (rear - 1 + size) % size; - return rearElement; - } - - public int peek_front() { - if (is_empty()) { - System.out.println("Deque is empty"); - return -1; // Indicating empty - } - - - return elements[front]; - } - - public int peek_rear() { - if (is_empty()) { - System.out.println("Deque is empty"); - return -1; // Indicating empty - } - return elements[rear]; - } - - public boolean is_empty() { - return front == rear; - } - - public boolean is_full() { - return (rear + 1) % size == front; - } - - public static void main(String[] args) { - Deque dq = new Deque(5); - dq.insert_front(10); - dq.insert_rear(20); - System.out.println(dq.delete_front()); // Output: 10 - System.out.println(dq.peek_rear()); // Output: 20 - System.out.println(dq.is_empty()); // Output: false - } -} -``` - -### Complexity - -- **Time Complexity**: - - - InsertFront: $O(1)$ - - InsertRear: $O(1)$ - - DeleteFront: $O(1)$ - - DeleteRear: $O(1)$ - - PeekFront: $O(1)$ - - PeekRear: $O(1)$ - - isEmpty: $O(1)$ - - isFull: $O(1)$ - -- **Space Complexity**: $O(n)$, where $n$ is the number of elements that can be stored in the deque. - -### Example - -Consider a deque with the following operations: - -1. InsertFront 10 -2. InsertRear 20 -3. DeleteFront -4. PeekRear -5. Check if empty - -**Operations**: - -- InsertFront 10: Deque becomes [_, 10, _, _, _] -- InsertRear 20: Deque becomes [_, 10, 20, _, _] -- DeleteFront: Removes 10, Deque becomes [_, _, 20, _, _] -- PeekRear: Returns 20, Deque remains [_, _, 20, _, _] -- isEmpty: Returns false - -### Conclusion - -The double-ended queue (Deque) is a versatile data structure that allows both insertions and deletions from both ends, providing more flexibility than a regular queue or stack. It is widely used in applications such as managing task queues, scheduling algorithms, and resource management. Understanding deques and their implementation can optimize many performance-critical systems. diff --git a/docs/Queue/doubleendedqueue.png b/docs/Queue/doubleendedqueue.png deleted file mode 100644 index 73d8542c59932106fac579462f0eb712098087fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15194 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%0AmiSk?Vtj^8sI&FVS)Ht#m!CPzx>5K0 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 B@tObt diff --git a/docs/Queue/priority-queue.md b/docs/Queue/priority-queue.md deleted file mode 100644 index c2ec0bf4b..000000000 --- a/docs/Queue/priority-queue.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -id: priority-queue-in-dsa -title: Priority Queue Data Structure -sidebar_label: Priority Queue -sidebar_position: 2 -description: "A priority queue is an abstract data type similar to a regular queue or stack data structure, but with an added feature that allows each element to have a priority. In a priority queue, elements are served based on their priority rather than their order in the queue." -tags: [dsa, data-structures, PriorityQueue] ---- - -### Introduction to Priority Queue - -A priority queue is an abstract data type that operates similarly to a regular queue or stack, but each element is assigned a priority. In a priority queue, elements are served based on their priority rather than the order in which they were added. This means that elements with higher priority are processed before those with lower priority. - -![alt text](Priority-queue.png) - -### Priority Queue Operations - -1. **Insert**: Add an element to the priority queue with a specified priority. -2. **Remove**: Remove and return the element with the highest priority. -3. **Peek**: Retrieve the element with the highest priority without removing it. -4. **isEmpty**: Check if the priority queue is empty. -5. **Size**: Get the number of elements in the priority queue. - -### Pseudocode - -#### Basic Operations - -1. **Insert**: - - ```text - function insert(priorityQueue, element, priority): - priorityQueue.append((element, priority)) - sort(priorityQueue) // Sort by priority - ``` - -2. **Remove**: - - ```text - function remove(priorityQueue): - if isEmpty(priorityQueue): - return "Priority Queue Underflow" - return priorityQueue.pop(0) // Removes the element with highest priority - ``` - -3. **Peek**: - - ```text - function peek(priorityQueue): - if isEmpty(priorityQueue): - return "Priority Queue is empty" - return priorityQueue[0] // Highest priority element - ``` - -4. **isEmpty**: - - ```text - function isEmpty(priorityQueue): - return len(priorityQueue) == 0 - ``` - -5. **Size**: - - ```text - function size(priorityQueue): - return len(priorityQueue) - ``` - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -class PriorityQueue: - def __init__(self): - self.elements = [] - - def insert(self, element, priority): - self.elements.append((element, priority)) - self.elements.sort(key=lambda x: x[1]) # Sort by priority - - def remove(self): - if self.is_empty(): - return "Priority Queue Underflow" - return self.elements.pop(0) # Highest priority element - - def peek(self): - if self.is_empty(): - return "Priority Queue is empty" - return self.elements[0] # Highest priority element - - def is_empty(self): - return len(self.elements) == 0 - - def size(self): - return len(self.elements) - -# Example usage -pq = PriorityQueue() -pq.insert("Task 1", 2) -pq.insert("Task 2", 1) -print(pq.remove()) # Output: ("Task 2", 1) -print(pq.peek()) # Output: ("Task 1", 2) -print(pq.is_empty()) # Output: False -print(pq.size()) # Output: 1 -``` - -#### C++ Implementation - -```cpp -#include -#include -#include - -class PriorityQueue { -private: - std::vector> elements; // Pair of (element, priority) - -public: - void insert(int element, int priority) { - elements.push_back({element, priority}); - std::sort(elements.begin(), elements.end(), [](auto &a, auto &b) { - return a.second < b.second; // Sort by priority - }); - } - - std::pair remove() { - if (is_empty()) { - std::cerr << "Priority Queue Underflow" << std::endl; - return {-1, -1}; // Indicating underflow - } - std::pair highestPriority = elements.front(); - elements.erase(elements.begin()); - return highestPriority; - } - - std::pair peek() { - if (is_empty()) { - std::cerr << "Priority Queue is empty" << std::endl; - return {-1, -1}; // Indicating empty - } - return elements.front(); - } - - bool is_empty() { - return elements.empty(); - } - - int size() { - return elements.size(); - } -}; - -// Example usage -int main() { - PriorityQueue pq; - pq.insert(1, 2); - pq.insert(2, 1); - auto task = pq.remove(); // Output: (2, 1) - std::cout << "Removed: " << task.first << " with priority: " << task.second << std::endl; - task = pq.peek(); // Output: (1, 2) - std::cout << "Next: " << task.first << " with priority: " << task.second << std::endl; - std::cout << std::boolalpha << pq.is_empty() << std::endl; // Output: false - std::cout << pq.size() << std::endl; // Output: 1 - return 0; -} -``` - -#### Inbuilt `priority_queue` in C++ - -In C++, the Standard Template Library (STL) provides a built-in **`priority_queue`** class, which implements a max-heap by default. A `priority_queue` is a container adaptor, meaning it provides specific functionality on top of an existing container like `vector` or `deque`. - -In a **max-heap** implementation, the highest priority element is the largest element, which is always at the top. The priority queue automatically sorts its elements based on their priorities. - -##### Operations provided by the inbuilt `priority_queue`: - -1. **push()**: - This function inserts an element into the priority queue. The element is automatically positioned according to its priority, which in the default case is its value (largest element has the highest priority). The time complexity for this operation is `O(log n)` as the insertion maintains the heap property. - - ```cpp - pq.push(10); // Inserts 10 into the priority queue - ``` - -2. **pop()**: - This function removes the highest-priority element (i.e., the element at the top of the heap). After removal, the heap is adjusted to maintain the heap property. The time complexity for this operation is `O(log n)`. - - ```cpp - pq.pop(); // Removes the highest priority element - ``` - -3. **top()**: - This function returns the element with the highest priority in the queue (i.e., the largest element in a max-heap). It does not remove the element, allowing the user to peek at the maximum priority element. The time complexity for this operation is `O(1)`. - - ```cpp - int highest = pq.top(); // Retrieves the highest priority element without removing it - ``` - -4. **empty()**: - This function checks whether the priority queue is empty. It returns `true` if there are no elements, otherwise it returns `false`. The time complexity for this operation is `O(1)`. - - ```cpp - bool isEmpty = pq.empty(); // Checks if the priority queue is empty - ``` - -5. **size()**: - This function returns the number of elements in the priority queue. The time complexity for this operation is `O(1)`. - - ```cpp - int count = pq.size(); // Returns the number of elements in the priority queue - ``` - - -```cpp -#include -#include -using namespace std; - -int main() -{ - int arr[7] = { 15, 3, 5, 7, 6, 12, 1}; - - // defining priority queue - priority_queue pq; - - // pushing into priority queue - for (int i = 0; i < arr.size(); i++) { - pq.push(arr[i]); - } - - // printing priority queue - cout << "Priority Queue: "; - while (!pq.empty()) { - cout << pq.top() << ' '; // It will return highest element - pq.pop(); // poping into priority queue - } - - return 0; -} -``` - -#### Java Implementation - -```java -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; - -public class PriorityQueue { - private ArrayList elements; - - public PriorityQueue() { - elements = new ArrayList<>(); - } - - public void insert(int element, int priority) { - elements.add(new Pair(element, priority)); - Collections.sort(elements, Comparator.comparingInt(pair -> pair.priority)); // Sort by priority - } - - public Pair remove() { - if (is_empty()) { - System.out.println("Priority Queue Underflow"); - return null; // Indicating underflow - } - return elements.remove(0); // Remove highest priority - } - - public Pair peek() { - if (is_empty()) { - System.out.println("Priority Queue is empty"); - return null; // Indicating empty - } - return elements.get(0); // Highest priority element - } - - public boolean is_empty() { - return elements.isEmpty(); - } - - public int size() { - return elements.size(); - } - - // Pair class to hold element and priority - private class Pair { - int element; - int priority; - - Pair(int element, int priority) { - this.element = element; - this.priority = priority; - } - } - - // Example usage - public static void main(String[] args) { - PriorityQueue pq = new PriorityQueue(); - pq.insert(1, 2); - pq.insert(2, 1); - Pair task = pq.remove(); // Output: Pair with element 2 - System.out.println("Removed: " + task.element + " with priority: " + task.priority); - task = pq.peek(); // Output: Pair with element 1 - System.out.println("Next: " + task.element + " with priority: " + task.priority); - System.out.println(pq.is_empty()); // Output: false - System.out.println(pq.size()); // Output: 1 - } -} -``` - -### Complexity - -- **Time Complexity**: - - - Insert: $O(n \log n)$ (due to sorting) - - Remove: $O(n)$ (removing the first element) - - Peek: $O(1)$ - - isEmpty: $O(1)$ - - Size: $O(1)$ - -- **Space Complexity**: $O(n)$, where $n$ is the number of elements in the priority queue. - -### Example - -Consider a priority queue with the following operations: - -1. Insert Task 1 with priority 2 -2. Insert Task 2 with priority 1 -3. Remove the highest priority task -4. Peek at the highest priority task -5. Check if empty -6. Get size - -**Operations**: - -- Insert Task 1 (priority 2): Queue becomes [(Task 1, 2)] -- Insert Task 2 (priority 1): Queue becomes [(Task 2, 1), (Task 1, 2)] -- Remove: Removes Task 2 (priority 1), Queue becomes [(Task 1, 2)] -- Peek: Returns Task 1 (priority 2), Queue remains [(Task 1, 2)] -- isEmpty: Returns false -- Size: Returns 1 - -### Conclusion - -A priority queue is a powerful data structure used in scenarios where elements need to be processed based on priority rather than order. It is commonly used in algorithms such as Dijkstra's shortest path algorithm, Huffman coding, and various scheduling algorithms. Understanding and implementing priority queues effectively can significantly improve the efficiency of your algorithms. diff --git a/docs/Queue/priority_queue_questions.md b/docs/Queue/priority_queue_questions.md deleted file mode 100644 index 7345bcf96..000000000 --- a/docs/Queue/priority_queue_questions.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -id: priority-queue-questions-in-dsa -title: Priority Queue Questions -sidebar_label: Priority Queue Practice Questions -sidebar_position: 2 -description: "A priority queue is an abstract data type similar to a regular queue or stack data structure, but with an added feature that allows each element to have a priority. In a priority queue, elements are served based on their priority rather than their order in the queue." -tags: [dsa, data-structures, PriorityQueue] ---- -# Priority Queue Questions - -## 1. Implement a Priority Queue using a Min-Heap - -### Question: -Implement a priority queue data structure using a min-heap. Your priority queue should support the following operations: -- `insert(value)`: Insert a value into the priority queue. -- `extract_min()`: Remove and return the minimum value from the priority queue. -- `get_min()`: Return the minimum value without removing it from the queue. -- `is_empty()`: Check if the priority queue is empty. - -### Explanation: -A priority queue can be efficiently implemented using a min-heap, which allows for fast insertion and retrieval of the minimum element. The min-heap is a complete binary tree where each parent node is less than or equal to its children. This property ensures that the minimum element is always at the root. - -- **Insert Operation**: To insert an element, we add it to the end of the heap (maintaining the complete binary tree property) and then "bubble up" to restore the heap property. -- **Extract Min Operation**: To extract the minimum element, we remove the root and replace it with the last element in the heap. Then we "bubble down" this element to restore the heap property. -- **Get Min Operation**: This operation simply returns the root of the heap without modifying it. -- **Is Empty Operation**: This operation checks if the heap has any elements. - ---- - -## 2. Kth Largest Element in a Stream - -### Question: -Design a class `KthLargest` that maintains the kth largest element in a stream of integers. It should support the following operations: -- `KthLargest(int k, int[] nums)`: Initialize the object with the integer k and the stream of integers `nums`. -- `add(int val)`: Add the integer `val` to the stream and return the kth largest element. - -### Explanation: -To efficiently maintain the kth largest element, we can use a min-heap of size k. The min-heap will store the k largest elements seen so far. - -- When a new element is added: - - If the size of the heap is less than k, we add the new element. - - If the size is equal to k and the new element is larger than the root of the heap (the smallest element in the heap), we remove the root and add the new element. -- The root of the heap will always represent the kth largest element. - ---- - -## 3. Merge k Sorted Lists - -### Question: -Given an array of `k` sorted linked lists, merge them and return them as one sorted list. Analyze and describe the complexity of your solution. - -### Explanation: -This problem can be efficiently solved using a priority queue. We can insert the head of each list into a min-heap and then repeatedly extract the minimum element from the heap to build the final sorted list. - -- Initialize a min-heap and add the head of each linked list. -- While the heap is not empty: - - Extract the minimum element from the heap and add it to the result list. - - If the extracted element has a next node, insert that next node into the heap. -- This approach ensures that we are always merging the smallest elements from each list first. - -### Complexity Analysis: -- **Time Complexity**: O(N log k), where N is the total number of elements across all lists and k is the number of linked lists. Each insertion and extraction operation on the heap takes O(log k) time. -- **Space Complexity**: O(k), since we are storing at most k elements in the heap. - ---- - -## 4. Top K Frequent Elements - -### Question: -Given a non-empty array of integers, return the k most frequent elements. You may assume that the answer is unique. - -### Explanation: -We can solve this problem using a priority queue by leveraging a min-heap. - -- First, we count the frequency of each element using a hash map. -- Then, we create a min-heap to keep track of the top k frequent elements: - - For each unique element in the frequency map, we insert it into the heap. - - If the size of the heap exceeds k, we remove the root (the least frequent element). -- Finally, the heap will contain the k most frequent elements. - -### Complexity Analysis: -- **Time Complexity**: O(N log k), where N is the number of elements in the input array. Counting the frequencies takes O(N), and maintaining the heap takes O(log k) for each of the unique elements. -- **Space Complexity**: O(N) for the frequency map, plus O(k) for the heap. - ---- - -## 5. Reorganize String - -### Question: -Given a string `s`, rearrange the characters of `s` so that no two adjacent characters are the same. If it is not possible, return an empty string. - -### Explanation: -We can use a priority queue to ensure that we always try to place the most frequent characters first. - -- Count the frequency of each character using a hash map. -- Insert each character into a max-heap based on its frequency. -- Build the result string by repeatedly extracting the most frequent character from the heap: - - After placing a character, temporarily store it until we can place it again (to avoid adjacent duplicates). -- If at any point the heap is empty and we still have characters left to place, return an empty string. - -### Complexity Analysis: -- **Time Complexity**: O(N log k), where N is the length of the string and k is the number of unique characters. -- **Space Complexity**: O(k) for the frequency map and the heap. - ---- - -## 6. Median in a Stream - -### Question: -Design a data structure that supports the following operations efficiently: -- `add_num(int num)`: Adds an integer `num` from a data stream to the data structure. -- `find_median()`: Returns the median of all elements so far. - -### Explanation: -To find the median in a stream, we can use two heaps: -- A **max-heap** to store the smaller half of the elements. -- A **min-heap** to store the larger half of the elements. - -By maintaining this balance: -- If the total number of elements is odd, the max-heap will have one more element than the min-heap, making it the median. -- If the total number of elements is even, the median is the average of the roots of both heaps. - -### Complexity Analysis: -- **Time Complexity**: O(log n) for `add_num` due to heap insertion and balancing, O(1) for `find_median`. -- **Space Complexity**: O(n) to store all the elements. - ---- - -## 7. Find the Running Median - -### Question: -Given a stream of integers, find the median of the integers at each insertion point. For example, if the stream is `[5, 15, 1, 3]`, the running medians are `[5, 10, 5, 4]`. - -### Explanation: -We can solve this problem similarly to the "Median in a Stream" problem, using two heaps: -- A max-heap for the lower half. -- A min-heap for the upper half. - -At each insertion, we rebalance the heaps to ensure that the difference in sizes between the two heaps is no more than one, and calculate the median accordingly: -- If both heaps are balanced in size, the median is the average of the roots of both heaps. -- If one heap has more elements, the median is the root of that heap. - -### Complexity Analysis: -- **Time Complexity**: O(log n) for each insertion due to heap operations. -- **Space Complexity**: O(n) for storing all elements in the heaps. - ---- - -## 8. Task Scheduler - -### Question: -Given a list of tasks and a positive integer `n` representing the cooldown period between the same tasks, find the minimum time required to complete all tasks. - -### Explanation: -To solve this problem, we can use a priority queue to manage the cooldown period: -- Count the frequency of each task. -- Use a max-heap to execute tasks in the order of their frequencies. -- Use a queue to keep track of tasks during their cooldown period. - -At each time unit: -- If a task is ready to be executed after cooldown, reinsert it into the heap. -- Repeat until all tasks are executed, and track the time. - -### Complexity Analysis: -- **Time Complexity**: O(n log k) where n is the total number of tasks, and k is the number of unique tasks. -- **Space Complexity**: O(k) for the heap and queue. - ---- - -## 9. Connect Ropes to Minimize Cost - -### Question: -Given an array of integers representing the lengths of ropes, connect them such that the cost to connect ropes is minimized. The cost of connecting two ropes is equal to the sum of their lengths. - -### Explanation: -To minimize the cost, use a min-heap: -- Insert all rope lengths into the min-heap. -- While there are more than one rope in the heap: - - Extract the two smallest ropes. - - Calculate the cost to combine them. - - Add the combined rope back into the heap. -- Repeat until only one rope remains. - -The sum of all combination costs will be the minimum cost. - -### Complexity Analysis: -- **Time Complexity**: O(n log n) due to heap operations. -- **Space Complexity**: O(n) for the heap. - ---- - -## 10. Find K Closest Points to the Origin - -### Question: -Given an array of points in a 2D plane, return the `k` closest points to the origin `(0, 0)`. - -### Explanation: -We can use a max-heap to keep track of the k closest points: -- Compute the Euclidean distance of each point from the origin. -- Use a max-heap of size `k` to store the points with their distances. -- If a new point is closer than the farthest point in the heap, remove the farthest point and add the new one. -- At the end, the heap will contain the k closest points. - -### Complexity Analysis: -- **Time Complexity**: O(n log k) for maintaining the heap. -- **Space Complexity**: O(k) for the heap. - ---- - -## 11. Find the Skyline of a City - -### Question: -Given the `buildings` array where each building is represented as `[left, right, height]`, find the skyline formed by these buildings. - -### Explanation: -To solve this, use a priority queue to maintain active building heights as we sweep from left to right through all critical points (both start and end of buildings): -- Store active heights in a max-heap. -- At each critical point, add or remove heights as buildings start or end. -- Record changes in the maximum height, which forms the critical points of the skyline. - -### Complexity Analysis: -- **Time Complexity**: O(n log n) due to sorting and heap operations. -- **Space Complexity**: O(n) for the heap. - ---- diff --git a/docs/Randomized Algorithm/Randomized-Quicksort.md b/docs/Randomized Algorithm/Randomized-Quicksort.md deleted file mode 100644 index fd94116e3..000000000 --- a/docs/Randomized Algorithm/Randomized-Quicksort.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: randomized-quicksort -title: Randomized Quick Sort -sidebar_label: Randomized Quick Sort -description: "Randomized quicksort is a sorting algorithm that is an extension of quicksort, but with a random pivot selection" -tags: [dsa, algorithms, sorting] ---- - -### Problem Statement: -Implement the Randomized Quick Sort algorithm, which sorts an array by selecting a random pivot element at each partitioning step. The goal is to sort an array of integers in ascending order using this randomized approach to avoid the worst-case time complexity of `O(n^2)` that occurs with a deterministic pivot on already sorted or nearly sorted input. - -### Defination -This program sorts an array of integers in ascending order using the randomized QuickSort algorithm. It begins by taking an array of integers as input, selects random pivots during partitioning to improve performance, and recursively sorts the partitions. - -### Algorithm Steps: - -1. Choose a random pivot element and swap it to the end of the array to prepare for partitioning. -2. Partition the array such that elements less than the pivot are on the left and greater elements are on the right. -3. Recursively apply QuickSort to the left and right partitions created by the pivot. -4. Repeat until all partitions contain a single element, resulting in a sorted array. - -### Code Breakdown - -1. **swap() Function**: The `swap` function exchanges the values of two variables. It is used to rearrange elements in the array during partitioning. - -2. **random_partition() Function**: This function selects a random pivot element to reduce the chance of worst-case performance in QuickSort. It places elements smaller than the pivot to the left and greater elements to the right, then returns the pivot’s final position. - -3. **quicksort() Function**: The main recursive function that sorts the array. It partitions the array around a randomly chosen pivot, then recursively applies QuickSort to the left and right subarrays until each partition has only one element, making the array sorted. - -4. **Main() Function**: - - Prompts the user to input the number of elements and the elements themselves. - - Displays the original array, calls `quicksort` to sort the array, and then prints the sorted array. - -### Time Complexity: -- The randomized QuickSort has an average time complexity of `O(n log n)` due to balanced splits, with `O(n^2)` as the worst case for highly unbalanced partitions. Randomizing the pivot reduces the likelihood of worst-case splits, keeping performance near `O(n log n)`. - -### Space Complexity -- The space complexity of randomized QuickSort is `O(log n)` on average due to the recursion stack depth, as balanced partitions limit the number of recursive calls. In the worst case, where partitions are highly unbalanced, the space complexity can increase to `O(n)`. - -### Sample Input: -Enter the number of items: 5 -Enter the elements: 98 -5 31 47 -12 - -### Sample Output: -The array is: 98 -5 31 47 -12 -The sorted array is: -12 -5 31 47 98 - -### C++ Implementation: -```cpp -#include -#include -#include -#include - -void swap(int &a, int &b) { - int temp = a; - a = b; - b = temp; -} - -int random_partition(std::vector &a, int lb, int ub) { - srand(static_cast(time(nullptr))); // Seed for random number generator - int random_index = lb + rand() % (ub - lb + 1); // Generate a random index within the range - swap(a[random_index], a[ub]); // Swap the randomly chosen pivot element with the last element - int pivot = a[ub]; - int i = lb - 1; // Pointer for the greater element - for (int j = lb; j <= ub - 1; j++) { - if (a[j] < pivot) { // If current element is smaller than pivot - i++; - swap(a[i], a[j]); - } - } - swap(a[i + 1], a[ub]); // Place pivot at the correct position - return (i + 1); // Return the partition index -} - -void quicksort(std::vector &a, int lb, int ub) { - if (lb < ub) { - int pivot = random_partition(a, lb, ub); - quicksort(a, lb, pivot - 1); - quicksort(a, pivot + 1, ub); - } -} - -int main() { - std::vector a; - int n; - std::cout << "Enter the number of items: "; - std::cin >> n; - a.resize(n); - std::cout << "Enter the elements: "; - for (int i = 0; i < n; i++) - std::cin >> a[i]; - std::cout << "The array is:"; - for (int i = 0; i < n; i++) - std::cout << " " << a[i] << " "; - quicksort(a, 0, n - 1); - std::cout << "\nThe sorted array is:"; - for (int i = 0; i < n; i++) - std::cout << " " << a[i]; - return 0; -} - -``` diff --git a/docs/Recursion-depths/Recursion.md b/docs/Recursion-depths/Recursion.md deleted file mode 100644 index 472c9e76a..000000000 --- a/docs/Recursion-depths/Recursion.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: recursion-depth-overview -title: Recursion Depth Overview -sidebar_label: Overview -sidebar_position: 5 -description: An overview of recursion depth and its role in recursive algorithms. -tags: [recursion, algorithms, depth] ---- - - -# Recursion Depth Overview - -In programming, **recursion** is a technique where a function calls itself in order to solve a problem. Understanding **recursion depth** is essential for anyone learning about recursive functions, as it helps you grasp how recursion works and the potential issues that can arise. - -## What is Recursion Depth? - -Recursion depth refers to how many times a recursive function calls itself before reaching a **base case**—a condition that stops the recursion. Each time a function calls itself, it creates a new layer in the call stack (a structure that keeps track of function calls), and this layer counts toward the recursion depth. - -For example, consider a simple function that calculates the factorial of a number using recursion: - -```python -def factorial(n): - if n == 0: # Base case - return 1 - else: - return n * factorial(n - 1) # Recursive call -``` - -In this function: -- The base case is when `n` is 0, which stops further recursion. -- Each call to `factorial(n - 1)` increases the recursion depth until `n` reaches 0. - -## Why is Recursion Depth Important? - -Understanding recursion depth is crucial for several reasons: - -1. **Stack Overflow**: Each recursive call consumes memory, and if the recursion depth is too high, it can lead to a stack overflow error, crashing your program. This happens when the call stack exceeds its limit. - -2. **Performance**: Deep recursion can affect performance, leading to slower execution times. Knowing the maximum depth can help optimize your code. - -3. **Debugging**: If a recursive function doesn’t terminate properly, knowing the depth can help trace the problem. - -## Practical Example: Calculating Fibonacci Numbers - -Here’s a classic example of using recursion to calculate Fibonacci numbers: - -```python -def fibonacci(n): - if n <= 0: # Base case - return 0 - elif n == 1: # Base case - return 1 - else: - return fibonacci(n - 1) + fibonacci(n - 2) # Recursive calls -``` - -In this example, the `fibonacci` function calls itself twice for each value of `n`, creating multiple layers of recursion. This can lead to a high recursion depth, especially for larger values of `n`. - -### Managing Recursion Depth - -To manage recursion depth and prevent issues like stack overflow, consider the following strategies: - -1. **Use Tail Recursion**: If your programming language supports it, use tail recursion, where the recursive call is the last operation in the function. This can optimize memory usage. - -2. **Iterative Solutions**: For problems that can be solved iteratively (using loops), consider using an iterative approach instead of recursion. - -3. **Limit Input Size**: Set limits on the input size to prevent excessive recursion depth. - -4. **Increase Stack Size**: In some programming environments, you can increase the maximum stack size, but this should be a last resort. - -Understanding recursion depth will help you write efficient and error-free recursive functions, making your programming journey smoother and more enjoyable! diff --git a/docs/Recursion-depths/advanced-topics.md b/docs/Recursion-depths/advanced-topics.md deleted file mode 100644 index 39b023e43..000000000 --- a/docs/Recursion-depths/advanced-topics.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -id: recursion-depth-advanced -title: Advanced Recursion Depth Topics -sidebar_label: Advanced Topics -sidebar_position: 1 -description: Advanced concepts related to recursion depth, including dynamic programming and backtracking. -tags: [advanced, recursion, algorithms] ---- - - - -# Advanced Recursion Depth Topics - -Recursion is a powerful technique in programming that allows functions to call themselves to solve problems. While basic recursion can solve simple tasks, advanced topics in recursion depth can greatly enhance algorithm efficiency and performance. This document explores some of these advanced concepts: - -## 1. Dynamic Programming - -**Dynamic Programming** (DP) is a method used to optimize recursive algorithms by storing the results of expensive function calls and reusing them when the same inputs occur again. This approach is particularly useful for problems that have overlapping subproblems—where the same subproblems are solved multiple times. - -### Key Concepts: -- **Memoization**: This technique involves storing the results of function calls in a cache (usually a dictionary or list) so that when the same inputs are encountered, the function can return the cached result instead of recalculating it. - -**Example**: Calculating Fibonacci numbers can be optimized using dynamic programming: -```python -def fibonacci(n, memo={}): - if n in memo: - return memo[n] - if n == 0: - return 0 - elif n == 1: - return 1 - memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo) - return memo[n] -``` - - -# Advanced Recursion Depth Topics - -Beyond simple recursive functions, recursion depth plays a role in complex algorithms. Topics covered: -- **Dynamic Programming**: Optimizing recursive algorithms with overlapping subproblems. - -**Example**: Calculating Fibonacci numbers can be optimized using dynamic programming: -```python -def fibonacci(n, memo={}): - if n in memo: - return memo[n] - if n == 0: - return 0 - elif n == 1: - return 1 - memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo) - return memo[n] -``` - - -- **Divide and Conquer**: Depth in algorithms that split data (e.g., merge sort). - -- The algorithm divides the problem into smaller parts (the "divide" step), solves each part recursively (the "conquer" step), and then combines the results (the "combine" step). -Example: Merge Sort is a classic example of a divide-and-conquer algorithm: - -```python -def merge_sort(arr): - if len(arr) > 1: - mid = len(arr) // 2 - left_half = arr[:mid] - right_half = arr[mid:] - - merge_sort(left_half) # Recursive call on left half - merge_sort(right_half) # Recursive call on right half - - i = j = k = 0 - - # Merging the two halves - while i < len(left_half) and j < len(right_half): - if left_half[i] < right_half[j]: - arr[k] = left_half[i] - i += 1 - else: - arr[k] = right_half[j] - j += 1 - k += 1 - - while i < len(left_half): - arr[k] = left_half[i] - i += 1 - k += 1 - - while j < len(right_half): - arr[k] = right_half[j] - j += 1 - k += 1 -``` - -- **Backtracking**: Managing depth in algorithms with multiple recursive branches (e.g., N-Queens problem). - -These approaches minimize excessive depth and improve performance. - -Key Concepts: -Backtracking is used in scenarios where there are multiple choices to explore (e.g., the N-Queens problem, solving mazes, generating permutations). - -**Example**: The N-Queens problem seeks to place N queens on an N×N chessboard so that no two queens threaten each other. A backtracking solution might look like this: - -``` python -def solve_n_queens(n): - board = [-1] * n # Initialize board - results = [] - - def place_queen(row): - if row == n: - results.append(board[:]) - return - for col in range(n): - if is_safe(row, col): - board[row] = col - place_queen(row + 1) # Recursive call to place next queen - board[row] = -1 # Backtrack - - def is_safe(row, col): - for i in range(row): - if board[i] == col or \ - board[i] - i == col - row or \ - board[i] + i == col + row: - return False - return True - - place_queen(0) - return results -``` -### Conclusion -Understanding advanced recursion concepts like dynamic programming, divide and conquer, and backtracking is crucial for optimizing algorithms and managing recursion depth effectively. These techniques help prevent excessive recursion depth, improve performance, and allow for more complex problem-solving. By leveraging these strategies, programmers can create efficient and effective recursive algorithms for a wide range of applications. \ No newline at end of file diff --git a/docs/Recursion-depths/basic-concepts.md b/docs/Recursion-depths/basic-concepts.md deleted file mode 100644 index 1df1abceb..000000000 --- a/docs/Recursion-depths/basic-concepts.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -id: recursion-depth-basic-concepts -title: Basic Concepts of Recursion Depth -sidebar_label: Basic Concepts -sidebar_position: 2 -description: Introduction to recursion and understanding recursion depth. -tags: [recursion, depth, basics] ---- - -# Basic Concepts of Recursion Depth - -Recursion is a programming technique where a function calls itself in order to solve smaller instances of a problem. The recursion depth is the total number of recursive calls in a function. - -## Key Concepts -1. **Base Case**: Condition where recursion stops. Understanding recursion depth is essential to avoid stack overflows, especially in algorithms that rely on deep recursion. - -Example: -```python -def recursive_function(n): - if n == 0: - return - recursive_function(n - 1) -``` -2. **Recursive Case**: The recursive case is the part of the function where the recursion continues. This involves calling the function itself with modified arguments that bring it closer to the base case. Each recursive call should reduce the problem size, making it more manageable. - -Example: In the code above, **recursive_function(n - 1)** is the recursive case, which reduces the input **n** by 1 with each call. -3. **Recursion Depth**:Recursion depth refers to the maximum number of nested recursive calls that occur during the execution of a function. Understanding recursion depth is essential to avoid stack overflows, especially in algorithms that rely on deep recursion. - -For instance, if a function makes a large number of recursive calls without hitting the base case, it can exceed the call stack limit set by the programming language, leading to a stack overflow error. - -### Importance of Recursion Depth -- Efficiency: Knowing the recursion depth helps in analyzing the time complexity of recursive algorithms. -- Memory Consumption: Each recursive call consumes stack memory, which can lead to high memory usage and performance issues if the depth is too great. - -Example of a Recursive Function with Depth Consider the following recursive function that counts down from a number: - -``` python -def countdown(n): - if n <= 0: - return - print(n) - countdown(n - 1) # Recursive case -``` -In this function, calling `countdown(5)` will result in 5 recursive calls before reaching the base case, making the recursion depth 5. - -### Conclusion -Understanding the basic concepts of recursion depth is crucial for writing effective recursive functions. It helps in designing algorithms that are efficient and avoids potential pitfalls such as stack overflow errors. When implementing recursive functions, always ensure that there is a well-defined base case and that the recursion moves towards it in each call. \ No newline at end of file diff --git a/docs/Recursion-depths/handling-depth-errors.md b/docs/Recursion-depths/handling-depth-errors.md deleted file mode 100644 index 4c0307501..000000000 --- a/docs/Recursion-depths/handling-depth-errors.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -id: recursion-depth-errors -title: Handling Recursion Depth Errors -sidebar_label: Depth Errors -sidebar_position: 3 -description: Handling stack overflow and other errors due to high recursion depth. -tags: [errors, recursion, stack-overflow] ---- - -# Handling Recursion Depth Errors - -Recursion is a powerful programming technique, but when the recursion depth exceeds a certain limit, it can lead to errors such as stack overflow. Understanding these errors and knowing how to handle them is crucial for writing robust recursive functions. - -## Common Errors - -1. **Stack Overflow**: - - This error occurs when the recursion depth exceeds the available stack size. Each function call uses some memory on the call stack, and if too many calls are made before reaching a base case, the stack runs out of space. - - **Symptoms**: Your program may crash or throw an error like `RecursionError: maximum recursion depth exceeded` in Python. - -2. **Infinite Recursion**: - - This occurs when the base case is missing or incorrectly implemented. The function keeps calling itself without ever reaching a stopping point, which leads to stack overflow eventually. - - **Symptoms**: Your program hangs or crashes after a while due to excessive memory usage. - -## Solutions - -### 1. Set a Limit -- Some programming languages, like Python, allow you to adjust the maximum recursion depth. You can set a higher limit if necessary, but be cautious as this might lead to stack overflow. -- **Example**: - -```python - import sys - sys.setrecursionlimit(1000) # Set recursion limit to 1000 -``` -## 2. Refactor Code - -### Iterative Approach -If possible, convert the recursive function into an iterative one using loops. Iterative solutions typically use less memory and avoid deep recursion issues. - -### Benefits of the Iterative Approach -It avoids recursion depth issues entirely. -It often performs better in terms of memory usage. - -### Optimizing Recursive Logic -Ensure that your recursive function is well-optimized. Check if: -- The base case is correctly defined and reachable. -- The problem size reduces significantly with each recursive call. - -### Example of a Recursive Function with Potential Errors -Here’s a simple recursive function that calculates the factorial of a number: - -```python -def factorial(n): - if n < 0: # Error check for negative input - return "Error: Negative input" - elif n == 0 or n == 1: - return 1 - return n * factorial(n - 1) -``` -### Summary -Handling recursion depth errors is essential for creating reliable recursive functions. Always check for potential stack overflow and infinite recursion, and consider using iterative solutions when necessary to enhance your program's stability and performance. \ No newline at end of file diff --git a/docs/Recursion-depths/performance-consideration.md b/docs/Recursion-depths/performance-consideration.md deleted file mode 100644 index cca112dc4..000000000 --- a/docs/Recursion-depths/performance-consideration.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -id: recursion-depth-performance -title: Recursion Depth and Performance -sidebar_label: Performance Considerations -sidebar_position: 4 -description: Understanding how recursion depth affects algorithm performance. -tags: [performance, recursion, optimization] ---- - - -# Recursion Depth and Performance - -Recursion depth can affect the performance and efficiency of your program. High depths increase memory usage and may lead to stack overflows. Here are ways to optimize recursive functions. - -## Optimizing Recursive Functions -1. **Tail Recursion**: Some languages optimize tail-recursive functions to reduce stack usage. -2. **Memoization**: Store previous results to reduce duplicate calls, especially in algorithms like Fibonacci. -3. **Iterative Solutions**: Convert recursive functions to iterative when feasible. - -## Example -In cases like calculating large Fibonacci numbers, use memoization to reduce depth. diff --git a/docs/Recursion/Ackerman.md b/docs/Recursion/Ackerman.md deleted file mode 100644 index d1a6fb6c8..000000000 --- a/docs/Recursion/Ackerman.md +++ /dev/null @@ -1,181 +0,0 @@ ---- -id: ackerman-function -title: Ackerman Function Using Recursion -sidebar_label: Generate Ackerman Function value -description: "The Ackermann function is a recursive function that grows incredibly fast and is often used to demonstrate the power and limitations of recursion. Defined with two arguments,m and n, it exhibits rapid growth even for small inputs, making it a classic example in theoretical computer science. Unlike simpler recursive functions, it is non-primitive recursive, meaning it cannot be expressed using basic loops. This function challenges computational limits, often exceeding recursion stack sizes in practical programming environments. Its main use is in studying recursion, computability, and the limits of algorithms." -tags: [Ackerman , recursion, dsa] ---- -## Ackerman Function Via Recursion - -**Problem Statement:** - -The **Ackermann function** is a mathematical recursive function with two non-negative integer inputs, m and n, which grows rapidly and far exceeds the growth rate of most commonly known functions like exponentiation or factorials. The problem at hand is to compute the Ackermann function for given values of m and n , based on its recursive definition. This function provides an interesting challenge due to its steep growth, making it both a theoretical tool in studying recursion and a practical test of a system's recursion limits. - -**Detailed Problem Breakdown:** - -1. **Recursive Definition:** - The Ackermann function is defined by the following recursive rules: - -* When **m**=**0**,the function simply returns n+1 . -* When m>0and n=0 it recursively calls A(m−1,1). - -* When m>0 and n>0, it makes two recursive calls, first to A(m,n−1) and then to A(m−1,A(m,n−1)). - -**Properties of the Ackermann Function:** - -* **Extremely fast growth** : Even for small values of mm**m** and nn**n**, the result grows extremely fast. For instance, A(4,2) leads to a massive number that is impractical to compute manually. -* **Non-primitive recursive** : Unlike factorials or Fibonacci sequences, the Ackermann function cannot be computed using simple loops. It is a classic example of a function that cannot be described by "primitive recursion," which makes it computationally expensive. - -**Computational Challenge:** - -* **Depth of Recursion** : The function's deep recursion makes it difficult for programming environments that have recursion depth limits (e.g., Python’s default recursion limit is 1000). Handling larger values of m and n often requires increasing this limit. -* **Stack Overflow Risks** : If not managed correctly, the Ackermann function can lead to a stack overflow error due to the high number of nested recursive calls. -* **Objective:** - - * Write a function or program to calculate A(m,n)A(m, n)**A**(**m**,**n**) based on the given recursive rules. - * Optimize or adjust the program to handle recursion depth and efficiently compute for small values of mm**m** and nn**n**, while recognizing the impracticality of large inputs. - - **Example:** - For small values of m and n, such as A(2,2)): -* A(2,2)=9 - - This can be traced through several recursive steps, showcasing how each call is nested deeply within others. - -#### Explanation: - -* **Base Case (m = 0):** If m=0, the function simply returns n+1. This acts as the termination point for recursive calls when mm**m** becomes zero. -* **Recursive Case 1 (m > 0 and n = 0):** If m is greater than 0 and n=0, the function makes a recursive call to A(m−1,1). This reduces the value of m by 1 and resets n to 1. -* **Recursive Case 2 (m > 0 and n > 0):** If both mm**m** and nn**n** are greater than 0, the function first computes A(m,n−1) and then recursively calls A(m−1,result of A(m,n−1)). - -### **Example Walkthrough:** - -Lets compute A(2,2): - -1. A(2,2) calls A(1,A(2,1)) -2. A(2,1)calls A(1,A(2,0)) -3. A(2,0) calls A(1,1) , which calls A(0,2)=3 -4. Now, A(2,0)=3, so A(2,1)=A(1,3) -5. A(1,3) calls A(0,4)=5 -6. A(2,1)=5, so A(2,2)=A(1,5) -7. A(1,5)=A(0,6)=7 - -Thus, A(2,2)=7. - -#### Complexity : - -### Time Complexity - -The **time complexity** of the Ackermann function is extremely high and difficult to express in standard notation due to its deeply recursive nature. It is considered **non-primitive recursive** , growing faster than any primitive recursive function. As mm**m** and nn**n** increase, the number of recursive calls expands exponentially. For small values, the function may seem manageable, but for values like A(4,n), the time required for computation escalates rapidly, leading to an impractical number of operations. While it doesn't fit neatly into Big-O notation, it exemplifies super-exponential growth, illustrating its theoretical limits in computation. - -### Space Complexity - -The **space complexity** of the Ackermann function is determined by the maximum depth of the recursion stack, which can be expressed as **O(m + n)** . Each recursive call adds a new frame to the stack, and as the function makes multiple nested calls, the memory usage increases significantly. This rapid expansion can lead to stack overflow errors, especially when handling larger inputs. As a result, the function demands substantial memory resources, making it impractical for high values without careful control of recursion depth. Overall, both time and space complexities highlight the Ackermann function's role in understanding the limits of recursion in computational theory - -### Limitations and Considerations - -The Ackermann function, while a fascinating theoretical construct, presents several limitations and considerations when implemented in practical computing environments: - -**Recursion Depth** : - -* The Ackermann function's deep recursion can quickly exceed the default recursion limits of many programming languages, such as Python, which typically has a recursion depth limit of around 1000. This can lead to **stack overflow errors** , making it impractical to compute for larger values of m and n without adjusting the recursion depth. - -**Computational Intensity** : - -* Due to its highly recursive nature, the Ackermann function is computationally intensive. For small inputs, it may be feasible to calculate, but as the values increase, the time required grows **exponentially** , resulting in significant delays or failures in computation. - -**Non-primitive Recursion** : - -* The function's classification as non-primitive recursive means that it cannot be expressed using basic looping constructs, making it unsuitable for optimization techniques used in simpler recursive functions. This characteristic complicates its use in practical applications where efficiency is crucial. - -**Memory Consumption** : - -* The space complexity of the function, which can reach **O(m + n)** , means that it can consume significant amounts of memory for large inputs. The growth of the recursion stack can strain system resources, especially in environments with limited memory availability. - -**Practical Applicability** : - -* While the Ackermann function is an excellent theoretical example for studying recursion and computability, it has limited practical applications. Most real-world problems do not require such deeply nested recursion, and simpler recursive or iterative methods are often preferred for efficiency and clarity. - -**Understanding Recursion** : - -* The function serves as a valuable educational tool for understanding the principles of recursion, but its complexity may pose a barrier to learners. Beginners might find it challenging to grasp the implications of such deep recursion without a solid foundation in recursive algorithms. - -**Use Cases** : - -* While primarily of theoretical interest, the Ackermann function can be used to demonstrate the limits of computational models and the effectiveness of recursion in various contexts. However, its practical use cases remain limited due to the aforementioned challenges. - -**C++ implementation :** - -**Output :** - -Enter values for m and n: 2 3 -Ackermann(2, 3) = 9 - -Enter values for m and n (non-negative integers): 1 4 -Ackermann(1, 4) = 6 - -Enter values for m and n (non-negative integers): 2 5 -Ackermann(2, 5) = 13 - -**Code :** - -```cpp -#include -#include -using namespace std; - -int ackermann(int m, int n) { - stack> stk; - stk.push(make_pair(m, n)); - - while (!stk.empty()) { - auto current = stk.top(); - stk.pop(); - m = current.first; - n = current.second; - - if (m == 0) { - n += 1; - } else if (m == 1) { - n += 2; - } else if (m == 2) { - n = 2 * n + 3; - } else { - - stk.push(make_pair(m - 1, -1)); - n = -1; - continue; - } - - while (n == -1 && !stk.empty()) { - n++; - stk.push(make_pair(m, n)); - n = -1; - } - - - if (n >= 0 && !stk.empty() && stk.top().first == m) { - stk.pop(); - stk.push(make_pair(m - 1, n)); - } - } - - return n; -} - -int main() { - int m, n; - cout << "Enter values for m and n (non-negative integers): "; - cin >> m >> n; - - if (m < 0 || n < 0) { - cout << "Please enter non-negative integers only." << endl; - return 1; - } - - int result = ackermann(m, n); - cout << "Ackermann(" << m << ", " << n << ") = " << result << endl; - - return 0; -} - -``` diff --git a/docs/Recursion/Count-all-subsequences-with-sum-K.md b/docs/Recursion/Count-all-subsequences-with-sum-K.md deleted file mode 100644 index b2b0ad894..000000000 --- a/docs/Recursion/Count-all-subsequences-with-sum-K.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -id: count-all-subsequences-with-sum-k-problem-dsa -title: Perfect sum -sidebar_label: Perfect sum -description: "The Perfect Sum problem involves finding all subsets of an array that sum up to a given target sum. The solution uses recursion and dynamic programming to efficiently count subsets with a specified sum while handling large values using modulo." -tags: [perfect-sum, recursion, dynamic-programming, dsa] ---- - -## Perfect Sum Problem | Count All Subsets with Sum k - -- Problem Statement: Given an array arr of size n of non-negative integers and an integer sum, the task is to count all subsets of the given array with a sum equal to the target sum. Due to potentially large outputs, the answer must be computed modulo 10^9+7. - -``` -- Input: - n = 6, arr = [5, 2, 3, 10, 6, 8], sum = 10 -- Output: 3 -- Explanation: The subsets that sum to 10 are {5, 2, 3}, {2, 8}, and {10}. -``` - -- Expected Time Complexity: 𝑂(𝑛×sum) - -- Expected Auxiliary Space: 𝑂(𝑛×sum) - -### C++ Implementation - -```cpp -#include -using namespace std; - -class Solution { -public: - int countSum(int arr[], int i, int n, int total, int sum, int mod) { - if (i == n) { - return (total == sum) ? 1 : 0; - } - return (countSum(arr, i + 1, n, (total + arr[i]) % mod, sum, mod) + - countSum(arr, i + 1, n, total, sum, mod)) % mod; - } - - int perfectSum(int arr[], int n, int sum) { - int mod = 1e9 + 7; // Modulo value as given in the problem statement - return countSum(arr, 0, n, 0, sum, mod); - } -}; - -int main() { - Solution solution; - int n = 6; - int arr[] = {5, 2, 3, 10, 6, 8}; - int sum = 10; - cout << "Number of subsets with sum " << sum << ": " - << solution.perfectSum(arr, n, sum) << endl; - return 0; -} -``` diff --git a/docs/Recursion/GrayCodeGeneration.md b/docs/Recursion/GrayCodeGeneration.md deleted file mode 100644 index 1d60f1d40..000000000 --- a/docs/Recursion/GrayCodeGeneration.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -id: Gray Code Generation -title: Gray Code Generation Using Recursion -sidebar_label: Generate Gray Code -description: "Gray code generation is a process of creating a sequence of binary numbers in which two successive values differ in only one bit. This unique property is useful in various applications, such as minimizing errors in digital communication and ensuring smooth transitions in analog-to-digital converters. The generation can be efficiently achieved using a recursive algorithm, which constructs Gray codes for 𝑛 by leveraging the codes generated for 𝑛−1 bits. The resulting Gray code sequences maintain a structured format, making them ideal for error detection and correction in digital systems" -tags: [Gray-Code, recursion, dsa] ---- - -## Gray Code Generation Via Recursion - -**Problem Statement:** - -- The objective is to generate the Gray code sequence for a given integer nn**n**, where nn**n** represents the number of bits. Gray codes are binary sequences where each consecutive code differs from the previous one by exactly one bit. This property is particularly useful in various applications such as digital communication, error correction, and minimizing transitions in hardware. - -**Input:** - -- An integer n `(1 ≤ n ≤ 16)` representing the number of bits for which the Gray code needs to be generated. - -**Output:** - -- A list of 2^n Gray codes, each represented as a binary string of length n. - -**Constraints:** - -- The output should follow the Gray code sequence rules. -- The implementation should ensure efficient computation, especially for larger values of n. - -**C++ implementation :** - -**Output :** - -Enter the number of bits: 4 -Gray Code for 4 bits: -0000 -0001 -0011 -0010 -0110 -0111 -0101 -0100 -1100 -1101 -1111 -1110 -1010 -1011 -1001 -1000 - -**Code :** - -```cpp - #include -#include -#include - -std::vector generateGrayCode(int n) { - if (n == 0) { - return {""}; // Base case: Gray code for 0 bits - } - - // Recursive call to generate Gray code for n-1 bits - std::vector previousGrayCode = generateGrayCode(n - 1); - std::vector grayCode; - - // Prepend '0' to the first half - for (const std::string &code : previousGrayCode) { - grayCode.push_back("0" + code); - } - - // Prepend '1' to the reversed second half - for (int i = previousGrayCode.size() - 1; i >= 0; --i) { - grayCode.push_back("1" + previousGrayCode[i]); - } - - return grayCode; -} - -int main() { - int n; - std::cout << "Enter the number of bits to be entered : "; - std::cin >> n; - - std::vector grayCode = generateGrayCode(n); - - std::cout << "Gray Code for " << n << " bits:\n"; - for (const std::string &code : grayCode) { - std::cout << code << "\n"; - } - - return 0; -} - -``` diff --git a/docs/Recursion/Josephus-Queries.md b/docs/Recursion/Josephus-Queries.md deleted file mode 100644 index 0f26a13d2..000000000 --- a/docs/Recursion/Josephus-Queries.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -id: josephus-queries -title: Josephus Queries Problem -sidebar_label: Josephus Queries -sidebar_position: 1 -description: "In this post, we'll explore the Josephus Queries problem, where children are removed from a circle in a specific order. We will discuss the recursive approach to find out which child is removed at a given position and provide solutions in multiple languages such as C++, Java, Python, JavaScript, and Go. By the end, you'll understand how to efficiently determine the order of removals." -tags: [dsa, recursion, josephus] ---- - -## Problem Statement -You are given `n` children numbered from `1` to `n` standing in a circle. Every second child is removed until no children are left. The task is to process `q` queries, where each query specifies `n` and `k`, and you need to determine which child is the `k`-th to be removed. - -### Objective -- For each query, return the position of the `k`-th child that will be removed. - -### Example -```plaintext -Input: -4 -7 1 -7 3 -2 2 -1337 1313 - -Output: -2 -6 -1 -1107 -``` - -## Constraints -- $1 \leq q \leq 100,000$ -- $1 \leq k \leq n \leq 1,000,000,000$ - -## Solution -This solution employs a recursive approach to solve the Josephus Queries problem. - -### Recursive Approach -The problem can be defined recursively as follows: - -1. If there is only one child, the only child present is the one that is removed. -2. For more than one child, the $k^{th}$ removal can be computed by reducing the problem size by 1 each time we remove a child. - -### Recursive Function Definition -Let `josephus(n, k)` be the function that returns the position of the $k^{th}$ child to be removed when there are $n$ children. - -#### Base Case -- If $n = 1$, return $1$ (the only child). - -#### Recursive Case -- If there are more than one child, the position of the $k^{th}$ child can be found using: -$$ -josephus(n, k) = -\begin{cases} -0 & \text{if } n = 1, \\ -(josephus(n-1, k) + k) \% n & \text{if } n > 1. -\end{cases} -$$ - This gives the position in the new configuration after one child has been removed. - -### Final Adjustment -Since our function will return a 0-based index, we will need to add $1$ to convert it back to a $1$-based index. - -## Time and Space Complexity -- **Time Complexity:** $O(n)$, where $n$ is the number of children. -- **Space Complexity:** $O(n)$ due to the recursive stack space. - -## Code Implementation - -C++ -```cpp -#include -using namespace std; - -int josephus(int n, int k) { - if (n == 1) return 1; - return (josephus(n - 1, k) + k - 1) % n + 1; -} - -int main() { - int q; - cin >> q; - while (q--) { - int n, k; - cin >> n >> k; - cout << josephus(n, k) << endl; - } - return 0; -} -``` - -Java: - -```java -import java.util.Scanner; - -class Solution { - public int josephus(int n, int k) { - if (n == 1) return 1; - return (josephus(n - 1, k) + k - 1) % n + 1; - } - - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - int q = scanner.nextInt(); - Solution solution = new Solution(); - while (q-- > 0) { - int n = scanner.nextInt(); - int k = scanner.nextInt(); - System.out.println(solution.josephus(n, k)); - } - scanner.close(); - } -} -``` - -Python: - -```python -def josephus(n, k): - if n == 1: - return 1 - return (josephus(n - 1, k) + k - 1) % n + 1 - -q = int(input()) -for _ in range(q): - n, k = map(int, input().split()) - print(josephus(n, k)) -``` - -Javascript: - -```javascript -function josephus(n, k) { - if (n === 1) return 1; - return (josephus(n - 1, k) + k - 1) % n + 1; -} - -const q = parseInt(readline()); -for (let i = 0; i < q; i++) { - const [n, k] = readline().split(' ').map(Number); - console.log(josephus(n, k)); -} -``` - -Go: - -```go -package main - -import ( - "fmt" -) - -func josephus(n, k int) int { - if n == 1 { - return 1 - } - return (josephus(n-1, k) + k - 1) % n + 1 -} - -func main() { - var q int - fmt.Scan(&q) - for i := 0; i < q; i++ { - var n, k int - fmt.Scan(&n, &k) - fmt.Println(josephus(n, k)) - } -} -``` - -## Conclusion -The Josephus problem presents a fascinating exploration of recursive algorithms and their efficiency in solving complex queries. By employing a recursive approach, we can derive the position of the $k^{th}$ child to be removed in a circle of $n$ children efficiently. Despite the recursive nature of the solution leading to a time complexity of $O(n)$ and a space complexity of $O(n)$, it effectively highlights the power of recursion in algorithm design. - - diff --git a/docs/Recursion/Knight's_Tour_Problem.md b/docs/Recursion/Knight's_Tour_Problem.md deleted file mode 100644 index 095105f36..000000000 --- a/docs/Recursion/Knight's_Tour_Problem.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: Knights-Tour-problem-dsa -title: Knight's Tour Recursion -sidebar_label: Knight's Tour -sidebar_position: 3 -description: "The Knight's Tour problem is a classic backtracking problem where the goal is to move a knight across an n×n chessboard such that it visits every square exactly once. The problem is often solved using backtracking and recursion." -tags: [knights-tour, backtracking, recursion, dsa] ---- - -## Knight's Tour Problem | Find a Path for the Knight to Visit All Squares - -- Problem Statement: The Knight's Tour problem involves moving a knight on an n × n chessboard such that the knight visits every square exactly once. Given an integer `n`, find one possible solution to the problem. - - -```cpp -#include -#include - -using namespace std; - -class KnightTour { - const vector> moves = { - {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, - {-2, -1}, {-1, -2}, {1, -2}, {2, -1} - }; - -public: - void findKnightTour(int n) { - vector> board(n, vector(n, -1)); - board[0][0] = 0; // Starting position - if (exploreTour(0, 0, 1, board, n)) { - displayBoard(board); - } else { - cout << "No solution exists." << endl; - } - } - -private: - bool exploreTour(int x, int y, int moveCount, vector>& board, int n) { - if (moveCount == n * n) { - return true; // All squares visited - } - - for (const auto& move : moves) { - int nextX = x + move.first; - int nextY = y + move.second; - - if (isValidMove(nextX, nextY, board, n)) { - board[nextX][nextY] = moveCount; - if (exploreTour(nextX, nextY, moveCount + 1, board, n)) { - return true; - } - board[nextX][nextY] = -1; // Backtrack - } - } - return false; // No valid move found - } - - bool isValidMove(int x, int y, const vector>& board, int n) { - return (x >= 0 && x < n && y >= 0 && y < n && board[x][y] == -1); - } - - void displayBoard(const vector>& board) { - for (const auto& row : board) { - for (const auto& cell : row) { - cout << cell << "\t"; - } - cout << endl; - } - } -}; - -int main() { - int n = 5; // Size of the chessboard - KnightTour kt; - kt.findKnightTour(n); - return 0; -} - -``` - -```python - -class KnightsTour: - def __init__(self, n): - self.n = n - self.moves = [(2, 1), (1, 2), (-1, 2), (-2, 1), - (-2, -1), (-1, -2), (1, -2), (2, -1)] - self.board = [[-1 for _ in range(n)] for _ in range(n)] - self.board[0][0] = 0 # Starting position - - def is_valid_move(self, x, y): - return 0 <= x < self.n and 0 <= y < self.n and self.board[x][y] == -1 - - def explore_tour(self, x, y, move_count): - if move_count == self.n * self.n: - return True # All squares visited - - for move in self.moves: - next_x = x + move[0] - next_y = y + move[1] - - if self.is_valid_move(next_x, next_y): - self.board[next_x][next_y] = move_count - if self.explore_tour(next_x, next_y, move_count + 1): - return True - self.board[next_x][next_y] = -1 # Backtrack - - return False # No valid move found - - def display_board(self): - for row in self.board: - print("\t".join(map(str, row))) - print() - - def find_knight_tour(self): - if self.explore_tour(0, 0, 1): - self.display_board() - else: - print("No solution exists.") - - -if __name__ == "__main__": - n = 5 # Size of the chessboard - kt = KnightsTour(n) - kt.find_knight_tour() - -``` - -```java - -public class KnightsTour { - private static final int[][] moves = { - {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, - {-2, -1}, {-1, -2}, {1, -2}, {2, -1} - }; - - public void findKnightTour(int n) { - int[][] board = new int[n][n]; - for (int[] row : board) { - Arrays.fill(row, -1); // Initialize the board with -1 - } - board[0][0] = 0; // Starting position - if (exploreTour(0, 0, 1, board, n)) { - displayBoard(board); - } else { - System.out.println("No solution exists."); - } - } - - private boolean exploreTour(int x, int y, int moveCount, int[][] board, int n) { - if (moveCount == n * n) { - return true; // All squares visited - } - - for (int[] move : moves) { - int nextX = x + move[0]; - int nextY = y + move[1]; - - if (isValidMove(nextX, nextY, board, n)) { - board[nextX][nextY] = moveCount; - if (exploreTour(nextX, nextY, moveCount + 1, board, n)) { - return true; - } - board[nextX][nextY] = -1; // Backtrack - } - } - return false; // No valid move found - } - - private boolean isValidMove(int x, int y, int[][] board, int n) { - return (x >= 0 && x < n && y >= 0 && y < n && board[x][y] == -1); - } - - private void displayBoard(int[][] board) { - for (int[] row : board) { - for (int cell : row) { - System.out.print(cell + "\t"); - } - System.out.println(); - } - } - - public static void main(String[] args) { - int n = 5; // Size of the chessboard - KnightsTour kt = new KnightsTour(); - kt.findKnightTour(n); - } -} - -``` - diff --git a/docs/Recursion/Letter-Combinations-of-a-Phone-number.md b/docs/Recursion/Letter-Combinations-of-a-Phone-number.md deleted file mode 100644 index 29f740967..000000000 --- a/docs/Recursion/Letter-Combinations-of-a-Phone-number.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: Letter-Combinations-problem-dsa -title: Letter Combinations of a Phone Number -sidebar_label: Letter Combinations -description: "The Letter Combinations of a Phone Number problem involves generating all possible letter combinations that a string of digits (2-9) can represent based on a standard telephone keypad. This problem is often solved using recursion and backtracking." -tags: [letter-combinations, backtracking, recursion, dsa] ---- - -## Letter Combinations of a Phone Number | Generate All Combinations of Letters Based on Digits - -- Problem Statement: Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent, following the mapping of digits to letters as seen on telephone keypads. The number 1 does not map to any letters. - -``` -- Example 1: - Input: digits = "23" and Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"] - -- Example 2: - Input: digits = "" and Output: [] - -- Example 3: - Input: digits = "2" and Output: ["a", "b", "c"] -``` - -### C++ Implementation - -```cpp -#include -#include -#include -using namespace std; - -class Solution { -public: - vector letterCombinations(string digits) { - if (digits.empty()) return {}; - - string phone_map[] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; - vector output; - backtrack("", digits, phone_map, output); - return output; - } - -private: - void backtrack(string combination, string next_digits, string phone_map[], vector& output) { - if (next_digits.empty()) { - output.push_back(combination); - } else { - string letters = phone_map[next_digits[0] - '2']; - for (char letter : letters) { - backtrack(combination + letter, next_digits.substr(1), phone_map, output); - } - } - } -}; - -int main() { - Solution solution; - string digits; - - cout << "Enter the digits: "; - cin >> digits; - - vector result = solution.letterCombinations(digits); - - cout << "All possible letter combinations are:\n"; - for (const string& combination : result) { - cout << combination << endl; - } - - return 0; -} -``` diff --git a/docs/Recursion/N Queen 2.png b/docs/Recursion/N Queen 2.png deleted file mode 100644 index f0c8d59b340f2e1a92f27db1115c1283e953a3b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70847 zcmdqIcT|(x7dD6mQ4qK)$Q1-sR0IS>nsghzNtaL}(h0qH6h)Md^ctm;0HK8z0*E5g zdr9ab1QH-p5=scni(Y^C_kC;D%&eJj=8s`57H`6voOAYhp1t?k&wk%M(NbolXQ!v3 zpd(hA@eLng<*6vbdMMHC#ulo3bzOVVp6x}nH5%xE8!e_2m)0{Cle(PAC&-KCl z2(fr3!;`ePUqqlkT)Xwn;GAOmwTt(cRT8f0o($cZ4!Cvv<72hss%zbAA5ULhd6PWV z80#Y>bJ)Go-Po{SG}1tiN*9rO$wXTdB%{ckDn*PlvG5|? zT9JTmzeeYRKesOnQs(AABkcxU<(7-U#aV9z>Bq|3du}^F(Ivj@DocU$gNPs3Ka<{( zf+^)V$XH!d?fsnXA=-L_!;uFm@(CsO11o%c#mbMWWOpH=&kAhL-ho=m722)-$Tm{& zj;C@TgIyFAt?dtq!7x1}yy5#IMR&9v5*}~NqE9Usx=;vhHH-$$@p4FmZI_UtJT8lv zHlcNfCtp2}(U%uYTx+REFi-+ECR|I+P!AG>f|=>#LO!5n6ZWYZ%NL9Gnu%M634bX@ zQS^yHTV>M}hXN)xM>sQOJCVbdcnYaE^8F=t$Kz5Gvp}xDaEzE&E(wC)+z`~LMm> zNvP`Rmd;^(I&!((`0DON#q*{`#JKaKvj!oB0tQ&yT;m)uGm(?&W z7sVL3L+0xWNtq;TcdQFpYF~wOIxC-t7Dnh$vOz{h6ye3QC)~IWhxYg_Vo2v5MgGc9 zpzC?$Gme{Q7yQdq?j~yC@k88D8E-?-^fi9>h5GWf(nyngWo_bXrC*Y7@W+oTyfdXh zW^iP2^ad$*=tb=wq%jRO3&Jg{36#);lL`V)Xzh_!Sdbf#A@89G- z$ZjUfIiv8%8@mT6^17MeM~G)V9AWew_w}uGiT&an?O1R~!*^*YvyeP7fptURS)Z)e z&UoNWse*X+b@e*q&mHURX1*aPp>+r`=I0!D@%GO{E+WZ{C=LD;*0*=q7+$uSHh&-@ zL!3K_c*#I?nTVcpF=}k;k~+w4B-huE1`O$F58^f!%0jr!HtUW7d&4s)f-?WR*qT#a zVD?)e+B`R*0Ar?{{+i#xq>jn`?v{di#yZvRpMz7m}8Dw!Z&wTLyVd^E3KqQ8t}Oj=F#QX#)1Rhd_rg;ad> zzg@FvCR-5a{c3A(~j2iiw)eS>EAA~ixL+99o z@jqUXk>1_Xj|HjvNmyn{kKW{vsZyfyKnnQPJF`-P=nROxfUTLT-%nRYq!E zhmFWkG@5$qo|yUxt`*q1m~AEAWeyKCm#=a&*%^NAVAQY5-1C07QnWuj&HvC|fkI2P z8?3aUuYh*h$bpByYa8TNQ9-NJH}>t!=lBOF_l^gClkOF%M;3X!u%V{uc;QX9KW%7> zUn$5kukVvKW;5@z9y`EqvV7oS5S9&*2|5U18)q`TZ;U~YdQ>B*WV92%Y8Dy;XqQ}=@d0q;aZ;;7nh$&Bd zi5rI0u+Kh@YY*mBSJ2J36`p7bmLucB(!2ss1qJ>{C-xo6HhVC%2h{Xh;N<+#ec={7 z-MGRaSu!c2LLp?rcw4&_&zy>oS2V=eW6h8)!v{R^+qfGD{Fp(s=Z`4||24^g>4uwC zsG@J9!ae9`F{#y^*Yt=N0?5 z%T=TBS*_Ib0PVgz-(^Zb|2?p`(WewSPb}mc3vTA!;&PB3-`#!^3RO-Nj|Hm)0#JhR=Uo|^&V(6dJ^wl-`IXRe^5Qm{7QJ5 zr?>f4RZqpCyxJ1U%v)#z6jF$Gw8hUotqPIU z;GxRZm)@04k;VF@Z+b_cEnJ3}y~pga?Tz2!Jkaj9&dB*Zs%O>ZR!n#{JeciY*I1P? z=OM}r4qPj6snH8dm>=F~t@ImZt6elJbI{p#EG%U44*bzZ!ZS{k^&6UvOo2vo*9+-m zE1RFN8oWDyNY%~v;edVl!r3eAcVlINtx3!n>?$Jzg$M3xr3Z=Wk6@+y!XWJ|1wuV= zzInX1L0^f{G*d%~Kh&0;|5=+d8zE*D>f65V@AR?_CNQ%Wk000@tazheBqX?}%gGM- zfG-Vethr(bI-8ACCBm)-6GiHZkhYkt;p(4fGy^J%JkrFG`_Jm6^&9ptvrx7By&i03 z&uj(iRrP%1q__Ve8-gD<&`y>q)?p*t2Gvi+BTCH!M?j-xX|TPXF%LF#OFzOccSW-m zawLH{%wdMvOPDKsev)^%|L2wxqX-2F4bWSZc6g?+9r9z;q)$?>W@NE32?4(<^Jt{n zOu1@5G*)O@ImUjRpEkKPm#s%v84?fE-TB}R^O@^<_UxPi!&I3LQPLwbMJEex+~-mw zJk#s8`ng0nj_on=61=@o+`^AESb! zqa>U-_&oc5s&9MR6a0jj8yppC^zyrA^hW)(R;bGnkRW+kOm0G}mUg}8A&J>1F!-ho z_S;Ogv>7L(DQnrK+;D;iA<*36h6i=Ka41mma;F1YSW}=_$%6mA_VK%sbzbK;mZdiLHf2|kP(ew4SwK{S@h4Oq3d-D)e zP1g2no-3*=)HT<(fLj%Pxv$5!mB9pQ#V|N@UUWO6&q|%B-0gwU+x;|3qSwn}Te-nG zvh`97)W15op$^5QOpa5NTWr73^2ii_4GZW=m+r1uYwI%cJ;Vh$a{GwmY%u_1T^559 zzqy?N2y0Zw;>}uA@FrSgjFY0E+RimV&N7Nxue6Pj7P|%87)_Z7@v!wsyte2$=;7jJ z5Wdb)wt3^W8b`20Q8;%oTnDmpXvJCNxD5jPc1ojo9`D;LX!9a3*AA?6S696O9r`=P z)-ODDu+4Fx0n znPo?MK3hSQB>ea_!{x5SYHxSV?&8z!n-dbjjdS03J!Em&Nh##o!sZ%cZ4-!9j91d* zocL@tB@{7uG00Z8ioI4Zb}oe~{cM;&Xr=*vN~6(LF)Pz7rUVjf-kDloRE)(f ze`DP?eo>XA#t(^*4y-_dzceK*%GZbq!TM8I=?~kgncN$-2S;Jc&tX_F$EL zHq|4AFt*!3+!mOA^e%{N>Xx$6ppti_Jb|m%B4TvPG*7ktaf9Xb(l6X6X-Ib7CeOD- z@vqzh9c;>b2Pe~7iEW+<)|&37d<&aDI+sVOTZ}b6@bBX~(UpFx8&hc4TtW{SS+2au zlRUl@Y4Kq6zHQtE&H%qLwy{iE4ofbnjoXnVVU$VFX6D;u%VN?3p(9?e`dRE$)>XLL zh*N>>%;h|Aisk?v^Sx0|^&E;D%lT&yPolhDO!2p@z4uLOacpQz_@L*Uzg}gI`)F)) z0E*!6-%IAgTD`J#4Qk(lt_ic<8>1jNV@53-mR}K3{u;)tc0LcPP&jIMG1&P>6NE1G z%&knRghT`;pNc>a%k@-rH!!>GclG9P;(U7rR^C=$#9A!S1&KeiNK{jpG6HMY#8?jm zQnzfxA<^;pb&`tHX~#UHz33sVfdJCZJwz_;+dWaX@lU-A4~i0krjN6dv0-D5nup85 z4&zfPi`eEpsi#xWwY(VQ2JiW;>m~M3K2VKg{@1M)Sj?zLVpC$`4d-2X&JL3?f2vcd z@Dk@pp`tx47Y28ETuxbu_T-ylN*lymal7L6_#DRi`0>>fZlnW`Fv^(SurgKL0iq@{zyMPleZ9l?A*eq-El4r-vOE`}?P!weA0#^&|+7Bk_i=WE{Hda5> zCiW-V%djLNs^>-P9Hu8D#zopH3IZlkz3-Z4F2s%FbOy(#3UDUGPp*uC7=LC3Gv$wL zhz=Bfdn7RH_CdA$rF%pEf^+FI-#HD$)w7)EX6Q8c9NtqIvK2_fkz|}YA1-9Lp$q~* zEP`?xz*k)p0I+P=9*I|%n0KvnW5$t()qn3IZlR15Z?q8o!6y;PBGHy#nCWnvC;5FI zY|5q`&zyhx6r7`Mmuc?uL`e|5ukz??@1O(a!*L-mA9v;N6xB>Q8zbm+5b5~^y}DUt ziu!YjFj?nCz;VQt3`kcV`h#^PZ*}g4x>rQ@gz=TEvX*jW5~xN+l^C#Z_c;HUbx^#A z(_fZGu^oZ+4cE%cwU$PvG$t0kYYyB73g&r*2;P1c{JHH-?`^m%lW&kgWzyM@de4K) z6x2hza^#)SCi_K*O05k{r#PxJr3^lHC=1t(#!5A1D(`Q^ON%jicw_uL%n1_oz$Gv4Z9JaZit3%0@zfn)LphnHn*pn0b=ay0T{3BW7hQG2(p$sx!pClbnW8yP0SaidbiZy!VC7 zJ3iCUgj#`XkRlk)Dfe3awd!>?`%l@Q=>;d1uChK#BK3RQ3Mix?g6eWbVzXk_~854_Juj*iHJEtgZ%l>1#8_k91Lz=;YK&-xAJZ{LypE(lB_E|r- zg35I{pE1QOf%X*&X6=N76mO5pDyBH(@g8pabeA^FwK#r8Z?2-aJa7LMu%0c zNFX*J1f4v}q@kiK4l*hU!O$Gl3*EyLT%MEeRx=?@c3|gEOn`sV^~v+dXpb;2Bq@H_ z7$YG1nzM=}Zmb@La^-(E$?x^>^M&bm@HE9rIL@;y13SfK)G2sHYPgo4+Xl z-$jfLh#1vAdMk4Ho?Evqn2|~<@gV1X*-of~#9;D2fyz6;`6gQi)X37)?(ksZDgONE z^pGjxM{`);JD{s!Gxb_2d^rD)qyB6Uv*Xw{1g?8SCCo7SqF2c&Z?6#4QE8f)@b>Bl z%CWRCyCiR;liKPmZeJQklQO3a9Syp|?ty6P_mXY|cAZni@xyA*@7$<-J2hGvH;8vP zAjne~X00t2z4TW(3;Ks9ki*g;G1LVl*=LS@aTT^-pBH3;kgcaw@2L!jx#b>0s7jno zcOR>KI}ya1ED1VCD0BSeKG%r!5=j&@W!f%l!_W_i=Nm|iJyE{s;~sb}xMZ`C-RomO z!4zJ=EI175uCRX~Y(#8+ZHnV^C9#`T>u|)@zn3s0Qtjz9u6BlqhzflFE(OiuRL<-F zp3&QG3t9sAu#KqB)aI#Zn`v?JH5Kzfq9h~Z3Sk*hmYH4z# zgLQ0IMZfy)Vv*(Iq+hel4YHr7=7bjB>e<@}^Ks?#iX}272}V<)WA!saE0osM=YG_r zud<#-Z)frk?<_P3$n&~<3d&QGBk3Iv={w5x*i0QUtZ_H=Khkz5j_f^TMQbwz?<~Qf zqs>?L2|DyX)zy_vMdK4cRAlj$)`G_EB24eli}7u*hClB;zp(BW5)ImzG$24~j%$X6DUh`P_`ReD2F~OXDqri^3>EQP^&^@$* ziuwt_WIvKXHa>?>#r1+5R2fd83$EIfemQ$dUQ6a77C&Zf6A-{YG;|yN#oQ$qIeoTj zI*Lh=W!)r%B-(Ysnsb8b@Q#;{ql}hI+6J=DTVrm|eFbpQBz&7CNW!NsTa2_s@pmXK zW-dumntL~?ZgfdjWxjU7Faz4Ni5;qR+na5z)J)S4X?YXbbyJE-(3C-fOGkw|a~XN* zL>X7(&2rO}$ceKhP*o0ICU&hvH_XTep06}`r9UBTIv1qRX&mGrQ+PG?j*qifw0j z+tlmrjJvLW(^Up%EOcd8gm4P#Yw~XE^Hphm--C=s+)Bbfs{xZUV5gLfaRmu)yzanF zht6@zUo4GlXg0$SvI0fzRp;Qy=HVh*TZ6ftG`83vb#6i{i zPTYQd9RRdoBn~qFaT2C5Z9d~4YkJ^T?VHzHYpu6>j4d0U5Rn~gXqU^k_rXz_$`ZVb zgcSBuMa92I{B>u5(jyx}b?Nqq3f`-9e*cc+4v(o$n{@horMwB;N>{((j@M=PtkLMP z{mkmAP|B^U`t6?E00&%eKtFu=;Jf*h-%ykENE8Il1~dkZu~RRRbmKjRtLZ?U=c7B~ z$3ABB4uOG$w~!NeSFVmJ%l2|xK}2>p<$7xjgfg6%WhdXq=DVM~wb;+!W1g-uc0b_B zlrDxPtHr}K@msL-TLFsJ>v`Ez*~40tlxv!TS7SWlck{Z&aOVT=d!Pt$gmxTW#EigI zcYt=|d}k)mzFU)Q<|b@L*q7aPs*`qz!yfuR-Q7pHg@EU!oMOh__j?POZBNp}O+d!S z%R+>N%iv$8f%;x|X=-G=2r?Y8d@0)(YTwRfo5S85N}T+M4+=FdQx zDf{7>P1U#a9;V(EV)WsHT7r+AIW+T2`?6LGpPnys&rG3FG?g_{Ea^+RMc7=}8{0~U zCal#BZJz`7rm;2TbD7C^-Er3GZ9McDopU&Yg;74)dyMb8V#d`ue}N^*5y<*Ln{XxB zZ#CO(CBK{j_!P|xnUz5r5>4D`Wuv)JCvp3lOB2LxS1)0<(x3LKgutVWpQfeMl>_8` z%qM#)zwoWZpx~lXnvhbj1spMODXyXlTq|IY%A6MMLwG{k7TuKd$5-Jb17k zA0KaXk%orv-o0_z<45c2d)OuPdwsr)t^b#=e4BQB?e~3`yD#b0MSuU^{c2)mXI*B~ z|41L8QCa*Y>hbXK^xU3(`P?#pxH!MW_=bXlUZdv9ho1KK?nxyPkwFwuZK@&dxT^;( z9bJa<(FbRZPorjcSIPyPK+B}D{M*JF1B$uI>R$M|=Bys)5oQ@NK;kKj{}oqnw4XeA5@=F<$Emdj9pjSeZ$;hIv)1g0070;-O? zsd0x^(vv8Zbem6Z{WV{m{jx5f6R1^a^6qaa%d%Rq$$}kA60g3h4n~V^xhsb=4Vt*r zH)pL*O7YohEidWlxjyPi*CpX~W4Q`u3+#vT1Wit(T)Y1AKHA`)`casFgk!{mUseO& z{C{*ccY%e4h5OPadz)j-EF1#)>b%kHHx@drBZTl%CjNN7?b@m=1z~Z!E7SuNU)@|7 zTi#vkJo2jMC(TGU^>AjHSnfL7&{wZ|c#bUe^Y&}ApMl=vN&HDaaJKZ$ZzB@|T|T_b zMHBPZ#@gGZZYTyedYH(#o^U?)2QTZy~&=7QCX+2H?H^( zonTfWqEmj}H7b}1PS_)f3UeI|Lt}dXf63bak1hB=S%&tcN;JFbrMsy)k;%8?BiMXG zWK04Z#cZO6EAs*HjNax`W-7K)1;F#^mF}xk|GVIkmswFuP{Q{==*+~hn29;1>leQV zu=D+Uo^Z1UXjaT2F_AY`KR*HhPCFBT#QzC6P)=`*VAUUXdEY0Gnyk6l%J^t?rs+xh z53@`@sVdM%Hw@>7^VM}QE&snuuK!yUoqZP=m=|@a=j^X-tb0+;pu#WX+L<=gJ!yk< zP>oe^w)yp+7TSMZ=Fj`<>$>aT2j5*Nn0=#HnD>H)&wyXAu1T(Gx%!qtc~hS+0t=n~ zc(KqY?S@YaK=T?$n^Sdu{{tvh02^ltRRRJ36pCAXx*5G^S$ZJHnX8mUZ#;zVOpwbR zq}_oZ?%a^}-2#VM^%Q;5OXjL{>O`+^S;{lR*DVI!>cXRaN_{& z*L<;TDwmTITdcLa@1UDsuC~x;G1`coyHH44jKetW-WM4`3pW>=-}S`PugZBobdd!q zhQ~rje=fttY}=R&__LLnK?Jt59XXkwmXoBDpqS$-)4v;3j*R4stlRPJ*$+SkQ$5hh z&QVXI@9tg}EMGA+NgJZOb;s;QV9*6_7s9h2&HjzsCmEME;^=Wb4lpAMmFUDS=2!o< zapqz1exR4UgjT$cZFSJ0h^A?|>QIWa!RLr=*duBseGjWu&GGlV|L%wR{N(Oar}3bt zT@u{=$wA7j92~gQl@XI!n$`@{`QNv#5};6o@r1ZuisQ&P3}mEMk2B1QQEUWgRfr4{ zwmU%;w6gIe=UAFt(^z7giI`QVdp@H|>EcL4k?wk9XSP&UZrdeS-gEyrd0@D| z*VhNJS>a;A2TDE06?%SEwu2|~i8@c?|FULQBmVt#T7eWD`_9@&VTC+$Hi^$Sg$to~ zSGCWc+57N&%FvcQj*ive$VLw>AyZw2QWtuPYCrd)!@rc1J<$M7Pn#&66i_t1{3;#NyZtKXp(J)dQ^eNwl)?Yk$XITe6dF# zQlT)=H3Vq*)=luHdX%aKv%X8XjkfI5P7xI}eC3Ht`%BAolzU_S zp~x~55w(2$bhE4azZ+O*$#gl|{Va`w-+;~T&d$9C9>d$|?IPuA#yW6xml%lOY zELe)Fw7LU1CK>Y|W41b3#Hu2L$1F-G)?>+B@<53{httwx%IIE-=xk@asw(kLswa8J zbf)jA6X%4&-cA}w&Ev!?Ebn3_5~{6CT{ulLhv*pxH%a0~l(J$5LXjx(fL*P&wl+TX zub%vRcM3b%Iv18U&Rhrbi6e)3HEq`2Y1&9~n-L!k||Wmd4-(QQ$~<=7;YSarZ7+PtRSPuR4jO?GNKC`i;k zE!S&Ol(7ru01!exx*6Hb!QIHsNB3Vtes}ElqgFgGwA3gTJg01MS1i2qVt4UFzbgLg z>K`htwS;FfhSQgA%1uCCOEShiFgBf66e8MQu(Yh5EAXIi1SRJBeTID$9e;N!^a0t) zZ8V07QzqYxE(X%^CJ5AMfw-HmojWQX3AafLYM=QgOn1JT@V7 zjeN8`#Q#{fOX`IV4MY^_zq~BDCGe&eYePt#VV71GuB`(nss9iknSc!Jq1okwlH`5y z#}*noEMMRFa^Tg)h+>9d-#cOJaOG?COv7lu%AystPjNY^kQy1=vhc6FyWYv9x?=bQ z*Vk?j@PE&*mtE7O(!i?=H>O8YgDa&4$l}LnQk{o+N%ZZ5HNAfWo&iX((>!;Cy_86(`f!F2(07LR{c}P1E>0?%e7z51)`@5Dq%^D69Xgh(=pSL z|KX_Gu@z@~52Lj~DBQcF-KaA~R3&V~M(1VRv#@E_yzbg1wqryw6vQ0YR|soQ7%`~# z<dlJPn;8h4SikZ#-Olo{@$P?lk>S8G?< z1lxxsQz_PCB5$yH;~baC`Vj#q&AvsT@pk^H7g ztBsN}pA%n&4XlPQp|K6`2WclU54J8?*8XMMWZnE#czkK;0Q6(ck>BJ_;d~#;!)l|5 zTc~B^U#trM<+l;_wR>WADcN`Hhdr{`_@VZwz{2Uv`+-3V8LgnnZsUqaJi*{nqItkL z&j~h}$DnfW+IjJ_gz0gf2KukYbU{E=27>I9X7EM(k2$VkR@*RJqI3TbvbS8aIhuLsedbfB2o0-t2N>Di3URq5I4(@5BZT1LH+{& zNjU`4D(H?u>m5;IjUVXwv?gT0jJNr58vynZ$Jb z>sr0&FrSX_v^9oBgK7!f`P%b{+n0u<8m?ns1+sM}ggt0NSRSNLvCBIpP5b4fZ{XD%*JyNRw(W_b)n6QgVX=}Y%- z!cnX0Xqq`6x&P@~2y$Rgx7l$hxO6)BN!X^%Q5q&4EGQBk!e1p(#w#JAC7QC@A6sPz z>F;7p5}`dC8vI?q8nm@zAdD<33U8%Ph55XTj2r_z8)(cc`ap_|;7|ERSgHxo?(J?6 zxObwI-G%2rh9z9Aq`L%eCU8?_14@HUsxbr4^Hq~tVa7M1p(loBcAA~Q-WJJB7N{52*iaLVzRM{e;5v00s2-p> zmDb8w^yC4kVYqveOYfq~KzXsi79{p!ZL7Mpb(-uLu~XLlp(5!L()Sz_NnVoiy3`E7M90aW@5~^7>q;S2i3p%Cx)n9 z5=5>RSAC!5l5M@!u`GbtVvCwT#@9e*H6(=%dH*QS~!HS8_pJFpH&z9ka zOToP%OHm`z%LK&DXrMW&SFAzcd3dNAt0-hji5x)K?8_omSawKPS0m?W+-;iP{u%58Gy=y+sb( za84NCb?tx3Tn3#Cs2Jj)w&hL8wt`Lr{3)xPE}|i{jKuTqwOJX@%C!|WSfgLQTtIhJ zWN)_D!P0BFMUbxN+HEK7^`0yUy>mHn^X+NTgp=fPPjW!DpNF1G_8)jlW=Q+hZ1UC? zJHI^dU)+AUHRUsd&+=v*E}6KWCE4|>4oWkN(bXSEx{+(sq4PR|m}v7&hRK{21?h;>N*x<1EmBOvl`fj?b-6hK-N@L`dUYgD!fK2XKFYMdboZ z*`XWYS`b~1C5gIOD!#A{MFv|t(B?@9{JM#zB^S60?z&pYS`+XA7H%+r6FnUKOyU}v zqd=eF?o|D%_|nkGf+FZq$17RJ_Dj1)itWV>N=EL>1(0-y8jF#MBL6)8(HOcNZZ~m z)obZv2rDfQ*nsP2V(u1i_Dcq??q>?O(1pb|-bn|1Pu4ivOovT*8(v zX95F*@sk*TqyVQFrk^Hg=~-F4R{0m|j8=f^4}!;B;W z9=1bVEW=;%bp&lo^%d^90kIwH?Ylo5WP2|kmKY&=dU#oG+eqKq>HG%3^Zl56LQ^r?!_4?z8w|7KU zpX9wAt|}aEtOvmMNwuE)XuGdm`gu@J_@RnR(L=GuA~F~;y7}&>?z0M{hh{YRqyTk8 zQD?jUmU^dX_JY})lt@pc!&I`hU*5&#-%!`M`fjDalPNleOB`5p=`xq^ef)%^{Wd1*(jXgHWvCFv?TtZD z(A#;Jr8GWiYGz2sQk7cEjH@!Yu{dZ(XynRhEV*Lhn5Ayi-&a>>gweYNe03j9Bym#O zFv)4xQ_H`(b983C@us}Xi%)K)5`*iNzvwfLz&IO^Ha8zt1{*B!`o-GZ_S3T4pUcRr z`Q~V#v<_5by#*vFsV>)7V5Y{P#_?TqkFniN)rnr4@F?&5eyD9oRqY|k=y&j|Q)~?B z7NY4$nF*VuE!!Au=sH#u;^X%(nGnYz~IIq5sS7j{65x|cM&{y3C z4(+xmef(zW!yD`CI{C>6hlQ7-HdlW!;Qq$L@vz4|oIl@7GaBdApKJG8n>;2SyKA<< z5t3tRBlY_x_oJIM&Fai=NRy4iZZ9YC8)(Um5Y?@xc9IO&#Q!1Fb)MH|D*C2@je+}_ zwHhJSBUJ_q*eiKQ>5U3s$h4Wt=ZTL8a#9LJZRU~6Yeu;tjp&o-fP~+cT z;L4?|D-UzbGIbT-|5$7RyNj#Ovb4LHB2WBy-jM~}MzkBObl&;0g%m~WeR0#kKH z*uy&FooXFGsQq1z8JEDu%^eqgtf~KEhyrlj@gwlfBb_KW9AM9rOV z-&8~iVOp7SKYb;TaG_Cq)A*GvKBLFFyWISZTjA5_j2+iK&)wZHyX6&1*1 zFrVV73!a}(ZGV0duonL{Hl;IJoK_M8wwnnW>#m#Y;LX>{%8OtH7DuJ1lL+cZ;g4gb zoc<|v!;+OR7R%GJ)Cnm zh@3WDU7RR<=EO(LHia)$ztB*1*jG^)cagSe{b)5evpGb0V z6+(rjATrPrs~61}E?$@O#QzhHKQUcdaY{IEh*=RH^zJIdj{sVf_cP0Ig;EoMnm09E zvvKsSfQ`w>3KOY%xH_9{ZO?;Oz#CmD>U|2rg2vD3C0pcu$Q5;;gL}58aA$A9^+gmV zHL~z$GZuS16uO;e%<&`YKq;GLa;yJQuVvFfvYB_}eIJt)%vB5h#6%Im)E&+pY#bTY zANme%t2#jLWl+ZCY@Pw(*K4LU4@tuHcw!dIQ*fm}5hcvxvP zU+1GcpI-m5Rk>$2zgXC!sXR_QdCe!OxWsd_d8jq3U3_ts$-iv#LVEMvl#KE0)Pc+i(vIH zO+=hR-2EN@e~+nl>?OZ`Nn&S;Fd|1W5;o5ZUEUqE`6W2h)GhzcCypMr)YTeCdY4w) zL(iCMjFCluV7 z*ugU8x>Z!|0@bg~qik<4_6*8xs~kH94D2+Khs#cw4xV6nf6K+(zK=_EKBvkyACT>$ zIRIv6$;iy`dfy~VZDV0@vrk<;IklCsye}*0_F6f3GiX~C@D&EI)Etfit)#uJ_#-l{IQ&Z{ zE4pvwqx3dOrnYJ!UuLD8@RII*@RYfqBDTRGT^0kVUL~o3n3|>R3 zXnaAsRj3s>P-To_LI*j?ekOJOeo)@F2CuCk^-NVRvc&Zd^ zG!S)c)bxXcJSEwkYu8-BN9K2q8uu5l>JD93tfzFykJRU-?Uo^#AE=a?<(1`oeAD&6 z;@peZKp{#cnO)9QkMhQ6bZoxB;j0f?f9Ie;I>?AE2{l%7G#<_UM)i}&w7`Z&1vGM^|vd(&PaQ!l0Ym3(CD|Bw~5OKA%SF$%kRh6N5Vi7xRBBl6$xmt zz}bu|BwH3ZXJyIcw?*blI88Q>4i&18z;00GBV&D)H`7-6g0yX%%#jEn!t zQ}uAYg9Vy{ll29&rzq%4MI=D*dqmMpLRx+(z}>T6UysQQj5*H`BbTOW$%*Wc{_)jhv?z&!J)rfZOUFIo3${G0}?Et0WWn`%*7;|<<3BC zk|!^_xvhhmDcmFe%XHSAaY`YKzF4fbe-%rem))=Kix$0sN(PnV0o^4J5>kq{L|+Yu zIM!V(naZUT_#vt8!i1Xm-gUwjwqNy#WS8|GwC@%0XUtdS46Z{>pLt2$h0Vo;7nktk zMUB$|IStR}zZ(?X*Q)v&ZPH9AcW4xQcvP3{H{w_h$s+JW3OsH2elepCXhCUFBr{*Z zTG}QN?>!bxb{;C=20!U5gxHPLyxQ0#=?tK%(!>*bokeWuOxq?H^@o@3O4&zs0G-OK z>lFIvadw)P319<+%1xZn)YZ#LzIzGKd?l#`HGs<0avz?x59TZb9Z>oCj ztw_m{2YltGeBSSQmXy+h*$e-p=^S+qseIX?{b0ve?3hl);Bn8$4%w;w*#vfUE5dAI*?Q} zA#;v=Na4WGb%rH&3a>Xx-IP!|G}%`mQQ-)#?!ymFflKPv+96cevvoSv|46KMm@t;r z$=!R@8oR0^RPkynLNIZ*BOf1NGT1#8p)!bgk5T+V?`M`-s2V)nOSj5Fv5do0@v&mj zRGv3pyg6mMY_CR1l3TO?7foBd`YRdu47+!qB8j5Lxd%_-Yo+|lpS{I@K(T$mT))rf z7Z9mA_Ubh-?RKnxQ%8_m7JiR1ez9JYIq>ksejv5Fhao(o?$27{N?$})y!T4d0$nO@*-z8K`YdRnfJ|@llu_d)4`9^h6+V~ z^D|{W8K32XEAp=2XJ5CuVBM40dmCLt)uD`7xYG$@Y9ABz1C*!Mh+h#x-(x;n|3_qH znRnDE;R+-v3r;kGXV3@bT*aWL2ST2Fp6v?lTE%1m1v~XGI*hB+Pn{etHm{AF*7%`t z%kcxTw=C16(x<%}BCG_SC)4=+(>Izn>JyKe|JXvmJ_~uk6JNfa7X>Y?$bk>j{nF+l1jc=K(k1YgiQs^hog)_ zA7;1w!B#(4qv;nKBS%`^g}^%_KPM>|#d*izVRXc{5REH4%cgPC!Sa3^i&sY zvQK3!nEzS!d64%f_=>{${C0)x57rrE0;$GeYcbcr*+0s2>x;b?)#1(8zL}z0E_gvL zHylP-uv;HhpgWW+lCYexTUCIF*Udc>7sgKBrhU)-2aG`f1^WdyXG1{y`!+VFtf$}% zAEb3pzaiPTAxJm8K^2K063lh>+OLfa!^Q@lB43vLplMw@ta_U3w& zhi4B$ZI*jHX6+I!|Ju_89C9R%dsvS-$&C+&^$JYk+FQQLDeLv*5j&$!WR76>`767* zf1uqZfvEZ>8CKcyD;r5*Or`!^Z zo63=UU2G8pMD#OZ(@B`y^?nkoQaM<}eo+F@F{K{6=wI~kSk-kml=g}t6-s~*-=X)A zZ3vjrhiv2HzFe)p;#M}0(Eq%}V^cB;2=qBg`ECp!H=SBnv@Vik&*z3f$u_`d+ukg=l%Y?YklkEmqK!0 zXWi%C$3BjIVg0H;Atg!Yn|HG4rlcu>&|qR+W}V&c?+*VMX#mN3-Mf8&G=#cNaa=ne zTC2Zt0Uq3C^203DAtX&A8ea7Mskh7b_AIRP8ePU>?bW_svn0@#b|9_>CLZucBKHC| zx$-(yBd}b-PXaFs7WSZ5qytv6x7LmunTt#%b~3LP`nA!ZD@zxC9h{ioH>_l-&@1e# zb@hgO%T%2%S|_LZv*t^$=VCouA@8>CpcugGXgQ{%lcj+ZKg1ECH^~bwZElQhx-$RT zhn!RMjE&4b{0H~cL4YFmXnUW$?_>40N6Ke?XCv?!C-Z~85SwR`CvDX2Ee|%@UV7)T zYv(ZRpS$zDa?W8@rZat&T)=ag)uu9XORLmHd=)3RS?&90xr%qoUs(CHOK&i^=9cp) zo#ZP8DzLhwyafHt>hwRK**Z1C(U&1#ig#ME74OXJSUA=`^%DQgZzhT}qY zP4g`QuMM$%JAhBymmAO3sYFTw>7KqfmI_Xe+QEzi_r@ZBWp8e^D1X)BzP0n;tr#Hd z#7;mt>(tpmx~35`%r`X?O=A-d>M+xs;srSnhietig7qrmcXYtGDq zWQq>*g(G&=g*t>ys>Rn@WV;oq|3Y@+9s<*ce9jX@ z`}9pQ^U5jBsRw_yb%p*)2eAFyQA!%*t;&cGMeP zzMNt=tkF{qQMh()VKLSUcg9c*$kGBym%cIpLs4^!DW8d)?H*j~l9$&X1g2W)Y!dP9 zMhm(?JT)6JMaKc)yIjWKK$zM47XYmSL|_0)b<|^ZJK-Y4fh9}T1X%9I*+!`kQZ??p zXiA80%K+^-8uSmbXY$j}i17cCz5Ty2nE#EP@Av1RQLH5o)@(J|j@d5?wLtX?-@y9@2vfRs8qVpK#F zUjF#!CVU8cqc&Y!hzVvrliS$v<;KW5rATpSVJ|$yg2#c#I|DhNj)_))`c9kd0G2`I zNKUB>j_hW>^SnDdt<2mdZq@*R#Ii57%N)Kx9t0z z0sSMkyw=ITXA>paGAsdbvk&C8Wpwr?ohbj1_puzvoE(Q?lpJ zNBe(0=tSd~VJdk35fc1bpouQ)4y;dmZVhlt$X(`@(8&T?1GsvH3J2Z5^J@8}36H)O z&VqbXHqXNr2Ov^PRJu;KpD{=;(p55mR9nab6ic{aLmK4%i=()OMR3Dom)4Y7Q`|B( zgE${%(6tD2?6`M-JDvYBJf)Tu_v@?=OZ+FvvD=|v4XEb=_(Dr}K9u5ZbfcxwGj8L% zOi6s$Cgt7;0aoQo-`t6Jkwb`=i z(ho#iLQaAbu)F&!%&2ISAq=28C|!0#rXC9ez{q}$ja1p>H2`}|Py&!yhKa7H@VSM{ z|K6L*W}}&=)uQRwdVDX&YX-}M^YR=(SlR_cmEmfG9y`0Z!z zbZBVpQ0Dj2kGVkK2U0ef>|gIbgn9Q8!y3R;ws*sIn6rU9%bf-CT9ei5&rb`%gtS06 zcUQn3U|@I0#>D9uj?sA2zWg9T=G}-^5SHVGyEQdhT$m=|cTf#%wvN1^gY`0~7PC)xGd4 zV28)*uv@(R#d~&}V|f9XfRWb#LXbb!xg7=Z&XQe*e>lA9%)TA{)BoMbmlA7qR{yTm z)m8W{l`7@UueAe|b}9W(C>^MK^q?{f@XDBR@_I0_pX0gb29O9wHvGSsnL5j;78a<) z&GVOUGu*MO+UoD%zj+cWkuNey(V_e|BL94?;rO)at38qe$cC!`(3|Lw=Q1Im{K_V) zaHTG>Q*<@8pCcZ&o&Q}}I6OKcLY-{J@U}d~0 zuKV#o{fe zHg?-O;nPA&v4}6I*^snBNo{+i2>+stfpv2VT;~BXspl}JYSLQ73G}t-Cu+UL8}y!d zVEFShHT>dKbkzCDJWh~$@7mP2+nW4w96Eh`bcZatvwT*{W5ZCEpv`N zcse3rQ{P04EN*U|(GGNocRZZCt?~io_6;GIT5D%NSOb8c(N_qT(27MF!QiqgT`AK^ zUthn^_g1t-#GNb=BMtYy>`ogk3m5WcQ*Y^q$<5CZ17ZbJ1CJFg%CDphE?e#pl5IZ( zs}_}lWLI34S5|gZMLFG#j{gey!1Z(2T~cwMWvl3 z2s!aP_IkHY@~@YQR3#v_vNpmd#uY$4caJL;MvNDNOs(BqRt)A%L%)Wqp8ts;Z1Mj6 zW};Z1&+r=s{dK~HIbquStrm)>{tohoNeUXY>A^E{AbcQcLlKdD=B!ZbdeBTe9`rgv zT6w8B6fs|TX6J3cuFca-d{W%J8)M*%16XqIEqtZe@xw4?TfWDuYm8 zPGh+2TbMfJeeS-*SMTBs<;AiP%;#J8bslX}RyKfwuNoc9 zTT+Bd*V6+NyQ)&air-f1>o>v<07&9FGi4+gfl1l?zwYV$OTm4Q@R{t9->`&Ix)Qi& zG8D`DTa{8A0EGdwpFp+6F;<<@>A6-~rdm^5X8+^rhu(TKzJcsb!Je?clwd*pMI*}U z*E{w0>qQ1Nj`4McMPz0>{CxF}U*7-lW5D<%@H__`^}fsmk2hwRq+YJcny-E`75gaD zox!!kFI(#!Y_+v1)FIfqU(4^^G(Jax1fjRt#|E=HrM}mASZycf(M9#_xoiNBu`nR4 zns`{}(JvYpB&?5wYEV8_1PP3LC&pqcYiym^9=WZjz; z);9}^-reeK{%ZmIIo9Y0fhxyMA^bEsTf8KKWNG7IbVu1 z&=8;q;AacV97y(s$T&G?>4QyH#xqT2)(S&5QK&5^Wd69e;Z47_-s_LMt*RPRSC?F= zRVA8IfRt70ToJWrz2h&W;+NPwC(hVMInXQmZ*;|L?KWFaK>ibsKuldk@thVlAo7XH z%#r(4ZVvPZmpTuiXV?DU1dX+{NDZ)B{gM?S)nn zyKx=*%afM!W`~$HI#<(U zLNF>b-M@J#>tG$HdMu~t%?GwP03N_bD}b^g-UEfYS7G7fSd>5 zQzt0-?u5)1UsR~>A1@>UbRS01OMvyL|KrPlwNOt|-CWWQmvQ7%ntoAGodxal%i|!# zJK^*Q4b;YS02wo&Ml%ufy%Zgy)VHzr!FBb~%w7xwSKja>S|bjD^r6KPXn zYb_{-=S@Kh@7)6@uB7Yvyn33V#>K0Yxh|8)i)x;Q16`XJ z_%J|!cpus5=pYlin(f+>^a@$KdildA5!;~PT`IrE|5onQsZ;uAVsg*Qw=oD-9j|}J zLK~91u7Z9+D$!puS^E_r8A<$3X710KkEPWoLEb zYzhF8ED&ZO`ixbmfaj-RZwoEIvVbDryh(Cw%VN_ZK(ye=Fm`U(2c#s9{<5+EUj#=l zZvkf;#WuZvp8*>N=rSofkfvB8g==pC{ziig;4A_I1!B0`THu}sLJ@$t6CsZC8NIUg zE#S4Up)v;XYDRN{-fjR zOXo87^&-2Ui@Rl5d{_02kDe3v+`v_?M^IP}nA$UM@@VG}DgLF;Kjf?h08q+v#ugaW z83Le$zhTDNSI7C9ll6CxEODZJTYl}gMwy#pY5s)n81-Xt=wDB!N2UbZ=PW-c6i{6F zdzinXC{e(T$g5t+|K4~C@hq}4WzN8g8J*`&3t)~p3pP{e!}35tA4kp|4Ai|&-wo+z zA9sU~*+(v+x;*q4Wf}iaxK@u(KX`fBB2?GWpvLkdOU)G$E0^)bo>R!~DH;8*o>3EXIhf_2QL7+K;gC|c1PFdMci$tt2Q8Gm z8J@fqc?gp}J(%JzqfI;;{6op&ps#T|eWvIP?6E=2Op zF7=GR`ZhWW0u+b`(LWRkeg0o;^u9d%AR+GKDB4AQ{YTV=%X-)I%C1hQyzcCX+MMQl z&AX~~BL>3RBvkOy=is`@630=FB|k+$Jmte_&N+|Hf;bZCFN?IU`E)j?tG}~sx*hY& zy50*0zWNr>`YjEV#cxPO$2~ip=+&X5Ml8Y-5GOPZq?#4{&|Nv>`Z>GZz$+h_fi*>9 zK-YI0An|fLqbylF=M=5A$(zX3z2^Xtx$>BGf+Dtm4ei?_i5QY8D1Lt|COR6eYX|cX zSS#|r29a~~ObMm!(H%(^sqm2^gLvXwD!K;hGT!oMUe8(b=7!&F$_Rge@r~5)ITMgh zCpwCoiwxnTGYfDP(u7-#?|W_%2D?%~o|2uS*p?DUXAhi4^X9rZ0M}QGOLLmz`0jDq zw2RJC->@CJ($J84%e=sPH5pX%!s*`K@!wy{Ew}xog#ei$p9^QiWK<$k>pD~&yUmnl zAwY5$$U-!n{^iXATC|u-WFFyKwSMeUBbmavY(F-PBQ?u`G7aS1K)oY=qaIt%pN@8UQua`NU~HTZe+@;F0l`F6Fm zT6vAf+^NT}8|uP&BxM_RD>+ApI8_k4ieHT}U6((H3Ucm_=SYAKsK~Hos+CeU>Plz_ zl+WsG3iYiE0_0Kf0#|cuAj6)?t;IA3-T(Mo|H$7P6B>B*J@NKfcO{!%#XO7Ys(n0& zF2ffLUf3^d%3h|~f+Nwk9g0c{O$Mk1>4;E3cnIgss^D#>yfDjs9{|M~#ctc%Bb(%f?>0;0RUf8_ z&z;vCNRZl97%T<+B^6P4f}iC%&Ip5d`lbQOOx#V922j$LGMkA4%C_hKn$S1YUDW{N z3HY*16umzhY~7xRym1=ef7||2j`Sp#Itn=|x9pV-sJdJCu}FH@g6S8f66DZ`g3X=u z)$t)L;HjSe4?uL$#Ujf`yLF&J%OGM_Zc~{4D;Jc04=B ztx3-rzxn+Nv76meHv(XiI>@jMfgZI-{R+~+7StO6b07<3jJoSfmnUf7HKlE@-H;$( zN-0OBNJQPq*ErcXNft7Q&9qnuRr=Y|+u*(a16#8vimU+$Yl;xH#n~ z)U6OU6rd(D6sxLxX3l;}gVoo~Lp@%*8m4%>y|_KDNi+TzCg9Bnnz<}irL4bPZ-emtp(mM7x++85BHhnCIJ9}`4M!cH zt}+K^baVoFt()YUZ$|!`$`1ss=9vzTeBr^KNWsLK57d|$)N($9VPZ#sObX*9l#NBL z%NaQR!V0{ZKtE&+TA}P+QTlfv7v~H(_X=d406m}Wb>__~lK0b3*dD8`Yl&5I%6-+w zt)YnAgnH;y;gj0e?7x0ah_S}5YA@Al!|s4iTYU397U1r~r)XslLR8qoNs>y?Ita&c zy?4Iw`Ne8Y8-+TvipIHqEQFfLE^w}l;t}Tqeg!H=?T$@XJxYU#X-=)KbxOj-f&oia z5F6B84X!OMavZuUQ&@drBdYHuBhku4M1 zZ8YNvtPnmKSRK~}1BK=3KL?!DD?%}KkF4^l{DJ|%#{Ng&1%z1{y_-{)Yq%Mt8Yciv zYz4-%Aq~cnu-$;9)TeA}VbOdruWz=hXNB+*AM6w=5`=rT&B_T*0Xg^oK^GJdwc}>8 zj)^?^m4&}|`*|^2w)zXIq|?p1i(;4L{5P*FF)}D#644uAqckLwZMEvVfhw$ZqB{0e zNw1FYr6@4Moqn0AM(LZ~<{BY91t9J70FBBYKm0&uPH$CbyNK!d?~nfO)an% zfK0}d63|6s&Ol`P_pdP9m+0!8J8zQK?jP0ttmckd^v!ce;I(aB$U3A zSh{-=kl`Z|j62J(TF=P9*{o6vcIwWdFTY@|z~43~Q~Hh)I@s(!thU`i$`DC31AVkt z2xh-51zwb{)2>p!I@xP_{=P@cK931*GMwwFMmarbwO+Vr@DCWJ3UubdTrQ!@TE?PF zuARZKkG55%k9qbc2=HHmk^ph4(eWXKEBVt&HKMVT()I*r&+u5p> z#UcvY<;xWm5^SjgSoH$ylXKqg^MJMLaE`zyRvCpkdSxwnD5GF$RVX|>BL7vMsR52O zg*ANsGaTD8>;oA7&$Cr$T?cpS0fJd7t@O3NJLF<*ZQ{-Vi>PTQ*qwzo_xL|rUjdOg ztl_!-WbbXBk-#35CDY>n3JX3ZKUAHH}q>%x1sVyWDMd zQ>C%{iT$SU5vUv^qWRIjGs!^nr`rK%H}Q&LBC99nGM)q7zq2%PD!yrMx++N?bFZx- zy_;O8S15e!V3*5fF(4MU&}SGJ3LT;YMJ`)^L82J|#v%gn0Ic{Ha)s?=)DpbVG&d!r zH>?8^>hlJkxSKAD)W3zNJ#vVD$F&!2-rK`L zz(`-Houcw|?d<`T---3EfGqYmPZE$7R5r&VzvgM^H5A->=^#OyIp%UDcIsQ{h~g6+ zppGDf7#r%Y>!63P&5oB!V2wNw8Q(9qoXPBXwx9McY@IMbWHB>wPj@YT`vncP|K~3L z%WiQomX@Qc*6n{9ED^6TU)E$O)A3NG&eW~l@v9e-cYPeA59M(4I^!}4d1ZW8Sy|an ztDUhMMB>NI+|(0*NTKe>UljM7!dtu&{~Ml9lxxg%O3~|Yaj-7}De3Gby=P(Kd#i-NWsh;|s4^j*oEtLN_%bl&Jac6*#8)!BBAi%8zD2!c2@_>e6>HCM=EyMoD zeg%Gj2WT?#9^g`LC=}TFXI#Dx%|2*LPw#Kr5QTk?H|wh#YB_NpKwj%YAHv>B{R>uZ zny&v@ISOKWP=@q0azsK8T^71JE`}JCaXGYk8wLWj-~&@bU<~;6qyXNT8wsuOBD_Dg z>@jto{O9I1cM(8RF1h(n76=Vl^N(RCuY}Zm8@-x8=Pb_YP;@%gRkLjSy2s~`uOR8@%aiDq=AAjq-(U^Fc4IrlmxF!|JXl| z^WFGFvarXE^_}PnLp7A(PO&X^HOn!j>KrJQ3Mj?@@oa?_{spGX@wV}Yl-1QV8~*Y{ z52Z|p6g~yjLpu{)^?Q@fTB28Os%;qgI!p3e`Pg0BO>7RSy9g(BJ{#dnP6!;sY_T0Ctg8;jM;EUKdFWUA@Nh z$T*PJc0lR4BZc^iQ&sD6Q`iIrg*)274Pe40ZSzN}b3A5pc$A#E2{SFV6rd_Q?o$Qr z>nm4jZ;^k{9nH%YFSW=(?Bmk-ZSXesCWoTz3&;_YXmZ!AQ`D`dx**-KWQVVFAh}@v z7!e%I5-bx~JLIkNgYKA*FPh3lvGIG?n>FK75`bBF?}YxQRN(C|uhG}nEnet4!~Uo$ zKf8d*sDN8esQz5m!RX@M6_z#rDl1@-*=luNdTZ(kz z-9b-jd+Uy+DldF>`H}TbkMbK`;peB!}gE;1kgwe8PqpWqu4oH;?-VmQg*fDJg9^$Fya3g2MN6tg+RGyP4eY35h=hX@!pM zpOUQ@ZUoFDGyYB!%uGk$9#evJ;$V43v;N~h*f{CMH1<#LfA}2$VfKGilFp?EWp*Ya zyQ~LwgKU=LL#J$SggsUX*YFG!U;j#rTRy?2Osz87W*>{)J|$b<5}y%tndkCk$=r!N zd}i4uwhfu^Z8S%)n&XJVeGl|l3M`<<#yq!6G^NBjdfk*V+QFhga_(Qm(XDf`Sp)+) zGbfCTRBH6nY9d258S!($zFz|Zcf_~$G+L$l8rR)gyE5Q;RL0Zz=r)CgH%$NAS8UF~ z8{2E@t=xVf&&HSJtNWJ3jTdv6HU+jY7XB6GuIVx}fgznJJainatSFLvilF@${gfNS z=X~zD#kVoaVW?wQP4e2W^T}Mj;BsGRBHYPVKa-%J&*c7k(#U(%6y*cuepT% z^}YcQExE-*cfinDcj4sA!lgevSyUu0Gto>j&kVF3x81dOd{#x7Du}ZwejP`OQ-9a@ zsjkMR>vTZR_w<*E6A71_(b>Lqc zhk-|X~P|DOsoq62O1BUZ_q z-IBQ!i?qgE)44BexMR1efM+6VaOZ#CGG?V7y_DHzBhZb@`?e?RC_f)u4NViyBO7Hu z&=F=}PLE`5uF}!pV@#TfRpCW2@K9)tRkmv+GX>3Efp!mBIqTX5EipIMGxgXw{_DW>MqXggwHlx&2M<%Pov4sLOg1Gux(BiC{Q+h@bs;?2XCp7ZzBY>tc=z!c z&0yWQT_3pWCh2BqJ_0bl{)I#f{g-_enme{s?EXc&!r$&JReWUwZXWpWFt;U<`uf>&dMLi$+rfA=dEyGmgrX}8Dv~><Q&a}5I+2j@EgJrj8H{pWvr>8*-=-{0YB9vKzL$%mXR*yoGvUtKz6-^(P#v4h zD0}Df#93u~!-M{zg%~4eiVOWOm$ta8iwp#0+MpUVc1|Q-A&FiT^xV)05GPa`oJ8pa zYol$nQ3@k2-KlNqW^ZPvZp$o-gjcL-{fRoaU*qaEhnmE-spCI4;+s>wWz#f!=dLq? zt(3y+;Db+)*Jc}4wC(-DsU&Tftq0>{XcQ`2)7+K||4~gwbg2b%$dvlhs$~0X4b& zAsBIAfRGj=O1~7ATu3GLUewW=AcQ~Gm(00Wp()RK7(G5z`8rf4!vxku=*~8SyVo1N zLPx1q6DQs$!JbvUQ?2%w?0@B@R^>60@u*2A%?Ya~04(k#T=>m{grBjhF1VBj`qU-9 zyRf}jAH7`S4-K8PD$M9~Yfmxqcg|Fsu-vJ4O*ilHV`OKEaD5lvK^(KnIn_G&m)^DU zg{sCNxx52r}Ii&G;CAI1@T)5)#~UFwway0JOS)kCi3;D&W>9{LHFa>!VI~z~ zGhceJjQwN{+Fe|z;2K{F@haGlCDFqW8QnU_n%Cd>dGL`GXIHbld!`odER{Kr^?8K_ zPAgHD55X_f!loP}@)fm;FA`x50R{8uTUOPyF|%cBk*korTUWIhCfC#a{<31U%BPoJwDY9yH_8#&Yc=N6 zQ1tB<&Y5vHI9*LOiXhpauIqtt9&md?Fqn}}V1%MRLYeuT5Qgj?A7)y=VTLy`_D}xm z3`U#r{O)Y${12|LJta0zs_>^j{$k&W>f+{(@TpXTt|A8wHJR6>P-!Balwi%B?&SoO z@8Plg8{$4e?;=Zt!(n7woY~mRyJOvEh6#m+GgWP^#B1~SC4hH{To4h?jlD3}d0dOj zre38;H9uIi>0XhMW;Bb6S#g7f;U5Ru@k2*MB%76uXPnMeW@jI8!c~op7JkCD%V%Tt zR<(A%Ye>IcF^1QAof|H4dSX|eY(;WW0U}Sq?Z#CBWm(0%U)wypJCcz#9@e!?szvjo zD>(1V#FkbbHb{+J2jb&G-ZEY4m|aiBO$CFpnx;P#viA+eU3*D-p8vjBSUY5@xVL}& z8*Z-3emNGk-fJLztt_ouSBW*WFp`|dQ63SG%>Bt zvnyx%s3&oB*G({}#-S8Y11VQAl3;GpiXkI1&}v01@zQbncFL53+fMT79TC0p*-m?; z^fA}XcWcrC5GLR^$6Ec`jc{_C)sC}kHD_00+@33943k9d^fN1N*Rrs~ID_qHCW(Ip z6qpVwL@|Ge2EPTWQQ?FKauQ`;hORYLU5+*d&An8pc(EpN+)!{be(tEb{fTkWm@0Z% zn;XotmJrw8=RfA^IdGb$*=`nFvwaZms3k}zi$&RQ@_25)x#_PS6Gkgg901<&?KEjkSKT4-R*I`aZUFXc= z(WPCnaNC?@TJF`tuG#|9oz<=^?bp#M;ZkYZI1#y4phxU8S8CgM0bp+<& z)ysyg%ycuGUN`*ZhjVI*fpz}4evi@JM<|8;%1T~!*N>-0+PoWn!1Eq_(!}-9IJkx{ z&MpKJ>k*m*od%{y5=`sN6NC{l(pWAn&|Yl1Y8pB{a7)_Zn6oSEI9p5BDM{9}6>plS zas;V3l_Va`J|lO?M32ByVIMA^N&Ms=z&KJXhk%_lr(_f+fSmeyb=Ga0utlKSdu5A? z(3j+)4T9}+_STtI9x)TDjUALZD)>QO zis3NT(sLA#*y&xj;H~I+4rJ3_rCTi@Vk{nri6SL9u7B<$m6>j;HJ%!sdN^COSl(R$wjXnp{;56(*dc zBe<%A5zI=~g*h;B`?@;`<-IuQQP3WmmaFAF^Igcl!m#>LH+ejRUi|5UU%*6lYfS3L z*+W`hkIN?H09I#CU7=RP*HVknSY28_$t>@T3HC~itiLaDap^`uunUu0n@APF14@){ zsIfR)T5zVZ6Dd)lJI>WS;gEkK+OEB0U5am*ED{mng4?QMtfH@kffG92(#kN^OZBH% zlQv9!x$y+skYhNF{-5I*u8(<_1Y>udg4m1nu2jr69k>CXwO_ax0JgWXSKZD|4)1&@ z9WB2W{|cU>N+>u{??~Bw>h+=K0DS2D?z(+JLMP6;cFR*8>mG#mCR*2*Uh>G%EWp1p_aQyx3|09+GROhL*GdfpWnkOynq zG4I1H`xebg`5RO2FZ=hNjyfZM_irEL`>0wDso7vUniq zQ{`*|$5*P|;O2V=sizS>U2T`VI<5p~KJR9=#E+`5YRX$v^F{d4sjE6lR9*z&u}Uiy z+{^lko=$e_s=T##=InIHCOE%E-ekeOH@-4FD&u)aOsCt4x|S(bw=lF#otfHTLDo*0 zbtNMeBN->qT-_yS#~KSEqYCTU^5c@D_uO_7ft+3LE+}U( zb+V`VBgh_9Z5^a!A7pEGS2ssbNA}cOLwVEsl6!hIMduVRKcqi^vs^3&9Y%-C@b3h|j*wMmB) z%gw&5E=CcvOw%9gdux_DrBVeCe+MY|vs?a=<}?EIJ%|~_RZzfGV0MO^P{B-!bzf~| z1^22nX)+k!#2mIVUzxs$d0C!*E0jn|crKi@wB6{xDe5b1n2gcm-KO&fr#fS1=FkwcKiM9 zOM@v_`c#Wjq^EtZseKALl_}U=w&ML%dXL!*kl$f{AvcA+-1}@K3Vm(NY$l7*-Odm^o8L);nI%g^hM1tUkH5E zoXb%Cv}(129w%M+;YtCw+E@L1Z%h;q`<~boPxoI?0Jp>pLhm}-H`L@o+yAh+@tG>z zc9Nhcffre?h9HYP@@1-Qz3D*(POF$|!6o!I&d z!ihiqX<9po7jdgiN2ozN=nfF}H4(DjP^L8f2#1J$xpnJ~SxyFba(92|&a7bQp(cuw zt51Nd=gM5yZnVxU$Fylx$;$r4%OAwJJk?LFgDBdbrezMHtY6rb`8sXe8i|F9th(U! zJu<+{{+Z6tzYR!@8NJn~ED|^lHaeR9NAJR9hw??#LXBM#?R4sC_C!272Yh8!VQXrxlF+Hh>e#mtsbFSvajm<+VDOO zJ^`6K!j+yUe!?i5Cwb5_64$Rn1p|7gu zS}XxXR%4xEv>O|0K57g22RTQ{XfsMi41Z6v&9K0Y{iM1$CD^0daPoqslT18IL z@F0e|34Z9BwzHm779})u-GnRZqnvV7H0%@sTffYNHv$AN_ZA;4^r=dL!(lcKi zx@7vCzzpPrJU;A{w_aGizgfN{<}Y!ef`8)4MAhm;+-rC*orBbAA+78WXGIXnrfP+c zJX>}zYbop*)OUr1q@nIG*o4*OE<)7-sgt13au~1l!mBbSSiv`kx#m2awN#Gg#T;Gp z9Hr)*GFdL8~V=;VB56RCQIR8o@=w<(n^u-Ap@1Rw*SkbDrRdzIC=9BSuHK?_J0sXoMH`?kRW&L{x?Kqdf$pt#YM_E*blxa3{&oZFM|uw%5facd9dS3NB;GzrU)w7+NE5YZ>&{>2^qBH z6&1#5rFKo9lvn6OYl_8Y)SC72Nw)gn$M8tC-6ZcmDCv&9$8*lt zm#H~vu{n0GUx^A}T=I}z11d2NbOn0G3A$eq)OKoI1>m*PwA;vS%yqX4%Fs_v4t2)-{QKpyz*7;nI9ex3s>yg2TF^42ZTjUMvhsH z|Iy}xBOvM~5wO>M+>))*H;8;XB}1tp%!(^A@umnmA44n4Zgbh3r{6zKFPvy}X(9fW zHdx_^m2P~+!_Aar|ACYtvmbEkO!h;}&MzBV=*sq1b`nuEi~YELbi$&ygSHzi%=A9( zsW>f`kk${IEuyr2CKWBZ=+(|0lXuOv$qD1^8Bi9CyXlei4nZT9KCI_JRgBm6(u(J; z?#LGS?`MT};+6Z*8OX<`A_TeV55kNutxKV6k&4v3>ClIg9Yh~6~V}k=K9lUBBLNUvm z70ZFAJAUxdyu7%1A#C~Fv8lTSe*b^QCdIldYe&JJ`ZD3)7u!`qSl`qaKrv+zf^2G0&ubA0l)>iG&06%C&Gn4yrRS{mrE>fW zLK<$nHMWx)aTPee-J149Se6%QrCs5 zbtg4ik@YU@K6KeVRs71(Wu>(0bEz#a%)GFs7iHSTg(h-wWQupX_#5|1y_M;=E+5v= zL1kS6mAYI$Qawzpr~K~yLq%WVj~zORSChb`x~!@Z3V4~@eMSDB*}GV04YPqBCsNH< zC#9BQ!_uX+!m;!I74EgStN=Mr_g87Q2u^HE+`$3`0W_tbdHo>yB1Tm-J z^D3e0W_p>xA`$L%yl4K-D6L(2?TqYtw(5pSh^PUy$f# z1Pfd7cfYDv9a>y7O_B&swhqNM=+aWwcaT!mr{zU5@9b2*JMU%zbz%yDREB)f;vZ(1 z3>J}G3I>CE+0%l*Ifxm3NQE7|Q!DDZ&HDTCzN#x2X%FgPyt zbH;sVYOdvz9NwyxQ*GC!h*0y3mop1}tOxzYbo_5u1^Gug4^$Q_S;sJ#O`k)o<6l;- z)u5Z}ok4WxdN6CQzrcjO7+7VX<;Z-$e5a`afzGV2N2M_QJR~oQl^U2;q0CbHRVd@e z$W_{Uggk-yJlf7)q9GK{ejkbQOBhY-ibssTj>zzhpUL~K@Dj@Hbjy8f=uv~bTY#Cn zZJX}b;daG0^^H?qo-7BII#|+eA@Djyh}=Kd5%%GecKb|2Z7$z2iSRjG6AuwmOWsZE ztMx$gTkJ(WGM)2I`c7r+t|aRg%%o~SmMt3mlrxTJs8F@P9^`6Y3DVOl$0{_(Po2?W z@OSX*4eR6)teH_0hxE3}npx!T;5D&39}Xlgr^QXJl`-O#=+5#uPW*!|rVPQE-_luj zo%z*mXkb1gc|~yl53O#u#DT9%1>OhsE1@4g1W)-Iy=wJB>l=?eYRy9MFTu#U$H-e8;n=cJ(y7nAnaa6;f{a$?Jw$>$O{+0FWfFw$`W(Rqwjv!5Mr=D*a z+#wN)#bT)BGPKCL)%KJGMlaWSz9W3)l*2L%G_bnXm^gmgGbQMV&5SI2@siPG`eV!z zs*?!{HMRij@ikQY7WoM&F;|MgY;fEDMw>R;O)E5?_&*?syi`%DNLl zqEe=PPBc5Fn+R=%E_Gn_0flsx{Dd%`qIM0eiOqKvjR0P!=(VyvWCMdV0 zZJO~|aJQZI{x1T+@dgLgxga`Wt_Cfh1exH0datfGZq@M5$fydG@!DYdmqb~(sgB3x z3L?63?`v86H4qV@2D}7!$MonI3GPs?II0@nnFl0e^w?R(ebS9wp>785q{krFt(563 zHCEE>X#JtqnSOS)7LkaQD9l4*&36+TX%YcZ)S*-i1C8~3zqs66#;q8e9-VmxXP7pz z@31@|muv^-lPGh&bBR2Cm#M5z#~5e%j~HgVr%Skv+?3cUpVaB=pk^5~P4$_tR0EOG zZL!p)!&uPa?v1?mA($XgUPWJV87kJ}cPgOdU3N~d8mfHJX)SU=)j-~qNA_mpE1*t2 ze1bE(fo7|>KdZOypk=c^!-w(>Ard_kJEc*P$TVU1YfnsTh+Z3eUD4{(VKld{eN8Eb z3#tYqYA8kg<4a!bwZ8Nz?vw}R#5g$Nw82u(IY6u(Mrv_hE;8DG~}sA^44b8vQ(-_WkMghYH(F*X&Ba zr!^n)!Wcysl|YvVesrxG{HYf-bla*QTQ?hrhA{)%Qwk+H)(eQS7d3;v7z~LgUr~kAd@z-ops}`^1%IFE3nPJAV`vj5)Ke^hmkt z3dib<#hN?)I6uRRytU2X^HOOWbEi$;@YhiP`vP%Ck&Xx`41BitZbn6G45E2VviXHL zDta}2^!gkln2H@eFH%R2ey?vD6x3#4Ue@-^f!7v?&hd}3?-;b`Je#3Zkm-plX=zM@ zwD&j9O(AhM?FC{vX#J_P4S%zt9$wXBL-oqiyFEgmT&LwLTIqE!SU?ANz|-DW0u`6A zUg^0MqSf_s-v-_eeu1902S!UMotCt|%4x3W1B~$ypw1Do&w2zm9aM+^Y>6yHN-a_o z@1!5{XI7+-N{S|r-)Sb+D#5k(@IJ@yKd2XyFv{~|a=L^lZoWBM?yo6s&pCz^rCu?g zD>>!8E-x7e*51KGnvbe|yTI6KaNE4XrGipz{H}YsOAugpgr97bc0Q4_*OB27zh86j)JLCLb#lAgpm4XE!=rNd?L5^Yft-1Q@2#Oq656KD=H4|MLsG#N zMDprr7yd~5}Ty;B}((aM<<(4ky1}fj~zfJ3QOleD9mU z`&FqZ+c&&Og*xXV$EpG1(HTK;;RQxbt_F9BQN<4lPO4gBx#jw&tS)=iKeW{eZuE|p zxM_~K=gEBqKvy&Ar(Y$C3JjL+Wjuqmrm$!C^2|A zgr23dNM@d^X#ZQx?lMAPbIXM5kepwvVj+LRQVR>T}|)1 z$~3WQvd1h^td!Baw3QJuy&DAk#6_X3v@t(eLQ;jwlaKvoyabCVT&BSR058qb~9(A0Z zI_qPMOl_D>8`do+%p>&e3GYSvbh?>lF#2D}hmNKan*P~-XD_If&ysvtUhQN3U-ZwH za#=2V?aB>0irWqhw)F;IMDzWcnl+)zpb-1L9o)vJFywXq@D8~Q=9}`F+FDJA*m8RV zDLEZx_xvMo5o#TEn{5gruIx_ktXU#u-Q2WKw1`8_J-2^gdZp?#;azlp|Jsai!$ICh z=$ZVvQ!S$|+pDGzE&;jp5H(ZNke#hj%&yLfsCZ~l-zCfV;~dw1I1Rn4$T-$=x`9_KB zU~B7&;m}bxtEUJJNa2`{t=t@g=P|$4#)aJK1N$HN%%B1MAQ{-Nfl z&2BxH3r(4j+k)L)-5=|^)yx1K82@xq(#1l{@HEaq-rx`VHkJ#2A%h(9-J?^+*Pdyi z&cQ;3ni7mu3-l=gn@@@WD>-_T)qtY>C!(%7!4t8G9mA<&4Je~+Rg?t$o=u(LPC2+f zX7CQG$T?uHrm0hQ2Ip z&^^J==iJC|>3P;o%DubsJhDhne`tWLg$#k-RFVVUnse6tJMRkqG}`uSXm-^U2vXOD zkab1yrLmi}_T#@dB8zQF=@Yxe&knQ_+SjP)N8*Yd$vTfAT)egjb2m`lP4&jSgE5?G z40!w1dWEK}YsH3`GuDWv>PN`iSWfKLs1g}EuuRy$N~dfxfaR9lS}@m1ewfkwy8#G? zABHX**Rz?U&!^c7%XNbl8yJALCi`^iaZ1;e72pR+c}^4dZMzuO%;eLq?ks(M!#UgW|+9-PO>A z`Hu@Zh~XIJX=blyv3H$cD{dAwOI-wbPyMpEn^h#g$*#9PBnn!M(14S zMw$-+=OuoC0@VuZD-q+`BI+UqypTuuMNRS)0P1yMoj zU8rg`7r>l(=(gCWkBtAI4tY`0v(qt72Dq_JJP0*pmnLmmeoYsaAyQhLwwu@OHPSz` zHEk=gvrm|vZhRM+^TUUUCfRgc#HyLiQf`0*+Fi`+Iq!f@$u&AR{GMMf;JfttCqd_OotAG$L- zeLJmWm-%co9v`YT(rQ`F-esrb!jslAd~og>nJJoLD}ML9e`cO-BM(Pj&+ymJV}9)$ zM~72{ZU21z)2y^A$al+$tgf!}R?l@9L+`nD-=U$#U4irJQvmy&N^7e%$gLt90cHmU zV(0YtuA8NRd}eMiu8d_~)*9JH_YVh3|CJ?7HiYG2F^|Pm^ zLIf9@eS?Y@%&Ir>@RX*jMrAIp{$mP0l>ll*3#_NhbRqhzzwcHu)DAn4H{sp-tg8(2 zK(xOycS2g~jT4OdE8voL^z_wEc;?Y74g}!VY;{8k0wiM+U0nOax zRtB@czCUESP@0UWD_)VgDjT%pb=H;e0eAN9Y>ljxUyS?*$);SpQ^E<~`D8o7)9LW5 z3pQJ6-;yAu*1JBX@@&hQLgPt=O=c)uT+x?4QAB*>XE&$qY)9aoNbx|G{zmstCjx1@ z7iDn9{U(FE*Ul23c48a3UeFa$;cndDm*s_i>+(%?OPQJd?p_437lWOKfRYQezLU}8 zs!K+eoKYZ*sfej5*~F4866!cY*tcwu`Rg&cl=-8EX{d7vK6g-C=q7ByqKujIdg*FG zoL=zw9FtZ)WMmx2-0<1Y&s;n-Z8U#L1}$6{Al_p08#i1Wp*ljcCn6i0JnKGe=U(jc ztUHs2oNG5psDdlp&!S`}YwlgD#oZ-fpCbSs@Uz}gj|t;VXi@{Vngl@kN= zg%I>&n+@h=7c^V6#y~E`SGr8Sb~Dg!D?Fka{5_`keOk#xv6Z2T$OL6{VVAh4a~lVY zrz3$N!-o%5%F(ddvT^&vW^kl^v+oOAaPF!#KO#rp&FO96LW7%4|1p2nK3%Do9ls%$ zQ}QU!A}rrp-;}bTUP%(HqAQdTl&*fOJGkJ!fGI9BMJE?5yf;%LZYx&@S99s>arEo_ zhyuIxpUN|>dc`)3eEAX~FvN-+&!5!Z60{?mR=tOoqV%XNpYQVHRYM_5TMPc8DmRRH z3IwZ^yzd^m++YX4py(7vXidaF-d0w%D3ufADP}b}3cGI!4P99Hv5?z<#Lc(uwzcj_ z&MV4GJa+}x?gGxV^Sn2u_{jzAI$6%A6-0m{Jln&n+me-2*?zzWRN}MAC(X>*ZR+AI z-ek`&hvQ=kQF4X`6IP%xruuxWPzOHweu>H@UA;Q%K{jR87T$rW;^&3MNw375xXvx> zk&WP-H|TYIa?%NRkc=y@6}vb%aRk>Jt9m6Xl6yVrws#+OwS@XmP! z!ODnazFpvj4|@;%@kC39poNi4N1~6)2%E~%`EeQg`&tL54Nj*8l`eG4AwDm))?(<@ce_T*vJ>9%Y!*l>i1cIQuf0HerA{7^C#&bNy4MOC(Fo+ z`*$-`227}=9LiPBy*csbHS2Bc|g}qea@9qvKo~o9nm(2)@si3SS2BAGdp=Ka7 z!VnrQ6TG$#s@W2H8dXar!_I@luIGoWS+-IPmj`c}X)L>--b7z(22*yney>^_#nvLa z99XDQAk({DDE&OPp;pUg6rx618m&nE}>i&O?ffQq~^4NXkhh)A!qJ%*-sK7d} z)VC!yxCsQOMx9iJZcqxUp5LlT9(&?e;XeF)%5Kc5?UQ`Qs7;1sRbvN;QmMbEbloea zYD^&Lb8SFUxvC3SVOZRtcsFipsJa6E&Nq4X*%ob1#bFwee3VarPiLOaHOEB zGqEeCBiBh0L=}vm-x~40G3S!>z0tjUGc7?)p^L>x%Au)B!bs6!^(o)kMZ8fKsL^Qb z8X}eWxTwTMGg4Q5!NWS~cdHd&P3n~`+gp4PT7nB|uIbuX-Nf`d?HasoKgA9T#@BA| zU1LWEnFrb)JYqF0q=17Pk$}53oE?ui@bPIZEr!RX6e4J^*zuW_ekP~;)AeR@?`{d? z6&Gm^U1Me$&p{Y>=5ozH96KeyULGM{jr(I@>w_T@PtqA>iD#yZ`L=3+&9xE zrw+#r?>G*3xnMS)PS%qFwHbznf)*@=(=mA!NZh;q-L}C!$=Ux^aa=5AJ1wWQU>8!6 zp(ANR!tWpjkS^vH0#@$}8Kw2E;aXg|-q>?M2stKSbLddUWESV18eMfl7^PX{0 zx|4B+D@#}va&!OXA5P@oyu;8}gVT@-0!u|4RU+31b4#T@avlT<<4Nzc6m$pPXS^vw zd3OI%(4RsM)+t#lJI}qlgaPQ@F3DqLHwv$n?YkT|W_gh-uqOt}gt@{} zDWWCwq571|C}&Q$2)3a6nY?&je~GUg`*`hbnNF4FQr|z*yh7EiZfC7ws+O|VC46f} zy@_$nX5XI6`#j4gqC`qt$6U>RSH4;)R9@NEWCD8JgW>BmxEeHKpY~@T-qSqvx`$?Y z`zNEhWhL4dKLetonC z+p6@nWE~>KCq4~UbWdo9y5i(LtnWEOtc3b{>N>}bN%5)80PWP$iIDCSTd+t`d6D%p zxry&uBaM~Ke0;bR|kEstj^R*Wh2filv=mh0W_C# zf+}$j^)Ux}TiS`lBLlNsaKZ=qdhZl-zN>Y-bk-@AGxss}90dFtkNd=8NiV34Zd1!P z2;$BXLdkq7I;D!qu&Cy(z<;S#PqzM3r>iy}vdv8>uuKaH7ywdIm5jD z;bxf23MKib4w5%Mcg-Q;S4sobD{&>ort-tSNkh1yVQ)pKz6$=RL>KvWVc<(J4D& zS7ykf{A8z+;+Lvq3*aT1nUBMcO?uz1Im0wQFt>o12&L!!7Rq72nd@jc0F}@7wBV1R zM!(mV+nSCzPJ1uy-Kc&Kj8n;u=!7IJ%n3W%6Rq!#l>r`e?(9H(w68&5MZTh3MofC4 zOO~pfnv(^oB?guJae;;S=(}V_o)Cn;zxi}mv@zNDS>^m%L{f_+)wDm|>C0v`J-g%K za-M+ms9OP)-fpkfj-Vtc+_7mOyY^z2-VSmgiU$UaO4E=dcYCi?$~7i(+whbiM8PQ; z%ES(&iF#_;Eh$R6IwpwJvS(mi^L~p7!>C!)tmEQYIbIeuQmL1vAZxgoj^JJp^Vp&D zjR=-Cs9Ct=f0SgZ78x26%`x3*%q@3vwoQls*0**|{UHIy0Et*CD*{$^p* z$5%>D>WYyshlEgA_D5AQ-hQ|pZQ9Z{KAu$W^m zoe?%IUL_7rj+lVtjd5cKN#TZB3XahpIa<6ZGF8mgWO_b&LS_s0SE=)OEJ?Xp<1o)O zbW_(LxWX`tFWp1xPaR@vYyV1zR~HPYlrB?rjyj7rDqiR-N{<;{@oF?dgFTj0(RsUk zac1BtLao{Gf~ymvq_VcUQ6(donRntY{^L6n2VHW3h`*3?&Bn<{iGymEvl}Xq&)@b= zFfd%~-0&Jo+f2avKY+wFJ_0|P7#?m+SGI)QYb^da^2E!rlN50<{GcIxIF#LRvwF$W zr`lLg2xI#h0I$^|?e{0g_uaPECY`$rd2{_*sPCWd0dJaHD#sc(a)jGCtR8N$)K;sK zy6nmGajsnoQPA1?eh<;J77um4JwZFqyKx%K4ceRY>bMU{JJgOHSXumNpchv*gDi;p z%ltY;o)o(AutaqE2@KYygs zUrrbyU*U!efFcVs%5$v->Y8CfXxyl&b{pJaQT26A3$+$NUTME#h3r)sn$N=O_Px)? zP#zLBJEG2M6Mw7}6u}P$E6_$=rANx6Bs3OyIh+aVdZDFUIIj*{OJ84J%e5}2HsRjt z!32J&xFT%f)#T8O&z1rMoMvC86{<4>OGCdaR@>OL!1UJlrF*S4odWp{s6s77E5#Kp zr;M_8X^&K;50rETrMZ>i%C0nCt72MQE}CvsbhUR-L82I9G)3^!kGH*93U!}y(0$BT z#nX5T#kQjl^#{l94)JcBE(==ylPqeAp#1KFV4_vrj9F{eG*UiiWTEM_>NTN~L0d_& z(x#!rtJXK{a>qS;GQ%y$y-N7&c7!z_K0n_gpGYKj=k0df=>1MYWd?nr3HulZSNUG? zC6aV(B*7QvJ^ihyPnj1Q6V`7U4ii3YRenN__6AO(b&{x*m(&Sbh89Dl?8KUTzjWF zt<@rx-Ny_%$olj}t|akI;3z~Yq{1(NKg)rkphyor(3O5_lbbzDC_-0})BAYR-z&+w zx5nVv4o#rUGDbZw8)gg6@(c-q4kJ{&WZ_JO@I5eGcQG?O8MmA{?t(vfCVJ+Qp!Ej* z8|;*a;=gw+tpB2+szO>k;bxn1cP|gId zR&|4!f&rYARw;?w00RXNrpS5qbLq3{Gf$;4TJG#lw)V0HTXtG{Gkgq4tHjej(MNM* zItEW22nb%|d&&E62ivQ5;LeAiNx7fo0{<`lc4Rqnva>rbO}^lk%N=ozcWoMDtGO)I zGt5Ho2w~b2AlY?ACqVN$190pCRGtOE-zCZ!%Hss{C`14oSuZPvWM&8O znAduyoKWa15fZn$KG*KRJX-0I2T+iDZ59e2D_8jWDpzBO8YcE8N$0$$1tuQD3euiK zs!6Z!M%K$O{oJH-_8`R1H%tFJ9QU8s{qO&GoAKnyYxnNnO}hO_51>*Quomq{Ny<4t zWd^hHh&E8uH$O1|ke2z~dKp0?6r#}F`Xw}dngzfIKO|e5%s<$V{~i?|Eua9b1qT39 zo_=`$5b71uo$mlnmVAdZO+{Gl+4as;VSv1jd8`kaChL+syW++?+Fe_* zNv9g!3K4$ZyGuD_koahuf2?)T{Z7@~x?qEAM#PhSA)&>AmjjZ^By!|TofDYWd^&I9cC#Sxq9pxqbPgY_$N%WMrca+feJw1!E_2E! z^P!Zm;zMQ@8Ab_!$Y;JYo?9VteNHCS)w1%wb6@LlJYDw%Pomhn<}ZiPtCRVQj!qQk zrET{^S-5@s_B_|&EPNyZp-ScRKFfPub?bxh^PV5^Mxo5Oayz3WX+Y8kY*x-7JQm~` zT^(_MCCjyMWV!%b1<)`2uOjuBQ@ZOM=H%J9eX6?gWcEd&-05$5Q9M6YzSuM#kEDo^ zj^uK1qYQE+l+6;efBbw;>HmgA{-4Y6zu&m*u(2UyAn~dMm1y5_kJ`{S|$wb1*j+h zykX=S`$klw2z2q$$qH1yu4s z$gCCHASzu;eG`xp#=5mQ#~09R64nA$t zgj4ka>>|mYTVK@DEGf=x-Z5>k`kQinc~Nn{S?2=SeRkVPl|IB9YJS!OR}A=TZCS0I}>qW1-_1uB=>10hwKF9-8Z`m0behs~7LD=nX``CKhW( zd%zGhd4MHn9`bcYf!OvWRL`mH0)n;LaZEod^&2{r)uO_MGayF)}EOx6kd=k~#{PBlo#*<(d^}@RlnBtuZ5VxrrI=|oaTJGOT z%&kfP-Y~UgSvRO;ENO4~y2}txo+?w!l8J6AH`w@|9#XuZ&F-bN+@N;XGKknRA-@>5 zL!_+bka=%g-W!4otF7*PslpsC$~6LR8JadW)xfto1dFbuv6TG5T?lE`R+Q-RlDoxF z&hk&BQ^um?wfR11+a;|rsmknt@2y$P{J>(heLo*eypjQUV=fdc=FPN;jZQ83Ami>= z5G<<6w3Q?%p>})Bdf$*0R%_h}fh*)Ke+0e#2HFT$<0|7ROP`=5P;$J_+$#ufQxcdzTgi;G(9Z32^vUmKEhWOjZBo31m*Nbq$0td zB%x612^FTe8jI@eww6ma1#xjjDlF_ zT^q2@d%3gzLHGp;;4B4PO^Dha z{cPXXz5v(>zr|Ncer2|*awXud_x4dT?x+1Wb8JkqOfvb&X6nXDI0M&_@h{vmkf?ld zx@J@{+^~SBc#$Ce&7}1H@j2F3m;4hF0{>aw_I6T)64Ig_IKK*{KuJ#{3D#h3s3_bh zwEI%RDY3%LD?2i(vul0jQU04vlJko>FUY*&?GmBeum6flt~CmNHi$3~fS^KDl7e?0 zKeMXex_6H_5vaLIOXho9HeTW}^n@_9XW3t3)TYa5<@cWzHb2J!CB4tNxYLQruB0?w z*ZlN^YQSzSXQJnv=vgV!#{Ut&Gkx)btnbuB@_vi@?(F6&-ub51ou;B3#{0K_?_D%5mlU~=eDSu@3ryTUExks zPOSEIH`rT~E}*-uAvqqHle4j_)9IRqc5YWg>@BEkmY|HK+?i1v#q$FR=1Z|x>_skl z{_D4fzMk$)s^|0BYn->CSNny@1!%jVP>YMY`yRhZB{><)N>PGr-}2YWS&@0HT(m2g zFboGw6B${oOx31C(|7fj=G>*{BZEFPS=$_xTV6J2>k~gKT5_9$i(aq@tQD*WV9F0; zBp@_|at(dPOSV@pF8tl86to*jFsU;dFh2|3oG}?))@^*g&kH0;$?$A2^9fhIL2z=2xm&iJ1Zb%!gopleG zW(|NY_e)voej`m@Aq;9cIILrGDxoWn>9E$Jq<~ihJFhQtcBaCzt)edxvlmKPU14o% zLHm9UJ?PpyuPUf^z7EqDHoKW*`sC~5T%AlT_J3RnY4by z_LV+pb{A^Dvm@yubnsuSA5zR~d)p~c!5;zGBYaO%0M)*~zhbAVuFflVk4~3>ERf*M zBkE#3$>KCwLQ(WkcCdu`*A^kd4+Dpy+fg{ecx9b%r}c%47ug-e7Xb6Hxl_r`txT1y zD!iEAf>G#}o6~8G&+S@`RJgQQ9_v0*nCvrcXQb@BRZ;ASzXM%veJJm`g^`CtsD-cH!%VB z=%A9`bXCc3x>DplvzM2LO~oB86h!J2_7{~H5cas1OKMdrpGPx@(~Q1`29uBCfEQPV z`aT-6L!C{AdXnlhV&qYPnas_x>jNW@&`SBXA8NZ!N!}#&Vz|G8>E{4nU8gO0Z0zEo zP}8nmRSp*AO%W~Xq_FeB)rRSx=C-KI9HIC5{v$_o*$iO@j`zOW)Aw5J`INb47VkG& z&pj|bbJoNAn$4e00S)vHe1oCi-i(DGCEdO*|4uk>liKvmMOj#X6SsPBnp$9K!}@HO z@8x$5sO6|g{ICm6&aL0uWytd(nP~1|m2DwXQ z>xM0S2s>^QNyPU7t32(zozFg5OF9QV15L;te<0>ciY1MmZ@`eS^808C_b@sSDQ4FC zeqPtGr$Eks$E?$)YOJTZB;dy_FzDlJ=l7DxxEG;|EA8$7uIrnz1w3^F@6>@RVfWp9 zzx>P>;a6RlRnq=j`vf*7C@B1SiE z37%jn2Ex^1XVo?iNo^KR&OyE$Rv_SFZ^{nYoiH-kVem+i8edugzw@Kf1pRU$f#8c~ zqwoD#mAgSZSZl2Ym|?X3ag%RqLZ|vX9Q>8o@j#)U|#6~82yKUub()5>;|i-4=O1P zfe|^VJYy+>LmN)fvg-MIhQ5%;r)s8Wc7eiLk_@oDOmX@03Lgf1Iz0zL_duEV4nLpB6TeH zfk0zQM&Rj%jhy)+%i7<^#)|WEDquF}Z3DORc)W=Vb|7B3^0306g@8sQ5f7TrU#H>f zTAlt0xlpGtB!N*t$k@E?GIL&Sw)Z=?k3=O^-Rn)<%UMY$-eHe%7a$UO3H zDqXn#wY*DQv56D|{GnCq<_6XXE|LG~>=q>K%scCV9yY5d1^QY$8!0a$zNLl_u-J3~ z%yTdO>Ou4lm)eTpCN?f%QNSeu?y{@lB~cA*{poN3 zJxc7s9W?Kdv$nLMZltVN;pX;C{w0R-0OMkiIdjeCi(W~zYUbbL44XzH&iS(!ESszW zC=sWw)JUelt)SF!@vAXukv)LgLiYBc%)*ur$UN5Mny-V)%GgF05tkd1;{Qw*(u~Bc zBwC{7LnV|vzV0Odead+9g|uBRc_eR?-|LtgTC7}y!Qk6>Z3A`jC_V`DXe^s|;6@bf z_LrUC1gL2O^ zz1qd|yYFsE55m=4J8uy$)56x*W{lER0O7cNxhv5wz5G>%TA(zCx63#wX!5De37=j) zAm^6nh?;!7?7e#?w>w@JUZR4%kWDXbMC{N0iYlQZp zE5B8p0DWvu;#Q^MFvSOpSfzvygk8qV|)Lm8F)p2Ya|*K1P`coBpINb*lUxnm(6z{KFqn^OxJ#6C$_ zkr5qKRdDNg0yaTsYD%ud=jT|!ydDnBRP<0^RC}L?+H_dFkm|dd?pmi(_L-bxSB}&2xeIL~lG5~cgHZ>v- z+kav>eHzzqu4CJhd_sX&dEUycX5W zVZdN_UFXNd1Y6w_kWtUq%WDA=%v?9T3S}RKm}DNRMAjYL+6*xE@#DB?KBFITfV2Xy zuL4>2e}yVl)**Uf8il=Ma*K7$Hu&t zxTO!rjbRS)IQ}5Tna2ZNX<+4{oxMhQ2PT^I)FtD%xY0nbS`k$hXc?w<0x(*vs@$4clVyQ!q}e(FkqZ2gPZzF-~f07Z6$C$SLSI2 zD0i;Qg?a2LQ>6E;WG->cctGz)A~=*qr>6&4_?`8e8lnc4-b3vWv{=XecH}|^)@P6c zAeIwRIx9^;Vt;ierfYR$YeWxt^iTb+VDsKrJP!wnU21Q*Wp6O@{~_BtB;Eg?2#R0! z#ht{pN@(9)+*sm(HNSxXe1pQ}>w>!~LmDTaDUIQW9y|_f*t(kMj#SZ4^LSGr9Hq1J z7)>a*$-pU^3v4YMAyW7-T6zoqI46#gchl#v`jasD0z6!IH5+XBxPeIBy2a?;73enAp@Cq=JHUFUUO$_bTpyQU5$WuDbVuoxc^g4a{n$9 zRen2E)Z(^WB8_f9dlw}g!{9|DBcP!< znIG!B-0}v+Ga%HLQ$ zryJfaESfMZit3XiyTvk5xqhr#f!Lq^HU18m!u{P}8#n@&ad&MwWTAjGE~n899z_pYb6lRqOPW0J$+woNvaUnA8`oh-V| zV7z!m+3}AXw{{7lfb#}8seZ)gjn?YD;HiVbzsD#r@RtQI2Cs)7;+H(vFdC%v83U7Q ziP2eU5CWh{gaID6am^TSq`yHka_UQ-rT|5S1emGAT2qvQ?(LKHJNazqrz|FIR}|8e zl8&?PZN~RiBV;x`;B-LCQ(vSA0Tfvz+re`U%p9_z{Fg}54CB8@9VJ_n%OI1tmJ&fg zBt)_+G&dNo>u2-1bm&D%Vg3G?ratb`+*!x8m>Jj*R0Uy?rS-$caLT zM3a(bgl5Ds%S|@U!+mTuQyIazuYW7jW(SO=s()&W%i8qe9;xvPNFJ8(RLUN`kRjEr zYa36d{S(eMBmaC29_R5UTW0(7`&&S&1&s3SVFbzozj5d-83};IQ-eHx%$02ZCZ z5#;WERB~15{BW6FobZgDfSd@1Ek^+GFDFh^b)-db!ISwaJDX?FTpU2?N_*j`-za&CvT-)6+U&^A+Ck_x|&FDucY z`S61Y(yDF7Dsb>|9-Qe2glSR~AX4k+FxWK%an~0V88`M6WCS5IuFMyWk7sNqP+{03 zoe43xLV9UF68s2dLU(4D`(ot8E?H&6BcF2na8k!6O%F$DODwt6^!LqSe!h|wesYn4 z=DFVN&>c1(3HndhZw*knTO+inG?NV!tCwvWadZ7^t>5;(X4S^9nO}8Q($QGQeAoeE z_^NTxJ^M>_d2*I@KgFRXH;?K)a01@5_rxDnoQPCtLU_CtDfB9wu zjSjD?D&_haL)8Dm%K==($)BqS{PxD?(W6ICOibQ$b!2}1tH@5r2_SkdOhIEJBI5UV zG>gqT*?b;#as!SWVK4{iRhes=NzNOt)e!m+*-k(i56Hx((}F*Yw76fMp(Ge3AW0$E z0a5LG?$6@{5Y;wx2JLDQhE3b%9=q20eCz`_>5n4vH|G)nxjJMCJmg1M>b@*9dE7r3 zO`W(P2-NG4HFp4Z!@6B(K-ARtV^6Xs&Ud`qqw8fcHPX%e=DC~(B#b9d(x8A{`5);1 zJa>_|3!wY77J`nX@4oGjH&zwLY2&l?>L4pDH%46^P<(Y7s>xoA#@Q z4!aDpYz5T)u+2y=8Ni3DuwqCd`8G`*EExOF^=C9}iV&cA!1^?t;{mFWK!*TepGGoY zI9yH>SF&t_$CO2siGqJ63vc6JgBh5#(W6h8!A~VM8vJm0ME+6y@^7>a(2@Y2RZ7Yz zLye0C@L=BR&)-IRy^)0s0HG6kV&xgTJm8*RB=A)ZT~6X#KXT82@x?(0fYXEAqY#HI z!>l`9fi1>cjcD62lk!}^j_vQ^2>nKLZGeT=NxY9$h2MNU5JzZ7o2okfm=pMcZwyj$q4=-iU7w2lVZeUn z>Eyj+OoLy>v|Gcr);RfHnN?Ps4z!rgefamF@w>O+WzrSkXIlE+e`0u_!JZ30#W|M# zGrRf!tIj|F@uI3?^Hvkh3#&?9q_0JIso*1zzH^BO$cMy6|8-aVz~n5d$yCP-HIT1I z++5Q@FD}FE7bBC7^e%)1q=aq_Pa6>E3+jeN{$Wl(aDtZQPm6+5C_ulS`a_nhow7#* zKD`L+6OMx?XYQRQyN8}0d&isu`*z90pxF(&#r67SM}w+~@1~8@T_(k-@l>@^7h^>-~r8RnLUeZe9(212k>`XIda& z2dcP$$q%SCDTsDB-esV!m8P8X;*8Jg?WH$79U&3=8Hvt)vD|VV!9(PME`UwWBLeW3 z^xeA=skhTGD}0aMX9L(@K`t z6M5JTSP5rSz)hrm&JY4PQG*W>lI7y}WS)bk&=cBNm8;}o!0tS1>QY;t@CD*xr;a~> zrU2)GE}(m&jcw`c=^_UMz{3NSIpUy>5GwP(4Lx?QgLcXR58p=1Gq{!oUvJtg-`pkU zUkVd3ZKEe@dq0$NjIDf@B>emp-;Lpz)Y0;m{o}4o99(BH-(%o!&H@GNVaz}+*+ZJP zf#H!Bg5CTgL2HO$j~}iEbiXz7$cKMn?L6#%Ioy&-7HM@-+n;Nv!`HD1pI5(_4?Z@( z_v(tQ-WzqyUM! z?3ES{djmFX(O;VEiEo=*C`e}4UPQC{DYwbQ2Ubl-P`Yj#2hl zHwKEPG;%8KsE<2+sS>LG4z_b^1%5|iyviM%hRLp2gyzZRe_5nzzFRsM|_p7?;^&=F_dJ|Vp7MgvFvllyD-%p%CQo7Yd$hK=S z9i3me0J&%iG#t?PZ@bAgA?x=_-P`4td*tRKN*=!3>k3zWO6>&l)w!+#o1%d`8zS^= z4_M&tV5dl|B+v|ZINoFl5Z*ma{zmj(`mT8oa#*pSACgE`tfBcHH^J;CZ0-hjcE&o8 zG9iOs)lJr-r$m4{oj85b8t9~O{C+e<03Xcux7f!*`Yi;SFOd(K(2rnU&PIPaYInY z5v|oH^X_t%kP-cs?@Mb2LH!H8W`z_AyWD=Bs|79@pi?&{tdbNF+YYEVXB~6)`3T8U zP9uTO(3X)-S)wd9MLP}iDMr8uNAtwt@=lm)VJd)XC0K@eSxM4Rl+g;_h z$fT-b-<5*55fKA%Q`ABm|ACiC!;*W#0Z(h*a*82YhXWoRLh1qKqeF%aD-V%t`am~F z_ou0*LXV^;+#9+MrXp!O;-Tj>GjI_(!M&Wl=7kOs5ZQo7AodRUK&0MSmT{Qu)2ZJB ztM_D}CF6PmRrLFe8yvE>k8^;D0Ux09$9M_cqW`_HrQ{-|y`&eLOAC_*LcO>})DoWky%=jY*Xs2+TDpPX?qwdt* z9!PpE)78$=bjtksi$^YgKJiMXOMi7AW-yPbMFLA;#Kyykg5NvHM}HSLqn$J-hQVD; z8|!O32Rl50J`hTPOZI%}AX3N;k~y%_pcS+<=G=4PqCie#@2)e+#+I^5VI_{4t%$${ zb^)HP3Kprs zP3aRSbgw!y&T6UaD)akW!S=lh?Du3e4CMT@u?oJ{JDv*)wo}Z%@WO#YVMvV5{ri2W zVAp=*j86QIUWd(b4MhJ(LpvFHPoP9$W)Sru?`_s?U}bdV3a!6KYJsyU6VquClvc@@ z>+4T*)f_ioD48!k``*m=PrV#Sv#50}zYbcYMnKy=XH0+wl>PnrDY4Ua(HU?1`A`P9 z1~)y!2qkveg)t16xo-Nxw5;>o^|9^#D3REL5P6l#7eA?sVy^-7RC68)4uejBjH~>J zYMMfu=m`@I#tplm33HZ%;UZ17J&O@4Ur+08bfM0Shy?Ub@M7O(;IfM9E)T2nLA1UN z``PQx-38KGtX^KL z!u(nPD?Xyr^Nf5Eqf4J6J5@e9O!u$ttjGoTdp8WBLwCIkb50yzLUTtLL=L1xjQ8mA5cflkIHE#ysDUYjcxqdW`5WMbE1B*i56YFf-$ao)OoI9xE>&+prJAA(c5H%lK zzoUiaRJsVybkaF6TTv(|yi;`R&=>b3AL4+8m2#Mt-G~t<9PE1~h+CWFAgD!vXXi?h zrKu=HS z;CsD&|8hTlQW1gyUA*u*-Le{%H10-k+{G_J@;~L>0c-~FIo#+F9iSzHP^03pvF zce^YbO#%E~1o?mupKIC@gC0>h>|67jQJ5y+)22C!VS!ae(D?`hJFZ+C3ErwCJIuV;WD#V+b_ z=Et70AG(t4e$dvDGY0xGbUO##vv&O5-g-kjhd&=8`#tU_? z&aGi>^PBU&+8v!B0{|HQkPV=H!*PAOsehv?yx8j6L(lOBoo}e?j^D2cUH#W6q_PJ} zo3RGn0LOFE5iOYhfe?u)W(mtrk$3g~sYe0YK4fv{<$EH|3xW0-lb{57mQPP#+_azI zIBW~qvubiafAiQss>?*V>;!?c~dJ?XN4@c}Mp17`U(_bnSx_d?;Pj zsL06vSkjB1>{$WF#W5kIw#GNB`6;Pz>1)^OsEd7CbsJspTfnQ={pKs}5nMS1FtPVd zW6A9j2TMW=GcTRMetWC0fMd~N!K|m6EQkp>N;^%0x8;6SmHs<;=D6W5^Yff93B(oKZ(pbRO)V?4K|6ov)7R|_Z_QHz03Rs+PI1#6e;)1b ztQTN2QG<%+7jqzljmu}l5lAQrA$KKszH{zQxIPJF@9Z_#Tx-oa#+Y;WEa=9n_@BM(<<$`Pj-1Rr zAVZSD4)mMPBoTG%6PCjM)efXzQ1u`L42EPX^6}Oh_%9|palf_kCs_K>pU5~H7R80n zO5;Wx=w83@+CXwT{+1%m5mW8!y^+~hhx`vk+Y%$)*UJ}mRJ;bHksViiVk!0@1I{|M z@AwcbUgAc5XNuqj1lFc{<}hEITa&9xuL`?n$zrl@_6}BC#qTx%n*iSSbvw}N=ik3+ z6wk43(iKMQUgs0XC{{+5Z*DXP@nAxf7*~;F70K7`izkOmV$pb)JV*0-81NpDP4I)Hj z-F}=@XBGnR9Pir|4?W=f;QXH)6I7#cjr0FOZP33}5h1R2>|jvw0BRus6rh`Q3W>}& zJPih!rE=m-<0?iKpyqlhue9SY@(A};8ZeeDIjkM9*4XzYPI3@(EcC;!Ml>kC>9Ncf z3H}ge3;~p6;B4&9!*4=)6?xnlDulkZjS>NkKeEZm>0OHok<_gI++3`19Gdm_N7rE#@uhLYx8 zhmOntbKui{a6{Ao^B&;$i^;ExEh>F;Ei_gmfd)NXV&lf*1O8dAae0 zMS0AP2EaFrHyL7`f$RTrdF9%FYL$5_PHlJZE6UUKZ(8knNn_J*bH*B@V zzeJsLiXRUH=kEEN8T31NSl#27WARWK2rOte@cQ+%uH5LM!eI}+o}nUVN^7lj@+| zCXND6{Qf$H?MoS3>lGSpxMf++ebuB|2Rel|9{-=^21;R$9~6qxC_1bk(U~I@Yq9DN zOVZ-kqp2nQB%Nllbp87r@nD}0&3|V9okOeyDxS^P7fl&6b^W)r$SCoL`|GigO zd8)GeSMAjX`sj#z0ViB~4bz*oe18<+hQ*;T*p>8zDnnh&^Vb>liZlhUU#D2O`)?B))-pUyz06Fw z7lXOs?Mvx|2d-)fsk^IW)`58XH9f=El{n>0>a$@y#N8RII6C`kt ze?$x~&lrFvr0c4RD$Ld3VKq|`>xL4h=vNCE%OWB1cE=`BA=>v|sLO2odXvbbHhP8eb8EG%Fh*FInB|A}7O+G9qF9#}_6R9~+BMEUu3cnq z3=6OlV_C2vVtkG~!}ytTue?W8$I~4LX+Oh6C{JFH@)3R6R7LLNg-nNk*ma}fSxVMH&XF$R4V|C%IaV7li*;y?_Dr)6RoAr5)h-1i2nexz?xQDoACOXkyQ1>WTX*X`K>NVYhz2Z1AJR zusxL%?EH&#MjXs-Cr_{uxkZ7z)QaW6{40)2d$&$&)c32=i$JiOa}(oZ)@?C`$>fC6l2jttB&1_j7DK zDf1#~kv9c9)gkum&~~pk-1!@E0R&<X9kT_|dNG zfyy(79dD*gVutEW_h=~)z&f=U^1v2^8N=UjgG25;O4n5n6@hmZW4-{Iwze7HFd`UJQkmgsNu)wi!v($_XKZb_XH3Z4 z`zHY_r?ebs?LokjdsP|L1@9u6mcTk-0GxpZ`d4eV z-kBonPsdtPljOP<7gNnJX#rF9N1=qgsLbs+t`C3Um^et;I}S+ve{PR1a2RbPvxnf< zD(cQ(mReueC#m&bPjS!7P+PC^Ss~n`rw&?*nne);i%8w+p-&Eth}``%E|1aknk&gb zII4X^$A{)0XMJ5rHT(BAEy*RF>ce~IGE3@Tsx;|;O})J+*GivEg(y&G&7Ey(t1^#y z@@!~Ce)E(~KW_gn5~FIl&AK$+!zeOP!{En(>k4x$eEU{w%Z&28?`FC_AcJE4Sk~V_ zhB-|>((}FpE{%avdnO(D-sU3k|DnA_bwV$nmcyvu;_DmkH#;kXeo1t ztpud_F}gwLe)7T)^V^07(BUPEFP zp@9!+Zkdgz{)k}gL=LOmO&o%6=`m7Z?E3z zDY8)@%NgEg8Bu)c+C_aNidXC`k({dvs?&xtsAT~dOkb6gV?xNREXXG$Sk({dgaso z36D1-+Lg@!KgwU76meR#myb~fntgir=Sb%}HD$pFW?Sjy_}0DUI1_4)hbj`q$flxn zV$Vwo-li>Vv1YHkq;elTrWD}0H(IqsfV5NUSy^p8rHM3ci3|NvAbQflpTqOX|M6yH#yuZY~Hh z*#>@-eM{9c8wM0;YPX9LX_IMBt!+S<48EMZ&2dM-<#CR`OzE$?{#q=ex3Abv0lsRV z5-u;w{qv<9kOP-=JyOOM2kjZ^XI&ifY7lZB`tWvZ)H{a_#xbM?l)vAP`|5{SU!$rF zuAE>U6+(Ue+HJw^mSQ|0-<4K&&f!khrUY=dHA?Q7x2Sv&t&N>Vm+&m!;rXkeFC$HI z!ZJNODfu<`J40H4HuXLq1QI86`?efgC}v2vmkfvWpi`P*p3&YLRBdC>Q|n8n-{UOR z1IjzvWJL&4X+ilUhX~VERFad!cRWF2P-i1$J`d2cmfc2e3 zjG4Z|XKjhP4T59SeHkzxQmd<|D+7=Ekz-lF9k3UE@gml3cd;tkBe(?Vri3QhbLY;< zNlG^D-mHYWwqvSAK;ldzARO7jlT>vq3N}TzbsOL>`>{Ll z|Gc6J`td=;CFiv@kR3@J|H#skp>}BJ4-&(q^;6$8WG{b+SB1~MX{cgw&3HU)gMS3G z-Mc|={h$8tUv_v?o1lhO`16#>_Fpvm5?Z7{X6}$Ib&3ccvfWq^9~(g6qkP@=@lt)V;qb_%)uarosw;O;^O0(fz} z&8w}vKv+{bB{oStst8Ky$vwIOWBY+x0H6T#Aw-@RTJ z%*}drG7HfwldmHnKk^7h%_@12eeyc+ul03HNfT{O{ONaGBlSb`E?`JtFAgAl$r*qE zAOC8%aD>gtM2dK9Rf`dirj14$=IQ~b@@-t|)G};{0?DC*^FCky6aRu7A!U8>wDFR? z2jL>+Zn~PuGo0d+RY4+&TGw(B^(cee&}RIBCE9o14GvV4l79MK(1S z$RbjD-a#+>jm)fZF9`4ArqcnFl#3c-*BXJqOQN-M6{?nrgQ1OP`msd~Fr3DkOi|02 z+J+>=57^g6bV8@P$8`u}Aa9nxxC=t2LVGFi^?IAzXA9NklUIx|)$=K{0Ur5!r^P6J zsSx9CB-#cEfAvR5X5|h#M9g!tODaj`cGUo+0|q#F=5T5O^sSp$8M)w);QgGYEvVp5 zk7t-(7kJNY4VMp>Zb+;5XFpvxXX3rpxZ|yy1{L0!L-UMNd~<72-&!nCQIV2Tg#-=`|WOX*98&!oF7 zjvI|z#Qo8@dscy7E?TO5-kR;v$+P2EvfRKn$S*bBH71+9x7A8G~`DT?5h5zndjpI{Fcv;>nqu5dq0N{$ENyy-u?0DKj;|n%BATxvIu+3jCIZf z6!ulufccxr(7=_XygPEeUMvrYCzNGs)>u!50qOEFVv7v#zw0!n2;^CHYeWwQC7#Gw zkpm;7{D6>4rd1AS;#eBJu?KS%+-^iKK1LgP?*TyZuZrf# zz^!n8mXax*4vGLq%Nz9`_4!2;X!Xm?)ebuZ>H_*!?!Z{@QN!#}gb^1;-gF*FP)kmO zubb3t>wZd7bmTaXx%gSFGIGEFNS=Gp{jviG4qz#Z!39SGW=o1|Is=K6B-8$felPot zUF|jq`%CsfZGQh2FXEh$r~{fn=nc$+)!gb3K!_>%p47z79(^y`Q%BW=q#M@nOp-GM zY-(ht2ce{2iJtGxHve_MAZ9bCVe!Kzu!?n zGA;rsGM^jF-kIHoO;z@x#02P(^L1mBE}*GOCcNJTSW(=VF2)FWgXIlM#Co?xvrxRu z@Ni+M!0Q@il}w~>GT?J-^5hvHH}s*dSkjl@*C}9n)vV#;F#8QGrcsj9f#X<8XS7PM z0OBQ18K4%{QElWp!ywxXQ)DMQqm67C<&>}9u;jQf^V&qAvf$4;DmfrT7%d6(>(fEV zi8{bEJu1j0s+kq4*=*|LHuAwjb|QkPvmY-Cn&YQ*iZavxO+qVOU#Vn@s7}fvUO!RE ztYA(!)3ZwD84vh5BOkl0z{XWA36XN+Sf&RyusY8d`+a|wd{E6qj#Eh~DV>lmy&>=0 z4z%7Oc0yFDQqd0yA5D_o6<(ImY6WPm8^d;k;u(mSv<`wvtjbMUi_mEltM%l7ERToI%th8MsI)Uh{h zcX26hf1bL0+=?Bw*ZLC+h#lk24fjKWQdQR=^+Rk zIdyW8i%S=;ZlgCIc+oQ&`x8Pfb&|TUN*o|wR0GcK0mV52S9yZ&81Y8<)Qf*Zt@gGG zrF0G;eD?dC$o&sk(dd(FJ4zd2%F~L51X!ghM4U|SX{9ip0nLnaajCAVf>oKUvrn0XK{YNT6V+*W6FkISgEz5b-ik>@p-JgmjE}DgMP&L-rxCW z^NOzX==lAYGFY2W8VJ*JVC}oq1%2G_^JCaz?d=+CjZRO*U>E!J)Pq=GD5^!6Q5h~> zy6HF*Y#2FyKb!p-cYld6W~*c<#GITpnR{(mXOd+7w}!+My-*za3y!{!Eo=x z*JSU#M3eg*P1ZhS6l^o;$+KN92x_pg*XaiVjRER1iR?*p0!M$YWSj=vzjxZL6t)Og zL=EzdUszrG&VlGeH{q+gT6Z=I-ObS!lhJER8Q5)QJ3kM4yjd6zLmTX(QM&aP?YDT! z0U{YVKS%o!Gs-$hk5&l|$OKiIIcK+_W&Mnyht`KDJh~-yLhdr;(2x8;+_(uF$D#*Qms^jF z*#0AexyN7qdEL^zE9KE5HscL#h<=q=Zfhw&Ve1uKb>ZQF1XjxI+Jl37+7&}$;DiR1 zyS^eM)CXmu3#DI{oqs~VSDzH(RX+tfvmJ`Lg2K?&=8&K_n((s+FM5!evwkKXvq|Y; zf{^#UNp&DP>im9q;W{1cG-+~&m?6khsJOJ$_YV!Z2w-_3`F$_P^`TiUHn9-}ISeXO_o zLLRi%y6417X;I>%4${c|oBu5QiqbTc&F39mTH=j&nVA zW%s`yxV~0(Wm|@L(Q$H1IhME+8sEr-;ZXnd$njBw8oNOE{5H}yQK!^K0F@VDq&sinUFQT$~$a$#j;1%C#r7CbQ>KKzH(z(9}it7)M}A@S4}Uk zRwZ$h;7v{^rXTD7US8~d*Jek1*d0$FD-@@%V4|sn1S5Obo#D^UjD5W+^dWWDM$I}+ z-v(8;t~7HDz5}qJ)2iCFH0CWv z?%c*MOq$gT-m?$td9K1YUOD>fvCysynUlNeg`GyhJ;)8WQTShF>%PWECq=Wj?%{CI zHxC-Ut9|g^ux=zfe5g_{bG^ote(PD1Tt4$tz~DqsK$~pc4QWdi63KdT@)n(XYjx4( zM=TvzL^FK$l-N-@L^t^q_vQRWQ$a<&@E3ACmne@PlNUJ&UdXcOGvy+Lu2AS%nL-VOC zXxw7IDmHz2bMF(b7-*9xs8?92&dAMqiCdGF5Na&<=;MKY$XVHZaL-ftKIQN z+!MhMEBD*h8$0!gcS zDazTYuLGPL6Z{$Ft6BlsQ&K+HcsaJeBnIG|-KwrQ{KQZc{y2KY<5_>S8%Dh|u%)lX zu6+@mHrwUFUeCc?H0_z;Q;~>93jgte`&;gr?fo!{a^G1q6~k8wnFWu&LFg5w0z)XNGww56D6!jkBK$-O%~Zc3G(BEDCGlSWI6 z_7X1LBeKkT@9yvXXFK6=`s4coC!B$5AnWjmwH2p0UbGOzSc349Q6BbxD=nVtUSw>tdJeK}G0^ejiHyP?~Son+NQK zSNEgXxjQhV+|B;1F|#%2J!xg8b=5uBBN>qft{FaeJGYNZ9LOMD6nXtCnp~80g*Jg< zC-UFI$0JZu&gy7&udW0#%h@pdxo|?|7diJf=5iiG>Q;8&Rl((lvOHr;M&DnV(7(Ug z6MoZE$M#rvpkh2xYgf5S=*8;Z+h*kw310r2HXX{mdF`?>VsPH7ILXKIiL-KOLNG^W3!^CTw)Y{N}k*K=DPVr2Bm*sNDB8F4#^c{!!@T(NK zi*zf3si6*0xO~eL-L0Pq?Qp1Z?-8-&RdpD-ea%{!obzD6YSH92h1oBlq2Mwfqgxp3 zUS2+dMpgSi9Js2iEmLR3$oRq^P&L&|fz;HcrY@EVjN&|cf-)_?4P`8uRluJ*oZk8N ze-kJ=-6XeWQckB*yvEPc1Md~szP2!_Zy@)sCJ~piZx%pNp`Y=POdkDs!mlr81y*Pz z2$gTT4JKNq=>!=LTwKpZvZHR#ma|MMvg#5ZVGkaX&erP{bN;jdQ^8X7hvxg)fYmXq z|2ETwvwH?}sK0}dAC-MZ%+KQSc9@FRWfGOtF4Yy5J}L4>=Mgn;O}6*E$YUi660a=# zNambIrgV;VjvAL5!N=8?-zsa@4zAK}tcWtwTemUnXB4B_#(9&KAP;q33}sNqNj5!K zhI$N2V`DW5pO)#CQxmLhC zTj&xhoqLjqGvI|C4Z@_pOVEP!CKur=$_=R3*+wbt7pGEPX7*ANse0>o>d#XZ&ep~W8>`DtYcD*568E9Yx2b^P-3tJDx*^law%ey#s`tYAKkf z_vD+3(z=vxZN_UAs7uawZ8NJACPkFtOl>|1sD?vFT-VAjVci03XMrZ^4Eox0icp}L z%i~{JSDqy=%5@);L1wE6G46DGdvs@oexcnZ;@guN{G&5^%JYmR#z85*q*?jWU(|C^ zQ5U5)s2-ALGy2#_^;_%mcdUQ{|ErNw9ol$%grr+)fqM#*nj6WM(9l0Y^jL@y(?b|t z-WD%WI1%a0Y`G8_P#qiU;uy zYc{Wl?1u9ylzg-I0`>nN1QnVNRi2U20}WaQFY0hAo^w3dFIbd|wMnKkKuC77sbHvb z9JG7xKZZ3IYJeHLUMb9>zk3_3MS~BXs9~bH<(1vBqHXO6P77y4t^et2rM4+~`(XBd zJ8Y02b0z1idAWQ)luuh#RW(|<7OJ`|Z15PV5hoECw{xs`=crv7jH$;b?H~7e*Ldgr z6Flrp`G=-Zn-h=*R2%;)X|GVLP{z&^JU$bI{VY6{gHC5poBy!QSaxbaYQ?=%jSi1H zn|Ze($!dglk5!{+5!V!NAXB&H`fOj0)d@3+ypR-hN+&vHn{l;q`qHeryR^fHsJZ@v zN~uDBzP8Drnp_#Lz6UR(B2DX@SQlVKr9DoIQE1uT8!5GOS?Oz+8LMq+d;yLqcjSnF z(ZK%f0ypN=5I6+yr2Bgv0C2^X|D-iv9&E?Ef;8kwS|Q3TywETN8Il<1k|USWaOU2k z+B0ack%>FrjEHW@9l90V(*#~~8#EiHGI!GOzxM$Emq6^9xF!7O`8iPe5%s&dcJ$ZU z{Ad|F=O@E!+96U2`0@1C#i#>Ft2H!8YG}5{w(tmR8)!djMizOIhjZ#_C$cn znisYXS2MAkipk84rZoRe<*OTWaDyDq#0b||ibNkNsK2$V;D}l51{RjR9bZ!OC7|xQ zXpL$hUSO$ZzR}6qcg|DZr&hNvsNjcIRMLrdpv~4Pp3%0UtaVW&QON8tk^Ed*aPY#Nv}&KQwTI89!XTMg_zZ7>^+0M} zT9fr+$jQvn=`kH|EuU^a(;ryg;5<8rw!pt{W!UPkXTKfyAlMqc>i!|r&h{pYaF9(E zzlHSR8mgJX+3t>rns-8ek(AZ!t?KGGwjC8B6jP(7A~6utiidxi@WhR8BIR$w&j~%o+?~Sp)QiSN3=txAE{fQPu_4x_4Q2eS^XPoKz6V>S>48x23DKCj zqyPG1GXC29M@T8LzyeNRajs5mgu-V1Y?d#g^1~oP*+-=gztR)x(L!!@o_-ol%$V@n zLtahnC)u?kr|%3|d%PChZJve9*=>+J=}W<4z7@0~?Ff?tt@g8e%%1k!r6@dgc&^q= z)aY%u?(hZk$XeGd5M(;Bo>2KLln4`2z7m?xpY z4kKjVvgB(H%nk(&6!=~ycZH`RyUakr+1nbX0Yd|@CSK8xld^wwBo*j6!uXjM&q*Th{OgTc4o<}lST?_8~(wyjc=aE6b*TC65 zPLv?Tt46m>6V&H@*j3U@qLPY*%Q7PUyuH<1m(I@?CSh4oLY(;HKvp{>zP~KCDFqpM zulm4+^xr2VRj_wtHKDn=3m1)q+12*0=Sc{0z+jGp#vg`D%lX#MiF1MD62`{zwm3?n zl1rdo@)@l2X+9a(oQFm_5j4PR`jmkKi2u;nnM<7Q$PWSnkbMv~<0YN_Lgj;7xJH^# zzF6E&GRe)7;JHF#jIkUD1toQ+sVdps^M6TN(z4#72gFj83wY9Y_YPtMQ{12;7g9rhhE%G48YPCT2O~`kp!USF^3VE0YF*t8nt%NG6xJZRdWzJ}WUU4v2gjN1@^kHzfuw@9dcN1C zqY1f2{hhDuGLynSVs=G165>(Z9GAW?PSz;w_P_BOftJQ80>RcG%NQi_=# z9%2?r`OQqNZSfEYT#TGqB}^nOV#~$7CmXL<)!JDUEX}e-8rFJyV8N55b+^gkl9VpF zv+WLE-*{I&?WUS{Ya-7;Rz5L& zX!&h~9~Ig2mS*D)%h33Iy5a-Uqbz+BHf^p{c9#cI4JzpC5yf5!Z<~)Y-gD%ghX(`J zCRC|%5Z#w7y+_eUV{%lPnU!r$pWCC1#p#>MB*f^GswChZeaUV}^>Jw_e7XJ7caf(4 zw0IS0y2n-;swp+vDyg?_eVek^=fSe_I70*T6e;$Dz}ZC0fzlExrhJm$1v8_z%uKkj zG*KA*^L=vHs^AM1q zL&o!Nd;_WTbo?n^wV2&UZVUUtXM|?VX*1WW;G;F>>(k`3wTn~65dqQhLFHw%pjjxZ zKyA}pOB28sMjVg(3N0Egf%`Ty?K5V&s|84R8oGI!RcYx`Y3If8Qe~ z{~2+AS|H^6cckCFg5dr)iSm^5zAGPRN6T5RS9>583d+7dImzc$+Sdl62#D$FX@vjP z#KejmMkVj$uf;YUk_O)oJaxQ~>18Ry%8d3&W73v|wVhgcR>?Qj+v&9oNVxS;=+HYJ zm%~|DLLza|)L~(pcsy?qe@%q7b^lVu1M|g_HR~_*svuj0d#bmVbAfYHY0Yup&Rw>E z67amR4}T_=xdp(4!bcCZ0D}I_gI2Le9?EZon|~QW6$u_X%%wn(TOn%rC~ul zx2?4ZR$=eg`g@_}!~r~+rx+-=lmsgs_k*??^l_fGnbt7Ei5c>6+NJ@oq_P2p|kAxH*vN` z@7nOLs({aNRn%Abhpu&Y&82mg4#6WWg(ztJW!BaQ6O;s};hsT+XdvfK@UJrAE)B0& z7pII2EiDIXSnF9YAGR9};Bxo+9Bcfnu*;hoYFR>weYE;(#C&L!o#xE!otT#rZXZ7= z(@rz#F0JhOWiZ&8<~}=(7=HFbeT0ZyZQ!h@ zv4KHsvmXBJo;26SU6{HUbCkn_Tg`75&H{t|)&mC1x4&~Z1sNn?zd}-vKXSyI4-G&^afg6BAuo_6YtO1UM=|h=_m2~tq)ub711(j=FEh_ z#cA~)f$5V6biwzJ)V;7i)V03EN??zy4bFd2UHC07(xxC%BbHzAUA*?UV%1%p)pSuE zlLscXDpZttzLjsCER{n>;mnm^SYJuR&z$xJw;LeYoZu>k0`kY5MD;{Nt+?5$Vl4Ls_$ zb+OCO&kK92)i;*zbL-oZr%g=8h0e(QZ!K@mLma!1^`_ z<`Vo`7o@ma*E730!66i( zp*(*hfdL|Ye!#n`%SpjijFJC-enI;9R{1R)Ty-qQy&3ZJJGzs+o+}(2zT2M<{Hi6D zCmh^U{yV^1O;6*)6;$8p4^*h9CfAv6k_Or%%(XvjkV%*ofko?*zFIF)zcM;#rmy#) zv%h?qkVB(!6VMe}#bwds~5_@{;z21@Eb6^isZ zfBjPdFcTC=|4)sQSD3v2R8Xt0Iz2sQjLUkqBX5QK_3^09tW>ophtEv@+wh;-7i&9f zK)6NNBDDnc_3TkhQn4nXtUhn_;Ku;A!O2d`P3IK#(zXsHpI&U!latDkFD?T=du+HK z*7S(kzL(70q$sS0-xq(l@fAH?CqJC$LbZS#Cizfc^d_!r2^IA3am<-sCRuDJzk)}j z5QNLY+AcCbj5V8wZV3u$M~2t5=&BITweBw&M=K@Ls>uMa=Ng~T2Pduf2NjfhCuv8Z z4di*H(T%T@f}r*>%=y2q#|b|F)Oa7Eb(C$ zAk=ny2hW<&=l~2j_!@An05-hGvo>YChgfN8jtJ`%)?B}*Ki}N1WGj(dXlXZZ_kxLS zToMXvH5WcP2(PMDAWEcPR4L_`aN}FOkTm@+2}I)#c>NW;FYh@@Y3Jcl<;sg0BskwM zY}i&@TN7NGd~A+tkfK@Mz}9`3Wl0iBY=E>VYeM?u6PZ4ojAm!li5%ym6q)>BPz4OA zBcC#dqx3m267`5AFCR7UtpeH-n@`7mJuteoXK3+n>NIA!ZvPTXPl6$@(>~UpeT6n{ z-<_6oG{NMCw3;*w&?Kl>Pi`MLPUEHce)64`(6H3Df(W{J=V)q|b!COOjL+5*+r6~L z*4snm*!Fp_-n2!jLMkie26~ByCZ8Ouy6T7M*dan-t6{L&@yT-I$iXF(3}D|%AFBEwvwIh#{9Y`h}!UO?euI_J@ z?PiB3P&3!n{yW#6?PRH)2xwiXXD zfL+6EiO|MB<;E7!FWTunkYp`B9%Nv2YkXOmHp|V!ot5JEZt6BwH?;V~b{vD?u58vq zn{#4crkqSkx%5MT#$4yJv%$injjr6*;I)kYuEv2P!P4?;;%-PG)7^SMB$dh49R{K_ z3AJcF+gerf(w=W9EeeaO$l}tfbk%C1D@&l_C;>le2SyyVlt4&b-Q6ER(*^@Egrh%? zmSj^FGg(%$`mUo+PKZcE97gRTXGQt=vW6UM4+`;@%sU*owEPEVd#8nqMtEAIK@it| z3vJ-$yg&ox;(1ZRM$?2k|Dxfjvmhdl8&3bxC!FpK^Cq^JR3{^HPS;QuZ#{T0myfkb zJ*54&OL>fFQI)U7VC0X>CeB@(n6$yc%g}&r{QHyP6y0p&rSZYLCm*~60>lZQpSVIv zUInw=7apmLA4>`*ZSj?r4$~~bzY-)qc6{M@N~E<+9+hC*O=S@;)RYr@ooL34!;)3t zU;u=b`WG(yn{87n7_@(^cw~~^&WqS8KC{*;T2j=i5!(ST?)j_h`D^t|pYcp3ji}Nm zw09&f8Bz=$2ZY3lrvhq^@X!F5k9Isr8e~zu0&5bH#{QwN03~&tzA&-VQ^g#oxOY-N z*VvqQ$y@;TCD$}kMi;*hjsVhhT4%=#p0EHO5Jj_WsiGm= zfIo~N^Ebig$WHwq((^hwo^=~8}GQj@beYRxJVg~qnV_Hy_c z5B6LSzP{NU-;1mIjd6dHA|#KijMdM-2Xe2|o}B=5idjMln$C|n-BIm!iA|_KyTw^e z%pAilVzxF-gziLg)FHXpnXx1?=$q!-cMtl3j?~W^#IO@b=Y+u=ub9sDn9eiQ8h#&h zkEn;gGT7q6Sb1uk{l?JV*3VpWNKSwW{6MUgu+vPgwdXP3WhWXq435jL)tY?=W1Apl z^;*Kb@Ns~;=e&1dR z{a_tO4d$2Cm_UPX>J_Xk29DJ~83Gqp8nct)F8S?RYcf~pH^Z(6$*vfxu{>bmH(N5x z=iP}4b4Ti#Cfs`?Y&S*6+;t>;(iGQOEl7%}@GP>?UDJYbXEd)U$-iz3cv}Ru7Q66* zKITSAcM-^AHWvp6duxpgTce{%Lwi91i2BN> zdVC+`_sYCu~ip70y&;sQBHsRW6s`~bl z8jLP`tO1(rp3tIjUm&GN(RU9lDx6-cHx4eZK;$ZlaB&tAdx@Uc zgGb7P3hlPQ-Ddy;iKL=HUNB#E?H-lsr*X!EMvdVkqTQ|9J88_j)Olk_<0bg{?es{)k0`(KZcX~X=f_F7~{ zZkJ>rq-5H_>=Q{$TFKm{xk$y2RRr09R%8yhL?H87-OmnBKf|$|A>uW%DE`XUE6(l8v~%EhkWDgpeA$YDtN4 zcvo;u>+M&Yh1I7Sa+!WpM?KcqPxlH;JzKSEP8DWI6!TZ6OadjOu%mFvJf42ik?nT@ zxpw#ashvAJN6a^}Bn;=meV?;ij7g)uvD|V)IwlWaGHGwi)Hv7(O`AC)>ZEch`uPwu zl;-~~RQTXUWq^{&xgob#oQq*r0J>im*D_M9R?OPR)KIc3pEyp<;@|==3z;D_I+D_W z=;{7_;ksI_Gr62Zg6X^br7VJjY^Z+za>s-stbE+zT~88Dl=Qkz(pmXo^G412mz4Xv z4I(d-Vx`tY!<@&a4~O1NI}sz}C!3ko%dlD9XNq=o%NTioep=(A>3??;0p^cnFjg{b zO@K_hr*Cf%gqexXCxpoTg-+M zX_ZS!U7hjXwRZ)pNe#PSPhd*RX~eQvN~|Vq(vX(2X-GAe^n)wx@)DPv+XH9$coKS3 zed7{rt=nXUR^`HY?6vfMFhQc=Ns+hSiu7VrkZFNd+v5BN%Ui_`gFFmewI0oGf32vVKY zR|}{cllExzk?2^)gFLit&ZohFL~{ZKP_(GZ!&u8(Pu2j-BD0RWUD|?2G*Q}y(j_-h z@u9~_Zeg(;OeJBH^tktdWvPKJ*1c3H*H6qj=H^Kex91lh&d*%y) zdhR_K82g5LxgAL6yPyM3+qpNo6Vcu$66BzGzZ?Kh*kvNWu1j+1m9Qmu&{5g$H6aOO zPf=vAxcf4yAR}?62T9PFeMLv--QCH1E5ZA++t}mO2Cw8ea-W;bo0?js_(Of7UgJlu zmRK@uf972clwO&U)}~swPJ&(>@Z&EtxJ)izMGfOrW*v>CQZ^3E3+G6vskK+q%Ev*~ zzWJCGU8l}_d-uCR;;a4_Zs4m}wX1hrS%Pt);0NxPRAT%{9(QZ~N5DBq&fLsBrI;ln z!q$#q`YaP*fq_crn77nvnZ7cqlO?fT9PtQ+WFIuLoImZp;&xN(W{{}?Zk)3cHRy6Nhc$w=Y1i6iLN+X`*-iBYU!t!wrJq_0)Cx!8Zs*K6NHwe_ZTbAa=g$6P=6(ZxIB z!xl^~(O5^1EdCmQN6fcrofen^qzdh7)ecP3iVLG;VaLEE2KK(vx=t-kejNHTHL!A~ z$>}<8)Jc38h$uFPBSHB60~lDM?`Y&@6!7NqRn_|NYN!j|$RV!^TiUNU5XA(DOym;% zg4r+t!aev+xH>YY#0zl2O#tsd@zOZuyKri zirv#3{^?v&?m!q{)!`;y?cainsXeD^I2HBznp)4%oizN!9Ffb{5C&e8Y;EGYWz9Gr@Wl*x{CKCwoMC7x(tSH(Ur~HCPS!LTKj3^Nfy3x zVhxXaJJ&`*6C#|X7^|c?_s9CtUXEpk%2@=Z1$HSB60*$hv&V|Ny|LE|)Nb!nGIe>W zh)`rl`u6G@XZ?D}8o*-a1um)@tKbWzF0n4VCoUb=2aAi;!l-g^`!}85$ydbExQjg) z9>#2V%qP};d_Q!|+ZM9(xmql0*)uC0o~RLw{kDaz+O?TV$CcXnH5cYOle*Edlpt|} zI$w4e@5<9HFAUAfC|~Vf{|0{oNF!Z(Z%kgQGg(|pYVB<$ZWM2X0+)FtP#&cr?O%&+ z(evgQ^pA6Xq@(#V1n97eO!`UoZxtzAj)M#(Y>SsFA!1n#_uTdOCXYnkdJpRSLz??F z2eum5T_ZH#vT-CMCm*Yi?IR>bM35TT%ij&;gmhA(4?g+4rGKlDJ**6n3CUIJBR7m( z``8gKBB$IJ1aw>v%m@{1V7Cceth{|&5e|cg~eZ=ky>ZRd?Ae>l&`(46J-EDdb z7&td(7@WrA(fDrm2#Yis*ga@;D<=ENyIN$Xpl4Nho*nlxLv}#1T+A7z9u+8=1?Oe5 zFmtr5yau#V{kMuQf<`8JphRqGXHXYAjS(1q5TV}sjI^i_D5rzO^aOA)2n8MBd`)1U zWFd^cCl(->i1?gQO3pDNM%+tPu28E>W%j@m0Ayzvn(Oz+L`^nG{{yBebZ)r3d?G ztn571Szk#-B}H2*DDxKl{wnaxWaf2jdt^8d_;>4X;_N&Z^C=k%+uz(($gQde>xA!H zqDplgwHSjA7O8iN&eFL1tFXY`2BfH(vuwq6htZJco0v!mscC{Oz!zTmp4kjAI^&02 zVIkf=D)x_g(0pNfVkWs-uUEnKy#r?Z}8wOCo&Z z_lR;u7CC+h8_(RJ?uBChxut^^ce_;jzJv1!SdgeF*zmOzNlU@FZxI0o7C(8T!3W7N zsd3?}Z`VKXc`YH*Z0JRHweZUl9HO-h-)7=LF%I^tMgST-CMrgx#g;4hnay*w_N*y} z?UkQ%P!btjlg#Gx5*^(yS{x=Tq;lGdI$X-++Xh&RjDWtmSWux=)@~#<0H@ye?Rxfh z=8-($f1*rsIzrhjFk>BR-3&<8U?3P?Hh#b`RD+%-j976KC|$e<*du*+~2PVh%!1)AfyNP383}%%QwQKxrv6C4;tdm4_3YD zMSRE+p|Gq|d{N7M*cf_nSYlMlxZ9LN0PPh){CvrwjkZJlkvSIOSB(SVIN`v)8CFFB z<YI6gOBCztz0@j;~&{Od0E$@ zMk*?mR}mw*J>E)&Q-91vM+cmZvB^99T0IS0b)ZIbdMA0Iv%mdBt{hl^%pyShw(@1R zBid~&d8|&SVNiR3vNVTKJ2UtB8H52S@SgS^INCLVH5s$r#XA4J$8`01l7(&hjT%QC znIJ-JCpQMhHT&R_-?UI^7vcVvQw!3Uk>E-eA6ku#g0!~I@jD8|SjTP^tMBO~Yi--0S)tp~s} z(^od*7#jLbt;4EGhRZ~wO?4*T-7@yGCIk1Lj2c=Ps~Hi?^6v#*yj(XUk5gmvH?ageReE`He=dSnU)s9$13O;Dp*Ns4 zJJM6?u+PhOa-+7B?R|5TQfdu4D|5;@MoFRvOX#TKSbKy3Kk?nAF+KQ!Ag_LpF28(H z-?~crIN@@*;sY01pseW-o+UYyzn6~^x;8-sGS1ctEIw-9e6SWT@E4=nV3&sW3@Rpg zAHjLt^AK2!7~PcK0f4|y^@GKD`_Zs|?-Ar24x`125h@D49Hr-A0D8uw&0jD}jk{{j zfEVkS{DUn^`MbMk$XZLhD1L06o!S{S=9&_IAcZp`2ZL54^HEwYwC#qrhSttp74`@SUYI>?@vx;bT+lS6epw zx$zmbMzX8m5$pEdsdy8e+Ixj?Q4p1)5tzjks3dw%7G6Uh<`L~4u2*b01wqQmu!2l$ zG&hKl8C9$PdP1|$2z+|LcR1liAP`TEmY5?4)OaRV53>;)T}|*r8y<12nC}64Y4UH; zte9zI9M0IBhoLvfikv_vpXKwPtv3!(eRBK&qbdx*31057vDOD>Q2beJq=Y^=qs@&X ze$04PsdC4@`_p)|$^{BCi5im< z6Y{4o`q;2!S%@&u!*8UATbt;R8i=u;90E@jqWIl%3ooxN;@?v*z09FSrR5F4$lPCD z`Zc_F0u}~aYpHoPr!KBCZ-=1A{U$k^dP8(A!^3`*G)zd|m4^|U>{H|>+1^YeqP zdU-|L&n+kvL-E`ClGek>t>4k-m9@mjkQ#5WhCAWqH-+Y8?j^20!o-!CL&pNT;SRr_ zrK6X#0L+uE*rBYYygU0)vQ4%Kmw5VjL!Fa$y!B!_)e>*+q3o0tmPK=m%Mut|#)zEv zTtaI4NkxYQphH(3pL9~5S=Hi{ixe<}nxm2T^7^LJ65yPT7(DApl)~IuFaJ)1y}b zLWAVgfos)mB}sA_c@uS@F}F<;YCGEFP-l7*QtZHF=g!uVLa-`3T8kgO_?~?x4(2S-;;Rl>F8Z;m77v{%i#wIjXq56{`ADfSI`;rHVmm-Q5N|UM)=ea&w(-7 zx$6R?cs?iVEvkb<&Fkxg-{W(AC4TGCY#8>T@9@>{0<2VFDn$u_2g88N@WGr9Mj;e4 z319Nw4V7JBY{D@Ubn$%5atU(LbkIGX@$N~yRg$x^5Hr6T6=3a^(Hk&wA@$BvlqRAZ z)Dd;7uxszdbvBOedR1xCR&^a9jP@u44KLfIa`2Cc3R5(7#B|&Vxsk`SOOFV42EX%p z&xk+{f>>K`8sv-el(lx&9Cvf~7d3Ix(V=ETHKE>@p7rl6=L?AIBOtb58I?0@sC=Z< z!HFER*U=4DF4w7K!P#JsU@Uj`azsc1^noJfvs?Ud7I$@D6s6ok=-2ie zZkU$T`x`Zj0*u;8wV2LD^m`;s#EpH|1eH>ZZi&GAOsX@WS?M6bVINN&sC)n7f#K9$ zTGRTO+^_yA0Ouj!ql_Ie-9=m@<|q=l1}40E4w~v)R$G)l?;Hu>5*aG2tlmzZ+=wK? zmez-r^0Ck5Mkf6wN#~8hv>HpUe0LgpgEZeXhofbCtbtjlINi0D`g$gp&diLL+LfmH zt6%X3jjY@GWTj2(S@W^?3#Z>YZ&*IM=r`PN;$@T_A|7S3eaf@4p`iJeUZ8ZKCCmnw zWAky_l6d&zR8L&)z4l1v7Pvg@wp^g<_M9R7DMz`hX1Awd zy4-~~ZFyAPPJ6SQH4h_!@6#}Xd=k_YW+oYgya7*1+T zw}Kc&Gq6CI-G8aGJKraGJ#r9M-}#6KAu5=bcvLQ={t-C#E2Dp`KKva9V2B0&6d$5> zdo!)If9cPN;JWGTlp>0w{agPHWoMfhRahH}>De@xa-<}xSX4iT7}8OD*i18D{mG--u3xD4#oyCKp2D(|!}k{X9`1ceNXd^9U@ zQA(_(C8pTgYK_L0&~SZ*gEc}o!)!iB|cidz8C8w>a8-h>^JB_X8A;-ujduv z6^uu>)6PhF5+Fu}xA`&kVjw#+(1~f1)^e29*Kl#87JU^f2$xv5KUl34dR~1kFL?EJ zCj(q{n8AKLq(%a+wq0;QJ{pmS1y1;jn--9Jf+#t)ykn?r~bL3(2C-Te~ zN0q59WlLMl&SuLY)>4oob7W%cm(7$(FL5e_xuG}7Y_|~nk@+92TWrl@J|A;B?TP&} zslhegvv;jRintpRD5Ve=Z3)t-FF+ow_8Xmks@$3Pj8YHg)32m^f`*81t`D)EzF4tx z(xqsFL^ZdPQ#krUKSifCstrO0u0te6ur)O$1hR1H@w|7Z9OE)WmU)Zpvl``OOS}s~+BN_#e%x@&7eyRA+h;Bh_Y<%i>L(pqKZj2AX zMLo*-KV?C!oITJxc-s<6$$_ox6-Zp&YLq13S*^B9~5;C49b&`ss{b zdr(EtH=ghny}jPF79kOo83_w*dL`}GcJ7%>6#4?0ijCaC;V{# zkda##cVf5lfsx;+Rdt1AZZSE;PZ+6SwZ;KOCs`_uj-uBKEztt@ zyhBv3hMeTGieCIS=I<;;E*UH-%WIbANB$IxVoZfc4FVw6mkv50{Fp1z~T+J!`~ERzaOT@R()S3z9=_* zJc%{@4{h|{X`qSgs}&fF6s3=p^_=crySOm9XF2s|b8sA~DuT+I7q>3rB{366%G*}G zA2yrcW0G~2x3PTg%5kAoL#;0@!{#>fH>V0eB@S|ApA8uSwG2-Svkv;Wf=u?#S~eyK zfnHe=jZd1{Tv^K8Wpb9SL>%RV146{ME)P-@ib9=>gdm@Ex#N!yoeAeBeh6$BAhNg| z@RbMLqo%_PJCP2nL!^eVrQap-SuCe=IV@0?rizKw&g9#)eewEI6|L%STNFqPsSew7S*wMMwy z!r#yDs*9(U2$UZ9HoFAyy0J-3RLIxG;4*D4a#0<5CpLSuNwHI8ftKp~D z@q~}58N4|`8}8y8IIdje+*3J0^Ly{SBok3{2wz5k>1zZsP2-PiMXaKtq6*s|c@S`g zIg#8CFXV;l8sf)*!KO)`xCaU%U$sFUS6X4x5=y=I$>5Gss~NIj1f!fty_j+$kxpLR z42_2KdTIXRVA>aH+Yh#cuG9B5rJ@|q z=OSZb8h0*0${t8hY9V><+q+Odco0aMuly6J@j#zD=_5q*PP_8DG$|3+VA<#R4=%g3? zZUVWdE!-+{s^J*_aH!01;btAJHO>F&rjU}dc8yu_{fQ>dcP~5BHvX{M`lMVg4Qm-dD~H*Irs@#xpMqykWFYkJaOPPg;Y^#c z`H*nP&9331&VB2b9`{elIpj0Kq_VNW;PWA*(Yt~i2iJ)d_FhHao%Wu2VV%q@!W2>V z(%wkLszz1bOw#*!7Xy8C9-w+0Y-w$DUxMPJusTykK8hW2!== z*<_J)X|2w%R1jNXvrJ-4a1HU#7S>i^#F|7Jy4JD^^8)<;3?+-`XI-VQI>=FD*W>Wkj}PJo2xNVW3>u4l$_6f!0^ z-bC~VC}4T)^%U0D_%4d^)9dfJ0*KdNxQ74$O~Sb*8G?txaLaFOpTljejpa2706f}` zbaMkczXgb;c|3%2VR+cNEM2b3^|*s&I{0a)1b8zqp^Vy9F8$WG&hupOm07>{x&AF% ziyiwPQZ>{6{c5=XUz+%jL=Xncou1Z&J?r$)PA@JJvi_3!MOj4tFLZtDd9DD+(IPUh z4buF=@E4o-EF4_}#KgJR9R`M&KYqYPlOgi+bH^3ko=yn;M;SQzED_8-yS+p_Zbm&l zi$|Az`3j-A`SbVh4eM%3nCl0&$!qBsZe6RZoK`t=hzE0sRQ_n5J|lqK{ocO?h}PZD z@Bxnu!y6jH;owXKm$Q9K#}pLQ6mP%BC9~D_2Tp-;pwQ4)?;RXKsvHu6B8YKup(lT9 zAB`C7CIFhojSgM+u+YI@N_cMzq{BXsWx(s`q*(P7W+6z2!YQXQ%VmZr@tRN2WCImn z3+fu!7T58bURbRUQo#oVq{wUf&FB85n5;AXUk%Lv(V$< zzO$=izuMLYF4W==hkU*Kd*EAQ{#q_}Bh@uDAPl)_KVvAmnw-0;%sz*ODe=;XkO>A* zqM^YZ9)8G0Uur}gO+$3wXZ%k;Huu!JmXl44$puznLWd@^O;E zXD0Ka`E@bOAo+01-5s9r@-+1~3^?`Q}2ybO=`( zZrJeue$-5<{y$UQ{?DVf-is4>dkGA}+Z2q5LRxG<{!d3G9?>q2FnArx$h}^1PlSV5 z0_l}8gY!c@on%ost?^F}DnEC2D$$jQXJ%%e{U!a4bAFcef*25#Y2^@BSGl{e}u(<(FY*g`q8(S)}i1T z1!36m86t=k72FeFR3(r@F}aXpf7Yw(*P&T0;G<#BzOqtKM3jx?7tMU0b|b{UHOXk-Ur+#61qkFg ztiX|xb#=de#&{Oa2OxY!#pn8ZrLtub5dmMFz34EEExZqL3>wPvN=WJHn86{>G?fDo zit4|;hoY_@uslOEwy?19{x1*wK>i1vZx|3mLUs^EX_{zJxJ;V8G`L-=xDV;DGeuDy zKQZ*>f3UFsK=bIi;o*jM5$BrnI+4W+of`y!AnWQ4~jx0Yc zce+LwD5)MBurds8XxVs(P*pN@g4JlfQF{k__3XPoe6+w~8DVbtK+`htk8=Hwgq@p4 z$0YnGx!Bjp$QikL8WjeMrMM|ZR%Y2HNfRW23)wC2W2d^>xHV2jcJ{Xlmh25w(b92e zu!_u4GoV-T+CzLizAtRo!Od!?kaZAM7$Sf@NN4_OTTgIaf9vWO{VCyF2B5JHgUCFK zHDHeH-yK!=a1dwzv0GH0NPcARv?E3DK`xTlpky=Ag~3MZP2IIbSP|oKMn)LXrLO7w zA|^vYib6;30^ORi&`<>_Ez$1zbUB((Dj0EnYvV^j{_itfXJK^IJc1k!M!>c9<%~7W zp4RvjNoIwmFe5{Y?7#Y)n-+h2V_*!w$^PLrj{y!5gUDV&fXqm4+r1R;g}a~o6G1;1HFKW$# z@Ij1J zuDE68?C!TlgfyOXLFTPJTQjB_t=TQ9vubre@M9-4R7cefY$71x0!#gG3ZzZme=)Wv z%{4O;5E7UGS^OQL);%+fgD%aG%j^BNMUMF346LAgQBXknj7q&sDGk&!-D-H-$`PZq z)T;V}k}e>KblF;Sj^ZfDw^DFOQ=zS#{mPKEfign+uHf=lOSLL!&H!me+WVUyPw!E1=)jfYlxCyMAf^1Vx4kHtfVT8xEgMSoTf(WJ2yn;V4xwx*UzPq$M7#h&yoTX`LX zS_L?uhu)a#YiE+WfyY?hix3i(SG6=?O2*D!&a~0|VgCO{kR|oggTrG#%wZJ-P2Upp zuZ-yQ*}Pg7d;2F;j_&o56#6V|b*2W@wGtSg)2&Bw@?%5Yzm7*|RGKUM9SeWERNGv? zL-K6R^(nobnbcP>(fyL%hH%N|!vsE~Re3|rN<(QB^uV>Bm}pbVNn`QvF6%>XQeLty zx?$ouzuO}*++M~#j2B!5CS)nzmwoUihK6MgxFZ~lQc_>BO%z3$XC#yVN1!D$`B_mN*_f{Itw-WqdIp2i=Q^rZ~5!k+3qKD{V8rd1?RvjB{GtS zO6n+yM}mRa$_KdyrME5$ql-lDuObCx)*)PCGuUI5eAO$(Er#`~Wy+|k)XGU=cfmBs27(#JOleK+6MXVJ>OEpQ?wV<)nA7m6IY3 z{oogoXUd^+k43lt+#dVGqe*yy`4?q|^|cOAlo~ik9l`m9b;Av&mRzexAI4sBnM*CT6} z)Tluo_|qh8?$Kn6CM32e}ecgZbpBd z#z>gAa9%|ifnmmxnWKdkTjeDYn+xC|=>RsQ}4T>Rne6`}z%zjfG+XI9+jA zol1`YwotAGXGl@`K=!)=@YW1Z9rVB|&ZOa&mXVi%HCcP+bn6>RI!!n5C2H8&rQ z(MtLHwkd6)X53H~RR9tKA}|Q0zhCnDxU0pTJI6bGaEgXzeEl4Y;dH82fkacFoznBc zeSOIhD0N9to&i{Y*H+I?yL4)`lGs}~4Yw}lr%&CKqf_p^eP-G7e`@@rC@zULn(@uu z2!K|*62;>PfnEvD*Y|m=9{CEMiK%NVmJC6!fYs;)xdgW8lc;GPH7@O}5IgqXa`S#* zfm!e8INHF0XkZY!#68@_2@bCf9f1;VH{JyI&tAl;j<$1`>MbIcr&?w*dl7f=x7e5% z?rtO~=DH#W34(ID{xARwkX`IxWIBwWVj5)i=4#fUiy>8XxadO=%2P4+ougNQPO^e-+g=Eo1D$6H5#p^m5wLxzDLyt(Y`j?Db@ zGy&B%pbf6p!mQ_Qntl_myb8)dtiYPW?~_if?!0&3;S8`I9svNjLRG{JVI#fl-|g3* z`RzXhp;xw}M3LmNHGThXVa4?3Om>8yTm)shvhpZS1}_SiZCL!SZ2#G$pLl^U zCvxqU_)|!9XSr4pw!Qti(= zn~{dPerr^LvNNloUjE}`R~tT7EQ)}X#3a=Dr4c-=K5R9|z!9jsx=tWQ6%8Ipm)Rj7x~TF+{L zq$Bgbs>T|GMI)#O8l?U!DI?$i4Ew~a@J5Lnq>9njt(DjU^BK9Vs+;UkZBBqd1lb{S z;9vW^CofFi8Ovb?=hfmjE$&CiL`n3-0i_b!hr+ZB_7};RSF#w z$ueF2s$q3JuG9Ya#a^|ezGsU&%V>Eh9)P#r2+N1u>$5Fb2nQ|05q}v10O~OimFwg7 zmIdii1bvZK{PwpNGTToFzUADQZp-sVh`l&maJ7E+O+lYmf}W>mZWhvRbsP2;n{1{a zWe$;aQS`n+#Jel4=UknWre5QPTQi>4>s4ZUlnHcK*-+TqHZi4xwv?36`{M{w@3wmZv~$m?GMxy+V}(d(AEQ<5L0>M zBItcD37rNhLIo01XoJ*g80m~hD}ZEuS6@Xxxx}N>za&B&7e(}a68lvGQks7KroSqK zfB}p|(0A}i#0p301)xu+MgYEhC%HB7?0|6`&%m``0weLfc=5UO5uvB|nO;Idx})B#n)30kF}GeiOlvrzuSB^X4c#+Ty$Z7|8HwSecWXV;H+pUcaY zc&TZ6aGUm~i*25LBC6?JWqn2`Fp=#!WiwR(pC=2?ray#40LYd_qHAlfM^61uZ#@#x z>BF^kX*{8jBrOcy2zQ(LU$_@Ma&@Wru%})e?ru!AhFm_wB=+ZiR%acp;b4-|5&XnG z5HkzPfuw5hj=`_AB8qtrA@MxIP>K1KVx9-aq}2ny-Fx`i)_bRO%WOxJXO~QVI^8I- zKM45uT3kOd`pOC);I#2SyF0CimGr9BLa4>y=iAFaIa|{pG}&-%jx0azddcrMnVp@~ zXcjSO@mLfu?3U=C8#MBA>DO}_i}S6hR5K9cvvMhM%_}xvh;_>K~ zn3QE~a17zEmkk`@v;3K#=YcID(+B%zhwQnHXyy^KHu~oe^j-hubn(=pE1^z=3Qx4O?Rjx@{C9e)sNwl~zDM+bA%Py(xIj!hqd5Y7|suFXF^4jvNx=ta~~lZ1-e=zB%dYL@$gGH&OVl zoFhRIo_j1~;L%SGm&A+oc9VuKBcdnH0#APYo%A-;>2Lur=4OwPT-fvF^M)YdHO}DG ziL{a(=2$*tDF4IOX&mQ0Y?lxbIq;B%>w{Ei;-%LGybb(VNIBIHL#Ts45E6-;EBH?pC zvxM^Ojk&^Aa%DcQ=T7aFa$dE%@BJnZg{9>=9b_*}*vhMNj{VJcns-_U2D>ibRk!Bj z9t2Y`b@g7ZmyMD7wRo8>EGrLp;nGT)=>523*=El_>n^>L{B49vtpTRB)CTH7KXH-uR z!Zypn!TO<#wfpWUqC+#X)h|i<_VT$!*Y+Zv906|~cd>`34ImL6NvU%iu(q^HX zRnp-;Hb-=G`NvmvKS3?)RmJ1bEyFEzknR>6lb%`TLH5w%;dU5_r;lvg*mnZAY`UZh z*K?10y>ad5iKA4lWhh+XtIcTN|3Q&$o_8yMC=wHzC=8YD#v=QG04@LP*x`pvJxXe} z>R_A&YPG)((jnXB5aU(v=@Qvy?DKik%~T%O)^8nX-!l5mL%E+7FaQBYZU4=l;!EbG zOPu}hui5J!Rgrf@5;9F&Iq>$-8~fPJ=q$>fTWMqB)kV@)ezv#T50COoRix407g9;D z6@TJ1zP(xH^c6fp-gbC+;mUKjK7&V*02=OU$heD3+SvJR4s@F#vG+Y%|H)ct8L%$;zZu}I03 zL@$|aX(V~Ty1ZhQQXL(EBg0fpdoE-Pvvg!*eJ_BS`~3>_!C!k?84# z+FMP_(m;*}qqP0wo^5(OQOIKJC%2w_pGH zhxMC9+pa;Xk^ii7I>uawwuy&emH%$#i&iBGzB(PQW82N+qeKRY&U@B%eG`%9JZWX~ zJcPz2L#J(T)|MHnPM;^__shsb?QZ#ZjdHQC#H-w#q@4~-b?J@=4waca?L1MVjxTt{ zbst$@*$?&1A3x5wz&HevF1wopo@BnS`r$54qjZw9zTJUh5ub0f4C!4`YYVRVas8_E zzx+QKJIlDJ*6;1p-AH$Xba$6Zi6GsmG(&gi08#=XB`KgtcMn}s(%oG{H$2;O)bsnl zd-iKSGqd-;*L|;bt?#vXm#*d*n)aIS`@u=s!84JYCA>(hVV~fX))>f%EGF~~m9|{> zE>5E#x0C)^sPVnR_FOZCZRu9?7Zg4UNh}0JSXfw|Q50Ou+4`}ONZ>&{M?jOKHoNmU z4NPu*6hMe&RQXBh5dr3^%HJ8^>4#IHHKEp1OQC~9GViuTKU`lY*1HBbjaFdx#K4~K zkp-!2f&=0$&rfD7USsn`z~opOGJav|G6#gXXB@|J!=J@*)|o)N@~q{!bOGmkm}{G0 zU&Tb(r52vHkSh<9JuRRa2^>rw^sm^otAc*MKuA@HhC8fR1k#U-YBkBEU+?Go!F#!W z3wS?f;+;;$Ue6gnscRzqNJq6@DzR&=NBvuOYdUA4*5ObEYaDOA)HHxotQE1Gou@)} zlh2h6|2SQ44L`dyf!iaH864{?5V<=cYu%1mS1-~w)JG6aDj2}-RAx7&j(|AXmVm9? zGc_RDIZDxkGcA=OD2^)OdLRD;7jZZYbLGe?R5pSE`XefIu~_(|X0Usx;c{hWPXDP* zPS0^Ju8=Xry>NbeOY{~3*Tr1p zt_T$9QVCX%Nm2(sqAp?2r`T_q`0bqz~t$kQaT@@ZII6*XFiJKs%8Md$n-fqfIC$=xTy_QrFG|HHkp(T!m~aL!u6+#3Nlj-43Jc&lwr)Y+Xll z!jQf`>3bEWjm0VGT)zm*0KuO5SGF-dU3Y&fcOlk2V315CT4YjgJ6236>a%EJ@M=5# zla2houfI=v!I;_0EiZH>KKn_u3=#Lh*rE(&zQMLJsti$gg}MCm37DS~c+xEFYS%c1 z;^=%T$cm;Xvc%iBO z>NYd!)5Ed0kdq0EJ;||H&ZJN9O)%4HZ%o(K-4^>Zao;EYgSU9CL${R965g;HEmsuk zsESkB+)^(i-axUVrCoT;hmz2Jnu&K!_B41CV7S6%6$Rx-<*VO zn4AI=WY+khcBuITZRAxG_sDzqMeZh!R(bRk6B+x%FSSDvLs^5kpdozFjWf%^-T=b! zh0yW43eJ|gZ?!`yXT~0T^M9+h&x&@F7($LRKuL45S>6-S6$NBFKps`0*J8l5D1<8Xi!;Ug+@$p0W;E_{TmXR1hfWz=M(iAgo8N^< z@sIGmvqausXvRKo6j11Fb7q!kA#04?;XdpjDz~~Ick%Z?5nBleQ-NDCu?x&gKz3a3 z#hq?!T+ytcRH`NKDjJTFoy(7gX70Xvj*#khB!Cd(|Q!RsU05gH-lfbe|sG^ z)xP9idM%ZJ;?~s(gDv@;{TV(P0H46r&O5yg%n!rFgr#wwEQX)0nGh&NAqJZyR93D; zzuTl|ggZP8$OwCAlSAjgmAXD1{)U`-cbB#Q1K1nYwP{Os*5k~gA5V_;=$K^4cTiNlRGw(RG z72~R)dC+knl?|Kd*!3Sa8wbA(vC|7QewYq<$fbnDz2y91>Plt3$2Ff`~|>H}#1Y zPLWmzdNwu-$B9k^*VhNRI^Klm^nb*ZQ-DiggsrLJ8ATW+-9EF*(kNg>=WD*A#UTeu zbdMu(*^w+y=U=raPeedSZEcN7O0WCq>@$S?AGok|xMjDyMZmL>(;fWG4pfrG;6?wX zvOztt9RY0KKk}8CBntKvVIrO!bYsCClRdu*(8uBx@fm??xjP2Y?^-_QQ+yJl&j~7* z>o=fu{eC+KvKdw^Uj#M36{-Pbq2IFTuV+ZAWe{S9u5`}s_{bt?1EeLeRS3_FyfKM+ z74#hxtJ+z7T~r4Iz|=49Z+>aHT+#^d<%*JrCDwACyTJj`%=+xN`Oqn2$b$O-F0UNa zvIi?mjS2_~b=)#5{E^a3Kn_bB4TOJf(|k_#SC4fxM^1exBDUm-4rE-LR@B(I+Ma*? zw<&qW>6-nQW|_kMEwTf9<3Bu5PU`FLJ>QJ|+hseBy30h5I`KJu!p?r!3djFjciO)J zy2T*j?dbkkHV%Cy^6%e$ zTlnYGHumw~CsVaji9URa4owrJDYG}Mawz-wduQHO=$68NP4x@UfGw-|fGU?%9-tj{ zs8i;{`ynBroY#vp)ytFh_le??TXZ3%@!XWsC8ZCn)DrMMoo)Rc(`pk3yu39snL=6)p^P3u%0X0+3v@hKYA zek-#Tnvo1D*Mq^xfeVc)*gdiE7Q=AJSicxMhZA~-8@@6NwT-a>ETFhf;ho(ikaen{ znNG~)6wLcrR>p-fB?Is~%d>-0`^m1mz45!|rf=c(ZNgIieZ>#xzfiWPE^TS4sZS+e z8#>*gk_)vUd-I~>kdC9BD`A<~NRz#{og>kj(TA?8NoJdF9e?^+M3$p^Afw~*#LKM( z-W2zCq^bm6fFinwf}NC3;2oKdsH&W|J9@e>Rq$(lqU@#RzA}+ULhckV1b(uR`NB-c z`D{@n0Z_1Kt3((-%i-0@SCT@F^q>qyLD~fxV)pO&j#{A5#A!^ZwIh*F(uSSn=NQN4 zo8?N7BqZZ9rtKR86(n~p*HR}>5i4>;pqIk=GGy%#tCrac_lmEZr1X40C~>T@d?gQG z;R0mCBf}J=Lx$B!%h~#jLK~Fb^_ZA$uQNrVawl$TVV*Og<|e@9FHvR|3WV2n^HaoE z-+26AC$sDEieJC$-v$c(POQc;}{WKQ23`Ydtc zpcek{kVhImzCc3a-y}5y%j4E=c`X*G=T@f)=5X+6@s;ZwV1>M%)SYXkm?$`Mm%TxS zuEow?MzqT;XNLzY`Hfv=3=nipuAP7~V;XeWgs)Tm zf-&xY&>{nVF46T~u#Mcj6`Rlh+AyA%C&V^)CW?gNjmqH23I$zJ zZfC%+y!wDD_^3b9Glw_kPSGyD=m;*Oia9j;s8j9C5VmyA=JP#LJ#T&*^l&LICycZP z?bA`FIOS{FKR7;~I$9g@?lIevH123VfXVx^y}WlA7Ifxug;b+>t01A%=#P)*%;q@E zPM58w(tc;`*AYA{fsC#1I`Nc257d0JAda&t#JJ+mkkTQ>L^bAQeP<=woc9Ch!Kaf~H3oQj$_ zgCgI^9;~RS@T=%fFR*l#=C?@B*6|0AJQTiY(zht|*2h1UAZI&Hofx?5X}riDH&(v{ zlUU9c7)BL9p?pF>0vBlPk6C5Qf)BF)OWXjtVt?CVnW2#DQ_M+Bw&k696pGyq)9%TH zPt(N|iw2FjM+>LSF}9fz2uF=Lw(eMpJn2xAEqid(5_Yo+Wy`~<`2P+3 zNWOS1j%UyaVY%nB4GLfLx0^G>;Gg7ip z-6SoU4e&IiUX#L&TpS*o2pQn7a%C&M%CsK{OKew%T4Vd*#+6A?9>TFz&OK=8*!)Z4moL5Zp$cC>_^A{h5(v{H4 zZ3h+0Z2Tli-%xeO)alSC>(DS~@qRbghSZ+lqZDs}b#1n2>Q2pt8q5xXc2KxqZkg+t z*^>srp5@7N2O4ftR#kF&FMC40TbGWw7WZ7{131Em6ZAvRP5E)|QOKLEa*w-uez-o8 znZmuD_orWHp1m0E9x(UHQQSk)Cb$z$``&Rx7Mo*{hGcD%f1$FM-BMdr@k0q+oIC*> zlw;;%`6@P$vEe~(kGhzBqU7~nF)M?f{X(I1i#2c-{@a{YKk((tkfaEdWs1q2?trhq z-cpCLZ~=|sU$byKT-rp5)M#06E%vObW_i9;GI;jB^Wl@jc+nJ6F+3^tp$reH=WSbC zKC#WEt>Q4py-D`4g3PMb_$esjLps76qD069JB(ZZ$<*h_u%ck920mK^r9^7pbD<&q zo3T#5XJ*GI8r29ac-_~8-$bTw}ch*-SN#vadHXRWU$U-?v7fvW+>d8ww3=6e8Q zG1;kEV`k&%-qzQrgUn%4q)o^hN#nLW*a)gJ z8L?fk&&nH+h_Ug#skjmG1g2}r@+BDj^e;27eh`@d$a5@E|C3M-;5x4C7I1$UIupB! zr$d(^ZYcKKp$e`G03RivPZ^`CDT-@?#i!Asj70B@!KtY&I&G#|`IWu%g|A zh~>7aFB@TR^U*%46EY<2z=t14OZzkOKY%6wX@BqJTJi)k_vtWK73dX_+R_4IG1)C- zVTN*2EBSIG2S6BKC~)|QXPCaVlK7!%U=VbmIBc?#pIg_c%_S4G+dk7qSR*jIM9H*h z&m=+$BG`scbJ~-YbNTW&R*5ZtGPh=-96i<$WU|diEZUK+juqI;#$_UZXJapI=r~yY zfVYpP2C1q~JKmJ7&2mPU3?pBnm=5Je+`IC-X8My^Q#u=hVi?sQ^|Ssc=4x z2Ox%_SpzurlD+$w3{oJb}6CR zx&Hc+bPh#q!x9g=MZ_Qa-Y8=|*iy|R9Itm<`#u2(j;*i@DX2;BnJVstRt-i0k9~R`$R=M2K!WpTsJ=OI>n`?M6FqTaHQT9JER&R z3_KSrsgu`ydm;DvHC4UM#59?kz@{h`)Bn7~)qHHejSZqz%Y8(0F;7bG*vzibGg}Na zyGYz-{q~M7qaoL~o%*|YV->jG928c%^}DU`B1kz_QW@5mTuG_t!$vNade|AMw{5Rv zx7Ot3^!`d^^HqWQIjeYgjkol)s~>Rvo}#)5XjwBY1vl~sN3Bgr(k91!m(}qQYg)({ z*HXS0LCA3wcNadN{Zx5F4FsBOk%9zID7et;Z*0xG1m+v~(h%AT1!-)JIr7jDu#|g>El%4||KI2F z1u~8*{=7R^bl}^BLyLMb^4#uvE&8(^Y2iJoA^Y*PA;3~LG=ayS6VF$B=_y!Mi}JwA z_q&Di9ft;IL<6tq8|B{v`te#yV?I>*uHmBWhFCuVM$N@m5Bnf!_Z!7K<6=C9tr|*+ z=nn1(%ThM&v%Yaa>=ZHzml_@}!Un)Fd0)BMdtO|1*Z*p(VWd<5a9v6J;$1FE3oAZ5 zu9)c-jWgd%2C%gy4Tu`*j@&@F7T1{UjyAO16zT=klBMsL8Y|_z6^+ULTw#|(=RljY z`*-s`&P3+|!R;M058w1}o;)EmpBojrt7d@1#;}dL zS+w6x+u64(Z2=V&#piNLY5F|%na_Ax8dLe}wk7_%?Fc}U4PmDd#&>T$M&`(~Sc?~( zUHjT7($Tl5g$bu?u#xbls~_7|%mM9JET}PJgtR8Jk|%EH>FV|imvD|sYIe4J6R(E;R#uKtq$r1F2#gZ@*>#ugzQH&~Vky|B@he z*>EadT?_zPiNu>6LerXslW=qpqc6%AR$QHwzSa+(R3g#!e5Mgr21Q60ON->b*Q4t# zy;#!OSSO&~^bwiQ*vEM}0BW&Z>rkdnw^B`f;o99!s9-8)$lOi3Mk9ADFpbg8PT;5@`|*NAG*dBBda33M%q_+Z&?(O_bmox(mu@eJ!jb1_0;dtx1%; zH=8+Sg}+WK?v;`u0K80gUhr@c_5zmK(#zPJ->k~0|CGPTNFspc4u-3mKHTK?juK@7 zSha{iQGo=b1;~bdtHF_he$PQ@vuXC*Z`~BU?RBe$lzMW4KG71@a_x=%oxOOZ<+-7Y z)k-W7x{w)Z@9>%W(E6*bPDy4CmX9peQPZl&lfsJLWGOPgm0Op4z~aOrX?)hruJ|q4 zvaRYJ2qS-J1_30Nn^fF+}T{X10 z1&7nsgYew&KCpHPcF_YKsx2`EH&cHtgy${oOa9UYNmb5;{l7NnV67#d^mo9zMAvZ# zXnRQoWF+=!!UX3BFP6=9QTEsjznmJ7i@1K{6BlH_<+SraB&_%J_}cY|^KvyO&jJnr zG=znn=$@8)3&v#tH>=CQ{tfUbjFzWR0c2%gB5Pt2gHaEY;%^uLTw(xxVX7DjF+Um# z=4-{vjD_H`kcI8JLaJ0Rfzaxtq|}n#B`Td-)fmfVfPWyiQtxYO@S#{-IN|u<{NY&P zNN}XLIX*oHN4m6j5iV6A33X%MlL;XAYI@*KPhj-*A+Kc9)er(ZsZY8L_Bf8`Tem@I2g~`dKtxN+TVfMJ!+pc0#bFeEasIhydk)mWL?+R_ z3pVWK1n$wmo3=MGJ>xwU)?I)GNdZ)*mT2U=Dz9+$?u)apD04LgX#$|`m<4YKfx*r- zx8Lhc?vZASe+4ZBa5}ifd=;!L+;??7GAtDD z1UKyJi^blo-~Uy6b9$EQ_-7g~*H!`5@kDZ_`D9S_NG1AjD1^2F)nH00p|+N&iK4jt zEIj4Y{jv5lee=*Colkrkw^;e1&c$Cg@>hE9C247e;f6yc!UZJk))QGTJ8Gl2OuN~B z+(Yh1bCg$;H_jN^YAcg35%GV+ak4!v~mS}aD!adi>&dvN5gP)au$3Yn+hHGbA6bd-Lx) z&A3A?2P>AWf6=)6@Lw)0O%E!6YwK@!E|_PBnB%3`<3&vPPnjrfZZFp1_9-XekGce8 zSew(*&DxWV;fBTN6rU!)P7G(U8=`Z+HumW9MM?Ft_9=dBa19e|;OFOg%y5Ux^nv5E z3aae6G;@~|OV3zP?k& zM`jzV)6L{s{UA5zPI)=s@7R=$ZfV(Ot2+jUIb=E{qlfj|=0Nbg7Fv{mJB}A2b$%X( zhzRh%#?t}hT0mtbuwPX@{M>=z(ALyWQRgH#FxR_^_d()?J{QO@4H>5U(VpdO2|F$zig zLSVFej7Q36Y3{Q4V!>Y$I;o!oC`#y^(*=l$L!?!sku@Y!M(tb(PDSy2Z>U;1itMS$2^O`?|g^=ggYKq$O z360p-F*b-%`G6mg=&JD&I0BQsTi)N;pPR018u{S6qIzO4%=5Sd9i^RvDCqJPpHQ4cAhc)$i_+4z63;tl5>aLBZa4JFJ z!N`nZsv)HboGsJ$h%p7^it5kf)4d{4co??m*XG2RXpM+si5gqMjGy;||LoD*dJRDG z5tN)uWVHPNmu{QRWpl)K&fQSKo+cN^!Xk<)Np(k}&Z7Ql+zv0OIe0_!&)(LcW!=IH z-O5D1y9;+sLl{LI;eSHWk31K`MJ zFF;@HiVBRU+ju7bTov-3ktnX-jf7G6GHjS?;P~8*5==Ucn&47AA}}gfuw?9uD0W{( zK5DWcvV40K$YJD8%I{a)2N6@{>JJud zK1~6(;8bqgPo|AO5PQMf`F}HC_0z!ozJx&a+<=jnfY4@XM+YbN%2A!h$=Ny1SO-o~ zQE_^9mRgtzHS^#O!;!?X@N$jnncp4kxnupWjk5N=gEKr2&pH_CatXWXoN%P-t1`19 zLaK~RfQajxAY6tQZly+;fPvb>vri6RP8SSGM|m+b3m~c$m6(BF6{54=#3}QwrGWyz zCXbAYam)oQk8URo3XwFWoWPpTk6>#z>BMfE0>s7)0^5^0LSZ&X~+(_?? zE@SHPW*VeDbe8fheNGzT9~(p$Ccfp1_rhUITMuBdr5MY(5!|AO8L(e2C9pNILnphn zVrP;Rk-YUMIeYB2Ick{? zg?oviV_W82J4-C9ubn-LFKvkZdkMwK&N|7+mLQ|(iW`D|61hUgd9J{G5lRjR1zHN;Q|JKbPue+J?bd;i zDz;Y(xqtK~A8N?eskGocxiyfwEGa%VyX>=$>yx=wgE~MV9S4*Oh5m)4wvoy)nqz-{ z!S-we5QPBG00k|gCP>`i-4|d&mg8lii*_2g+oRiNanErw<;!-CV`6iw)ohw7uPNld z$o-`W_!oM4e!h{dd+Owsl3%tJ_#1_f80rfrjKAUYs zl(fG?D2TD^LC3luq2*{?y<3g8f7>lir@G=fr@!pRL0}BJLt$#y%CcNqe6htZs=0yb z`e&CCr1{^84?CnD51xRJKI>Ocyq&c)Ydsh{E-@jb-s0n0p+4p3%X;(!w!J=*eiCjt zoeH@a11H#-PoG=hp*AikHd4-de) z#I?NLATn8&Iz2@Ll224rsUod_;9zAw8H5g6T8z_%x?VY6Min@}M+(cIa*Q~*uh;*_ zvakJrqE+Vc;o0>T_MO8rvK+nqa(&4#O`bhCT?bWAFqb{{Lq!6Y@2$%^!Ny7o$8eUe z$=0{(R}GJT%f+?I$f=!2Y3NXJ5A5Y3Vk$rH4^WKd1jFRm6j51ue1yXK25dwG5JmwR z0RCYlJdtsarvirb@Q@6=MeHY43E1Sof@^%Q)Y?#=Ty zzpQ>K*v$Rvai_}44k!t`eFhK(u?j&uQs{E9)Jq`jSH@YWpQ3FqQv8Et0v>kn3mC&j zI7&*M(f1GcfisoW#pt*TReyyp>jV8Qo-+~;LFjwZH>vZ!71z`WNQ*Ix9_2kzP{)(D zH1QMM6mph=-!m?7M<>1|1?HbMxir-us~C(htZsbf{IyPnH+DURy;ef)IjMyPNi_sj z_D@-fnWKe}D%Z0_JCdLuSLAlLFrCZI#>TcjZqp-kT^eIf@gAKdyr#wO zcxcnzfp#M#UC%jHM1)#|5oyjZC5FJJmPS;T<)cmO^`8)$*lj>g{pmEuWqym1x1LW- znS6?(2`|O}yvjCp#0oA*EC>o5{WwW@UuwR8V=46!$CPYwzz!3;r1^LNmI`j^Sb4|v zHw|5&F450=e%6r)L>=hTFN!zC0{SX8d8A5JL%4d=Q^@1jLT~HoL(UBMjluuQ^wQuJ zTY-`OP_%u|;x@vYckj%mjF)mtL6jAz8*+c&M5ik%UsB=|I^kc(e|qp*U%W^59(~n` zH4CGG1o68`iRoFb&qgyZ`zo5rcTJq8h?Y&>#_D>v$h+)5e?mk=lHXWQ^3gwf0^K&K zm7S`!&2^3Sv{5U8W9id)e194_-P}Uc1G4B`BxLw$()x zNWu%8l)&lFYtfI(d)P{Kbs#A0RF6LM{F5J)waSV-(tGbBy!i`znH`zKlp(M+IF&d7 zO~%SVZHXV?n6 zfK3*jW*%Axz)YrStrZz;YMG8T4QASAV-K7x4r~j?js!%PbROjpa;-F~5lt|DkNHdbp7$(23)Xr8E*_7>&TNr3T{sym=G#Ip z$SEoeOZ3x~ned)|!YRUP=9k4Aa8u*z4Ck6%K3~Oc-nKNE;gM}s7K8}=2~2-|OypFa z<8D?eTE&>xs$n?n0y7o%!7?Gtu3HkQNX2XNdkg2)ArI&X}j!!fzNoZ}<0 zKV55VdmQV8=T;`;6v}F=KYsmy!gDZ({GI|`IRgzqXaIHNZ-g0A@dId`^t*hldJ-aN z4{~hw<#M*=e2%!pgFV3+Q5wh0N=B)Fo21fXd;82V?J5K}UCb4wcF_;H8-przM)E#} zNntU_$Xz@l8rl4%PX6h^Jo;!|r3QXg{hIWC?3A?o1%1A_FBLFL*>u+3pGKG+-t!u9 z8hWhbQ~rQ()}Zq;sn8552jKf)sj~_Qar-(Yj5%VH_;(`UH@HjcaC@M;b{KqmLo)Efj5*rw{}D$;lux~^@8*Rd&bJoGI&yv^^VCwipApK z(X)@DBNd+1{X z^3!b+Kw?Cu!e&a*3-h2`o-&3%n1vN}Cxuhh()#c0Id@)wQ&HH+?3n{Kg>Do*c5RA> zuS^tTMJiDhIlBZGCo!yIg_(BbpM#^-6iibV+sOp20-|j`nvQixPgA9!_}UB5UVu8o zT#IlMQc?BEY`{n|n5hDtftWVszS_hwats3?o8*-Eu)48=I8cf9>C^uHK}8)oF~B~) zdcmRc##(rxfkcmIFbz2*3~n%O0QJuyHl+;&pY3R+JM+Hn{!7k6eo_zNw#7j**mJVB z<|?ZXzVKqAIb>QKso_+c4-qSCnF=o{+^axD7_2t#Rdx$#3@JUwJ+0y6kPqQ$xhvk0 zG}vm8ufL#!kyt7}qW}m;^N2U(CEw+xOoIJo+giKPU4tdbZn&Fl z?u{$%bOmPm0r^Oiqb$Oe7o^@Eo$vb|rVXq2yq6L(SU@)BVrYB3f?JhJGRQxfQz7hv zXfcI>asyp5BZNI%)!bn!-@&yaL8BknmmBy|26Zs+sj#P6PKAY87<6yV!hYYai*q^f zpGXTw>eaq^h(*2cSC)txPed=A<3qTZc(T;jJJd1d57d}UR3Hf#bn^ZFW~&m-7ie5g z^w1x?5aI&dyRB>|FmIDFi|2hp$OO zKE$6yi9Ye6Iyl5d{CQK=z!aTo$jyB@SSTap_O>>#Iw_tO*OwR2nW3HdQVwOxf7HKk z;>4B>LqO{adQ2sH`~&*(3g~%_zW{~=#l^wg9r^EHrTtb7tiO;(>&QLu!t*|efD=0r zns`0Q-Fg_!*CsJ_n)Z!tjd;*y?GGXqKYtFJcHUt=$ZnF#4EFc)LifGFYA5oyQ?$2d z{K#=de1Gc(DVAkgh8#Z=JD-+&@9%>nGrJV#f7v|%g7Y$@^}AbTci9<%Kk})>>1z<9 zC)bIUu65D;C`f*5HWr_m5%^Ye2*SP~bKHGf>A)eb=GXYn=h%YS_B;E8;GnLKPVcx= zMFoa0uSy159dK;^$w6knD8Q?zc)N6zB-vz7QFN5Bk4{&+BA0}I8;pdIOIBQ39Ol>O{^a$*!|ie7RoTLZFR zk(Tt#rx)RZt;SK=hH#@LrWr2^jLARyk$#e(D64D~YtC9eIo>7Z;SF5t*--d%Usix{ zzoLGVIQ!4^HjVS!gALs2^z}$TY?bav(7PLkQh04#P2;_MmV6axo+S56mog)1leIa+>nFnzY5&%DEjVnb-#9wgZsWbR1Yt(p?v zW!&`bLF=Sms53(nn@myv4mxwY&2Nb^X%Ftvh>Zd-p&kB>=uu_wsEH`bS2B{ z-tP!`jP9x_l+)3h$#%?z(b3m|{A?$TzVpR2*3=<-Yd-ct*yAja2{&VkTty$db2&!9 z!~X7`_yj^XonQ|OIwEu!#O!FkjA<8@9O}7lTHOVPdhITdfn!Qs3dtN%fM$PSA+yQ3 zwaIACi>)HA{RQ;*q=?^jHLlMpI!1FL8fvgMQ(6+uKVCYW&_}9%hWW_xnrFB(*XPe> zlvH?3s3J%J$W0U4@wNM$Z!Esh?kLj^89fUO2g&k*exk%&RD{M`_C3Khwe%csZloDZ zTz_NI|HS0v4KP!Yku*L5-sg%2=v_&jZt|4p1g*mDi&Uc9W7%7#y+QOj#e|+uIXwlQ z>fc$5%ibq8kUpTDQ2l`KBjJwJa=Rn?<8B|_R+2C(Cnbe12=<| z{g0&r49r%^CpAgS425?z6(Wp_Vp{Yjb+78}YFJPN%&KwD29kZkeV>}$1qjJ?1DHg_ z0~=G982*;iuT`RvQ{9RUA`+X}cj(`Pz9Eql%(OyTA)Vp-}6 zCdA8dC<6axae<_md~XefLaACFP`zV&sI4E7_C?&_dSc|MSs3&)KBxL1{qkLuuc1DZ zB#P2C_6dhC7%CbI37Ti4&xn#;k605TC5if;?!zyBV1RLPxDb4m$mVLm%+cGuNU>LL zy=EjdaUAX(fhFmCEZ)AxK`omi$xVmdB_H}s(x0@UNoM`61+~Ztm#SP3jkYn$lO0?F zPXxsnIoj4T1gm2v2N4>|@EG#88FZ0rR#M@cEZ1fngp4Xkt7I|cd)-1=kw2l9R{xO! zQ#c;>Nzhv>TLL(}zinX8~c$rZk*e5g*-8^n1%SJ|V<=<%b1Ow^v?CI3*w zqFVEw8-f6Rn5I)zliByWLU@!BtwijK1Numixjs@Wix~5%8j8XxQ?A2CXD*Q{>%c1C zB8S-;iAd~+7}<~PBkf~o$XY|vkD z=IFK~2tH}TG&ID+^;8YFhX*O{FH%fbIl^nP8-^(Y{||{G^9O{Cbu%|1w(;ivbY-s0 zVdrTbQ1Gd$7sanEQ4p@MX4!}!xVu5wR7)jTO)|YjaADC8CYy2vRoi_5VTEG2Zk!FbV$9#K@*=Zo7E1dB5xn% zq@~J@($9%$w&?2FsHhASaSZ^qCjEMDYx=ce1%w%@8ip540+COod8;py;arbH z(Vms9C|n@xORuqH64blJd`-Qp?J zQ#74AoL{pKq~rue|L6`;q(>M{W!v-u_M%v$VG31w>c~py+vmEy%oTF|q2@YGZ$P?XPm^NteKFudZWs6k_d*xx6>|?pjPFC{s^(y~{@=yuu3 zOD!~Znh3(Y&S99CWcQd-KH9$qV=7{s$gi{H)qCXRxfn@Gu8T}BPvyCO@_dK;x%ogv zZ2DSVXv)UJ%5wwxSm^V-*6*~Fw%EEVma%P4JC+?+7{zW3h0;$&eRzVjOAE_#X-!Kf zzst6{;phSEoY&=`W_#yCe<6xvac$ zKIeGvcTR?JG%s~efsSs2P-7Xz7(MT}4KeZvoewm^Ji*P}i!=)EX%{ucR@EKvqH}i* zH%@Cov6@5pTHr=ET127nz5!cJ+yT8EJJi&;g3{RMmS+BxcNuRQ*RMnXU`nMkZU$F2 zO>!STs(=ocWe)vcqii*?fPTWjFvWOPHV z67te-W_e%U0_g3t7;VGnj<`;)R=u2jRCo1wyXG#@psqao1PADy^p9Cl^iiu(=2w1G zi9;E4?GrMwlF4k{WT2J^2T=>3mPc_u7aQ>0|oYC9!mV zH#<~S);qBjX%Fo`-|ji=`bebm+XbwT;a;s>%7dRzbkrJ&KgmmPt7s)M?buv!II%*( zW~F%ebc#QDI3N3C`rg6Xkrhsi55WN-+8*!V&-PhFT6iRYk>lm%VXAcpiRaosea;0e zu{h<(mtvwVYK!jq`Jb_dy|pHF07i+K!s8HIUQxXDGmN0TWs6;tnKXTG=Rrn^QU~uw zq6-N{hfEd&jUa2|m&x}fU4a|bMIbQ>bU zdBJ@wz!i%{c1hlovZlT*wog;l4(n6HK+!yRZ9ZJ_+QVxSZ~mv8*iBOChW}&C(x#pK zv#Bt!iYtW99LaPkG6~0K&(4V1UdxFYgn-*(#j0m-xNAUG_@A!Idwmh1Ki!3Wx=WVyQq>pehAK3k3&o~xn$Ap>Qv zLAuZ;De}Dt1=sa)d6`H#@mEZHS>UAG7`O(DIwKKcMMJNyZXM00ID``E*KUoImu;Oy zIMPK!`5!4E+sD}L6Adux1!i%d4kEUgVmfy2Z%sBV!+Y1ZM#kxoZQRpC!i$(V(&vL4 z4(z4-;}7Z%%C$#}RLtv$K6lL5pO&3MpXV`Vc6}r8cDR@~57)wh_pgB3kCun1oBDE0<*wRz_z9DCfX(T(( z*pJUqX054`iz$JW`4rF3V-!dHz+~44L`7|p!E8gO`OzEIrsEN8p=D6S^N3dJzCqIP zCbVPeL(*y2?e|PbEs-^L$dG*Bf`Qhh7V+gR!4<`$L`#Yo@Ijwc)e-P7#op=wwZUcwifwp ziIi28$@F+p9IHRZ!nnI*oX>?MWBW%kepZ1hCtKjG zzRcAnEUJwrvl1%WEZX9s6IU;GV|gGpDNT46*^F@avL(gg7e7h&tNr*ypN z@?{~-(L6$p9SuTMRwN=iGqW8N6Nt>?bi5kjcfjn?r(+8g-{TTLMCRb30|tbrOOC49@by?JqC0kQ)Y&Ixg>({v(M@EB;&6TB%pEr#^|{pe)obrQG$XYnz=V9kLH| zq@pseYZPi*>?0V$a>I#^-cJ{Q6ZgCjaKZ;IBBRfTWz{vWf=!J2Z@_OG zL`7k=YM>WiqZ;}v43f?#p1f&L_$bHG)+tHZ?H)hKwRo=8RK3IgJw`8j^@Eu(@}GnF z-0_~4aVn7x>5M$coiRFbO|WG?$iS!R)V!(b;w>9RIq~Ie$g=+dRU2)Eqh&f!$Byz9aI{vIS9J9*$NxgI2tzsB zW0C#jUb%g^q4^=Q4|nF zdheYi^j<|kYN(+XDTxq5q=Z01;4bw0_CDv_JMI|wjB$V5ar0}9jJ4*PbFQ~O&z$r9 zZ_tt41)#$Qh9)0=<+?Pr{P4_O&41DU{p>IItr%T;fV*}v9&&tD)U7_rT1&sMNntHt zEBB9${4cg^0{Hbn01A1dxc9fHW3qUh{8%Wd;U3N?!W;E@%JdlC8AYMp${E_w~mZ>hSyWWiB^durQ!L zKWj*>(2wY zX`!ylp!E~*6>Y=6{K+tl>)9!s|6RHSoZvd~h9ihX$&pD<0Yw3Jrm{8=PwiYpAYhL8lYee_}UMem^GsIPxI&93Jt1k_I z)?bqk7~0?ahT(?fX3_{_qh#a3%GoKcPPgn-^NwKi)0dRaD!m!<p4b&843|b@J0b_$#^ib#7^z zuQ{Qwx5&(xNNg~ZxA5gFlYYe1lAgU(C_U%fEi|1XYPxVowJPI>3Ep>(FtMSv{Y-sg zS)6MkOkQw9=66%4;=(i6B#aXpv|2M7G}zGFs(Y2GJ8@CdB-Cg?nlmWn=RMzbOo4?$*L|=R|*h|5OakEK#tRw_N>T`eW!@g3s7B@uHY;THJBeXW zw!NVcw$0&65rxwFlp5$OgtVVcXVQMLjk)H;^&d7D3WEj?5_n3}Gn>BNC!YD!S>6ws zYs`JU$dSU3=f0NhS4q3Y&mck(y`w%u`Xq%Hac*uqaj6x`0(4~<4n;0(D|Ff{r<)|7 zKOC-tox6<}5aQLmjSBitTfsnEcVUTN#A66w5h6bmI9q>yy5U@?(s2#G*d2X^AW^6; zPj3I%Sl8L<`y-o8!f{lhS@u}}Hs{luFaPw1Hw0(`NEAHiNsedIg z*U{uoUMJi@2ntB6Jwpb9`@BVJ2kD?QXSAA9uKj*ix^e&UlP5>{t$JW^asVT*)tb&4 zys>IGTG4I`-g#x#qRgVh5|^aHCmdhn6jxD^tChBqO+&-*^q8FCu^Oi{n(tN4QC~ko z#;d=jQP)hK>|79o!MpCTFVm%;3(eq$nTgE#Ay$I?K@C(cHXp;nD)6U)7e4@`SSuel zlLs<=?us=K;OCFdKxD`-|BbrOdH*NFyX+iXHjT3K2ppn=o7Q>y0dgmlw!GhKtOOHa z6uu^lad2c|;-+HE{_fx3@es*w5Q@Bj76I&zr$&%b)iLciYvs38BJ zXaE0m<$sf#TYZBptt%Nhp`3>06BSYJE8yju5~h-tnNF9|8~B>r|BXMna$5LAj@yhf zXIVATp(Bn_Et!~%%6wk@c$~Z?PKJd@e3szw{HsT^o;(bN=Q{t@L5O?t*v zd7ih&rxqLc%oYmw5rQU@DX-)evtjZ(%xjdYmUIb&Aj%FbG-XC=fdT>mihO_=jb z#j4rER_X!D!c+1vdv-t&y$qfiPjoXOk~}p1<^n8y=O<9E#xly!rlMSeBX>BYw_nM4 z?#R)S4)w7+HUa1(e5CGn9%gTs8Fq-aCo9QJM-A<$`11;>JsqkNF&lN<+bG804M-P# z9^^g8Rdm;#NdnzviI=lFv#+!jR?d}vU&X1Cj6?|6T(hT;32Yw34_Q~l z`jg=ekY^OFWEoJ@_=k|d=#}U$$ZZq)8TTZ?GTs|MKHvV{@BNHdbJ>qD zyh9W)RfNupM`3B9S8AnADA%rm%DEo#Iy?n+S`VU_wjks3fpzJXeNI$_f}s03iu7e% z=|%7WL!_b$UC=MT&vjNcHX>6m6~FSkr(zy-Mol~=U@zuZbEP1SLG&$tO%Md#65;TC z)Y{jfgV2_k^jB#6Po#TFMSGX^7r+Att~IEsD6Q|W<#v%lvsvLAp}ff98Gjs=$j^4@ zzr*BzPCHs)x4!a`WOexX_Df`?!;7%iT`%GWcT)VB4idK3@$7W*LRnVBcYAfd9YkM8 zq!UE9_wf9$i%~m~{uFj!A{QgpIVea2fAlgTlCXCEL=28O4!DP^Hf6jZD(=nk9R`=S zf?6J@RoY_npj;DjF#|2B+1^JAddu-NVDi=tzoHI+z`5f+hxTm7s}PTbcg%XlbtT4I zu&I7Qu@n(Jy1G~4nu?&U3}bhL-ppS2X1HOA*DJ2n{Ud?5p#~!9k zv7&qI@>2KO1NC};9C_esw~@$4CK;-XSm>;QV^o?g4*v-2*&G>az-B|SuA$yKOd@*p z2a@Nt77qoz$$=%MmL9na*F=!`VIf`iMqHyx;df$pc~csG5GAMQc*WLXDkPLKfVV#X z?y_W$>DSJ7Ol9`{Yh=2l!inRf>ERjd>)K`iI|%Y_BJ#6Q%c1*{bj?(UZCw*SC8r)a zy6hyQkMa%)r(mq=$@xvl{21gXZ&PHBTkTaq?h3wC-c5GmLMR8VWoP1aJvwePLhIME zU42qx6EF^(D>|{oG9ttY2p2erokPZeYwjxIXAW4@THwdKSCrx8pzoh7C5b;?y)(l0 zh{GZ@2Efn0CWh{IOO|pT&_GU$7y0ec-Kip58mEP7n-eb;>X487A|%w})SW$?awmi2MBypebSfehfP6 zA|mUDa&!2cg&ZcrA$~?+NMY{)+l6(WP{@&i*XLPy?qKn2n>(eBz4vb9Rkz&EDfKKJ zo;&t?Uh8?@-En;wDJ6tlirZJJm^QVhe3-U$#D*9SG>bnKw|NI$yoh}zRI`WC9Wlnw z=LA;6YN0hq5oP!JCS~tWnzH^Jux4vCzqk?t89x3NZOHYdP?a-uU6mZ&*g2y;J|%KC zc^T^*sT6G5FeR%n1M5y`&9slAm#-S+Hp3S#Tbd%9GR`6kk>W}!jyWtvB4n;YK)^yAtI|E?#QC}rMr(f5;5^t zwrXq?%sHKRl36QTzKP(6te@SkGn)u%K!-4nd}ehEV2weT=InnfS96eixJ4fWqllS7 zSm{9#6#vTLexJPVqeP0;ph~3(zNQ8#i(lrtf&jtsO9~?WDfp9$2U1D3y%AKn#>QO#Y$bFWm1v$vF}< zkRhlt?=9a6+Zsj${gi%I(PA8V=;YyB8hLPm;u;!*|JjjY&FL9v7)jEqd9{BbfgIpI zGYmubQg+&8@1YMjDw@)S1p`!fY!BY?!xf|SP-Hm^vm;7hUPDC|rER0TzXP-6tk8|J z72P^d^hzMsCyh0_4d#eN^+jV&A{H$f8cAdN>jgU9nTv#dByOhgu zi4I2(ufhW1@v^np1G(87y6a)=$)rB9ypy`ZAng{N0beh0(DP~(lj0J?+{@<8h2sr| zFJe*yHKDbiJ|x9vxSHl6OxiEzSJv+}U_@IiI!cY>b0Z8Y9#U>uP% zUh-J|ZV8Sf1S-|i)1oSZ=-m)GWKLAn*CSHLBUIECY&R$aad}SBMz%%{P4m-`QjQE) z`!1naR_cQ~9N}tAy1Fnrj+WG%$QbTpM)?)`nMnj{crzm0_p3{BnlJB})N;)X!HDt= zn@wQw9+#gCP>Y<{G)DMoynZg=PMB%vH+A}zSRJN-oS#r>IJ`^A^3Lap+pHzq7+-Zw+gx)* zibx(Yq?wVDQM=t-y37-{Aq3&suhWd$m5$4VmFm!-51qRl*9SQB6iqGm`ou$PIwe1q zM^a>{JZt@)hkL>g{Sy5YjWAP;aaIa*Pl;lI#Wh*l$b`YsJK`cjM+g-P-St&tm1-Xn28KazX zfSXTDcYS8+yJFkBVT;6k23>36O80H^SLASQc~&!@qaw0CV}z2q>(;5;kh=0T3mDE+Zi-y)odR2tA4b*N)q1hB zB5H<}!kn0#@!VLyEY+$nwZ@nL9?4O%c&IZmBi0jVYkwY8uHu*G3(A|$l$j;^J*$^H0b+oLfy}b>O{a~}V zA(kDkiiPk;E%}1O_fvf0H*Ud0SO)r*agx4YEWhtII%5u|P=TAM!zU6&UuF_= zx*7&d@?E7CO32OuCbV*}Zl!Vu_iu)3Jv*fsFp{fwmY~IAdi*m(&AO)&wWk04y^b0} zt(qd~ShJ_EUFRceg1dr&?#ym^mBig@PERb&B;g{DqESKy!$~QUn97k;jy0?=`}90Y zi8w*fi=(V~u^#7_1{G$X$!13|E>+iqlsIh?7>=tByjUZPt~Qyedg31GP<_3#Hq2mX zFVA=LI}wV*PR8e1Vs1Hf<#7{MCb{7ewvm0+#B~A!1!i0t7a1hA*Ke{XsdS}U_w+_Y z>OUjsXn5qK4&5{axl~Fm7s0L8H&FNfjT3VxLh8MG+IF1S zz|SigMG?6pK1^{I0UEQI@&ZeAe6-B!kV0Z?@(E`|S4%zNZJ;shGLf^tv&3BE zTN5AJWuJ+ad|%?ztZ`dNp{B3sQDjsl(b99*_WKX--7P+hxXC6_vxw<%C$kj)!Lq(# zlU`gXp;VD=eM%V+c*_Y_2D&fgQP3bJ|1y%B_m8}HTLSX_X3O_zTl(zk?X^%g{7_7{ z#}tWvhi!@VhZ}`KR+zoFy79tyu=?jU--M)6$-St>h*|#$$F%p{gh+y=+$i{7sd5lK zyDP%`b3ep8ScqjYYFVDpCviy<8I zL3^@M5(=t$xG@DEv}8cVU6V)n0L={JnF_l-=4Oj?{Xy$zn~&7<8)mnI=MTH4yXq?m z!#Nb3thCe^-~^6B;fa>~nNqIq33*uq%2itd>$gdmwZym%Qbb)t7^hAj zDb-j?3#rH};2+V2?UCw+YEFt$2zejD^)HLifjh}gdsj?fDTGFvrLHHYz2d<5Z3ln! zr4-3|bmURSDWokmr+ZJO77U}280OoX5&Hf0sJW|+e8O_ib@O=yDvj7c*x0~NmT{@l zoeh}7$)F00%CR!odp?6lVAS)a3c0G6ew>~3>{MMYh&Nd0Xn_ZVg* zy5YEbE19I8jg`z%Z=BS7ytelQRgO?#Mz~BYjHw6l`B`+?`6?k5iHS}M`Bz69=91`2 zn20Hhf-R3Cs-KB-m`L*LCryPmR&yo`w}4bAjYrphOAZ8tB)PirmAPkDc_vDss~J2c zW$x1-VebmjU)G%!nvEw(dqlU0~H#B|louu*& ziIDqE$NhI*;ux-8f*uPt12#+E8>>xl^`v2kd)F9ZhFJ1v`d>D?FSw*F6qGc0v*)%B z^y*_?a5H*d;?JOE+>Xs~Qmm@qo5^xA%hLtT{d(X08n;?1x52l`lAxw)#+h$c0`^HVJS@_C3oi}aJW|g|v}ieA<$>aCM^bV8 zVNmxp3*T;jUnH82@zkb4^s>pYOq{g*O0`9BxN*217&8UtNWHY2+tfq$&+k8t|GcB z^N8qIl#q>^oQ~%yO-FfDAL4nd>d&%`Tyk@|M}mT|425T8j&$n`Ys_T>wT$bXhEtnaX_aU0rI)a_lG4hfsh1 zzPgpnxr4ybUe$@4s7pICou$Ct>aC)-Qk&jPE zAhJ_XSWdOigz6?2dfJ&DMlom?eA>CsIVW8BHTB%*F8nk<&%$Q9FYYPD(PQnEYKj!iC?UA z{2sGRAe5{|vFH`!a8%>Mca(d=1@{j8gCJkNE|IXk2E%G#+b%CZ&Au8HL8qrp7LU|h zGFcZBnDjZF;qvTXeRQfmfvio%wURGDZZ%V`1A8} zWaAGY$osn}$;Z0ZOX$%7AY?7hO@}__rgHgPKX$Tl9|KkN#_ndMs3}I>sci;#W$XYs zmvmk)L-I|vlm#082BXv^@T9If@9||ta85y^@!#(xJrqTzXBZ7y?L4npbq$Fg`=%F% zcympVQBlE|c@9K%63SPDSm(aXY!F-UZOs{bd*{*ps=*&Phf9u*MSke^^rlPt|FB`9U;t# znXV$qncq^V2aHmR6K}*okZF6QyO!k~eN8A1Z1uG?;ES=|?nfD`L|CsbP3KdsZ@2we z)u?^)DbP3u)w$l_ynzXHZ=BvpEu5HR<8)g|D`$%PTl`@LSNStm%~#XO%kyUJX8c<2EFU7Xlqg$)~HjF9_oRb+ur`Oxqp=rP#w|Lt@<5$V(_(dIyqAM;+Sg zYmA@VVYo|njHzBws4?rSK71^1jT9!3s;I4NTIbSR^~^Gi)swQe8YrCjH*ceVDFA+~tkJH??3{ySB&Gkvj8l`yf6CC^%df?8v3KV|ps#H8XXS0$aB?@`?9q z?(eYh^kbB-SswmH5z? zcny4fJh*ej+tAmvr8cRj!q#j`B6$}=UZgL**BsWxO!me0^kMQxklg${@KQw#;GA6q z4ghW`ev&Adz}{cwUMH4-l(xzI!Cfc3%84lJxAw)DEmzB&PzlF-X7GW%kyaOmCQ1!Ka?jfU{L=nX2&qjYa>ecpnIwr-!T%UkkG4W zVC_oc44|H{HL}Jt0zPgVh=&a3iD|C>n1~m9>Kc1L0$4`HO@Exf+{87?v_H$S=8>TS zm>?JQ%2`b<4!Y#ayE+-s*T77tc*8j*lGNvCSoC72LaAa8Uj@w(;vf!(!TA9*>K|49 zuwJjlGrCI#Prvrg_j5=jQMi>x`wg8?67FBMm7PgO85hM)Si3f()!iDqGg@+^pK>F0 z*1}xB&dz~1XtWy6{H8AlrT=BnJkqFu2LO+ocirv}xB36|t6v`@BJPyqxxU25+bmEm z>VG6$TAwo}?OXEmbP4;K$4de9cI`Yf^V61=FBut-U)kAM5rHr9BHkj-^EBG;3k&(k zzbV()s7zYv=bfE86nJ;ItLTQeWu=k1-j8!@e|kli+Fv$Zvym!-h` z7e1Y?*KOF<3Fe6n|A+W(`zRnBFY6tjuN8MivLbv{G;1*U?8wjIkvdne;qZtHYi*~! zp+zUN^~Qdn$}LaAqY(1zYltDf1>17l?xDwO|FSz1=rT_o_N+CKr`t}~>(a6Zi zhTo~ClMZ=&-fT4si>v`U)aNwIr%KVHgzmS#qoQAZ~iW}J6Tej}Le z?AeiLimF23r;G}AY;SUawP;hslZndoud+KMpl%Q!8~wwlx8Ec53C}D)G|(u<$azf< zb!f?3X`-bywbPs2zkP7*H{tckic_8EYJ44B)Zv8L9#C&ipNp`D8BbbN`X;Ay0cp=6ew~Z|e|Y`S+`K$Mf?nxc1cU&hnC`DrY&;}Wn&a9M;F+xI?SX~O(!Jf zl+He+q?%^;$w_D*KY6jIW4f}cT3@dN1ADb+*$m{e3jLL=&GWD2i)*KTYUB1b% z2UWw=>SV?Su;AIVB*FW)wA+^r!5j|Wf#RTMdHQKSXamW*KV{#0qz z@HHu3E&pr`?dw$0({b#-W@h(rlZNHPFHpYnwU4J;h_BH`NLqTjA?3LxX18z9q|BZO zs<`;11aKwS?Mn9JD$Jg?3HJ2zqjoO&nyHr8iEpJ3;NBMb|!8K$_uJY zq)xQ-oA-It_Vx0+K&A#G)~vwy9p~%K_}8Z3!v47ACnb){vT)*=R}cUB%8P&Td@yRY z%qS6@J?iHGy&4sj?Uy`NOKa1gs3IABhMD!s3SF93h&{WcB~ahfi5WIH5QTuI*y~qY zb!fq!&X&lDU^g4w(s&QvDa(G2E7@pz2%L6ohu!p;NYu$+jq!<^153F;#u=np{}Uhl zmF!|5E);L@az1C=Sl46G99|*_jv-YuPh207tog#e%qK1SKr)zW1@CRquERgtYiFsG zoZml_8SW}!p(z8v}VR<^{{>XRC68691CwU2G`{E%9sgY2Sg{eD7PZUFY zze`kVi_sM);I~?TCK-#kKq#B9Sd7R5KuPj<%F1xoXFMF@LalD4#GxA3Dw3x|w(O-W zI3=`_>VJ6sT`DUPlSWZCc>E)@gVUR%7F0m18of_b&!EuI zHyLQ0nRX#o_~)yUa|`!`Vsu~uzh?K%JQjYL!ku38_IeP+Z=~5vT7NC2S0(Rai*eHl z(K&_5?G1~mHtQEbQ6-aUKmMJ22O$~BN3_rwh>(-p4xK)4#e3f>r$V^UmG27+)aq`Y zZ^SKy(u8eZZ-H79@pMhX_jxx%XfAo*6cSev2?CH_a_y*$5O!v~_r+Hprlln9z7S3E z1SeNqkfNel+DuC{$=kkoD09K|G~@Wye@3kBm}qXKkNkD501bAz;%RM_-7VbSs zTUzIr{=VR(zwEANEa+qLFrVgF4nl;C_j!8O>()b(rhG_vsc;im{W(u(Cy-!<{gzeB zW4iO&a&>&J5EjSo`3nP(>W*=U zU~A^nPuO=Q-sC3^qtero^E&$0^BtQM8p5v`@m*9v0^l2l(%l`BGO?o>292i2>!)#A zBx$|8u(0rIexFvGJ8ENl@@vHqK|Ly2Dc5(V`N|1vU%&5bji3K#tS;axRe+Dvl3u-ho z#t(->{R=){4?25pU+~sY21-l+)IV?5w%1@QY6^Zhk$0$BruULXqpZrtI80}>64F=o z;ge3S0X^V~VB-0mVLlm+MC-L6-Guco^Frf!J`{ng5sAwcR?AMeOI1h4G1ak$>IevjwFSE7PA%waPeE-MTzYZ%hg&oAt+xoyrhR0CA z?JQNkei(Zlxvl+v5|0M#>bSu~JpEXvmnPZBmUYwuicP1wa@;`&)ITbLY7`aEi}hWo zXtCIF8Zb*KZI@3ro-yf@eBiBb*I_T6p z-M9ZFLN5It?y`xxnfu(5idfN}WhwUvX%ap|f0 zcN==76AL_NbR}&&z2@%MRc1rqO}iH>jM72%mrR8W6H4cCmJrBzFjdK>ITkGt2!FFQ zfg2kPNTT~i)Ge9hlPqHU;Sgt$4%KyZXj|G2T2 zy512Y1y~7(t@jXzQ9iI^%45JQKb-P83$}117Q^`AI~`StP_W{|ETtoO2~%=rRNS4Ph)#ec#*w6qVmce#6(cZqPQD!9)Xrl2t zHi7q@L59JDJdN}4kZM)9U@ZYZt5@wnJ>_1^wew>kH5E%7frnjs|YNcC|>(f59GY&nar0h(w;Lc^D;>!S^E)d&a;$x6fv{& zOTM&Y6EF&F@gw(6nqj^3q4UK!hbd7VOjRl3^L1#efu2`Qm2Fg|rFSU-n|F?0K;C?| zocNm6aWd};iY!y0|2AfV{@0=szqoF(*@Cd1@TeNp>`7$2^L$Qj?1hO*U37DzyEI?h zvmcVd5UR`+!RaiEf82&1Cku-zm;WLIC%C36{91n!cjvdK1IaSygYP-Tq6g#PbzhA# zw^kE2J!_ru3{|P3FOuwExM5*lStrGli$TxU7Z#?-M$OaBj#^0xX8Os0d7&QK zBaiL~%{PHQt)q0hyQ*=;G%O~qee=zmrx4lQb0O|%pFozzrPTT}+3cx-JA)D|%&d(K zqe&=DoBIOpt$}))pzx}gdC5_Kn}MTkM9XQmf2>I{_fC!{$)m_dv&c*lKw1*->Vz@? z7|38?;qi93gj4G7M&;&%?i7`4(Y}N)=NP@N$tD^InFZVi5=%(o>(;|g%6wYQ`-UUm zwdE)r4MVBn4Nhrobc>Ly=ieU33waW|jfZaDf`YvFoa1f!Kevzvh4p~Fi8_x%yh{4M#zvK_d8IIC)uVxYfLjJ@?<8`V736F_+5bCq@oBobTD?j(A&{C)dh;olb9YaFPU@dDP0t_6EG+d|)wrQ> zn{I0-8bNE(mw24gL+xWd-j||Q%XtzR54xa4uIm}ocnfO&aPZLzs&<&uoJ&EWHe)q7 zzYCYKo!kS&&z``>p~^DD@#hT&NQ#zoD=F-V+{tm4`k=(-uLP$*2t>g(C0$R}=?5TF zx2)tRB!T5NC*|>|=X0{vEZXhrZGSLby>sWN5Rt5RKAQ$X)HLI=xvTw%PPmzjtk>E1 z`75F=uquKQzdl?TzVPtnxo`L0UX)|!wZWSbA0Q!(vW?8-rOr)3`_6CDS6|Nlb-{x% zqThUx#r+=Rx%nEHpQwv-w|^h&TDo6uPYf=Y>iDo=tfg7PzYf6jJfZd!U-BEO5>TUJ zC?>tneDP#hgLc%K-dU1*fh0#;g0+hG96vqweKuiw{SlO!1KV_DO^ zA?QBdoGb~TLyg{z1!3njWn@O;Kn-Ss}$=39}F9rp3Z;e6^06SOE zy>E8Vs%$3L59BuB_L0WntUxC({%b9AvTxdxJiM zw;bvK7TriXF7;0HVFg(-^_ur6$+0^!?5rk_p*VT6>3xhSvdNh#@Q8r$YCpZxVre;- zaf$buzqaq%ZQx7raNL7YsYLui_+6fG+Z9I+qBDCkv9nX-o`X$n?h2^lRRv5lr~4>) z16Df=i%li{L#dSx{nZ&aHRG>f!ZKHw2(& znx{|eXltJ!q#FDB2F*=9FJnesOHafs^9r}!!|FX0S={63HX9bfIA73xwDW~Ea64b@ zC+RnG-ewPEs18E%+|R0SLW^9w)eZ`u*3+Ph>ZHwD*o-pb41=0^hy$hCMl()0ZQ^ECXbA-Jhp3XVSB>1{uP&2{K(q$G!n_fmZK9(TevTs{41n{!FOD_ULw>b|K$p8ziF399 z_J{{ohR?l-^iiBo6dg zT%8Bk{B7CwlvB1&gwYw^wfgDcx$~JY+YHazkZp9dO0H>hZu{H3Mf1j=$~O7Ca6709Jdm zh!1dS#K6ZxKta6?hG~EQRgB-`zbu3EiSzEYuid^6>;Nta*n20yDv@Mh z&O)Dz?svs6l!-PjwnuVqvRa}!yw>ADvp>$vIL5RYiRS~#TC z^nZxDE=h2%%VG)z7ujb$;i9~{?kyR)^(8eWO5~#kw0D5M_~davR#wWdhU`PbIDM8; zOl%fYHahfOwEG)1zpE?25N$2zUEqY!&wmiL7?*2KV*K)?D3op z-^H~$4HYU!%OX^m9FJZEGngC(^W671Z3*njgpd4p<^ghXTwe)(Bp>+JG=P97VVi@7 zOP0IWyFpylw!axdmv!LY@wh0&`V(q<%wRM47oi(m=2CR{Xv613;!dTWqt<)?tja7s zZrpiD@g6(g9bPGFz-{u5XCuuvlK$M|3*1w^n&S>9ho(1>-3ZP5Zq3`uld}1SISZ53y?_>@3rRk^b;95)mEf3qz6e-uS1xuwPYvO+V9xdchcF< zH&tM`mOB2qhUx&8UdMc1`S#5 zDJ2L4B1*<5nEG@A0hWE5bq#Vu#JS%~Bb5)>7OMPs67ZOxZNIiI(IrH=Hgu0DA0 zz{Bji-p!R4%e*!X1yYcF!P!TQs*H+vPO`CP!>Xsghg-|%li_s_eHTyTyXUIx#IhoN z81oymnaF$f#(YU_)+KIW_*4R!md<=IFz|Q7bTg($H^r z$0^s)(RkuM--RYXM4YdPeVfx~KKVL>Ev47WUeap6;fp{1cKhMO-gFSk z3Oo|0FXAjP_nU^6?)anSfSc3-80o?qhFh>9=Hbun!-OD|d{7Gn8R=_`R6KT0n-ClO_eCzg`(*X< z@;$1>ed>1;AbcR(&!zUap7Y9VYuWRTf40)U9&P`h7;t@^=g~mY2k^%yzG~Ne{(g}X z6%hAeKaeMXD-{YBL)wiFehb8kF}&)UDQb>04OF*yfoQbt!CKACEkz)S95Oq)N&okC zh-X|Sk?GQnyn-1oPAiL`5D8t8aYqzqz$k!B zZU85VjUh51d@3IaDAmx56QGDNdL*9^1g&*!5K;)O=!iFHWzf}?|HMFD>H`!0a?U{RaPKgZU`N4h?Z z)MM0!hk+dGqu8JI4NceWis3rCd8K!3+aqZ?&Ya0@@Ju@^&huU1PAotG2D42~ZQ?}R zpDQO~fbHBbQzET`fsNpEZ$2;qixz4ZoD^Nmj|075TkR!C@ra5m4a#7o8I8Ah^1eS^ zJ3c}lxT`^Yi{wl^E{i6+3{ZoK3jq1}y(gOWjth-@njFBB_si@9l|mujGKzcXRC-!h z8d()C?^w8_lxb@W$2X7|iObDqx?twg7j$(=y<97vG`kVl`L- zu*PL&Va?v7*#(v={8eX``2k9)iK`MaZwj3d299RU!(`N+XYeN#jn$PmvSct#n27`& zmQ&hJ1F-l`^&=YF(>5&skcat|h5!-hA0T+~q8{krKwx)gLaG%$Q8Ca+Kt^L`#EWl? zj+9DB?{-nE*!VC7>)+j&fJ4SdNc12l@3 zsY3tOcUcyVHk;tmVpPS@jek({A64L_IuK@_k}h~bOyk~AtGjNq2j)RFRHs{C?h@8J zcRj3I5k$`Slpwvy3M*vy_o`YtBf$Qjlt@7O!3FL5X-Qa)W5!&8P{w=-k*nE+9vaGj zYsjp8_{ZMmZamJJwP^W!ttYw6iL}vE!oqUx;rHKhew*s!p^(wuiEb5uob@GRm3hwd7`N{G~(?%+T5`Wn<)QJZp=%s#H5u1)H;XF zH-LhC9E;Hi)e%K!88aaZXo+)o*S1`w6(1r~yE5Ksyq*}L|LOB7A%F5ShlNsKU;*Ca-@#;y7#9-p$E_y8fb$_nD%}Xv->B#0 z9g45j<=2|F+J11L<}xecJ89>Xi$6fLsj;xIL9v?@(nPoWZUz#w_A%w$PcA7&?WfwW zgQ+MdB?-Heo1O+tON|782m(^M(|#@p zy72SkqNQ1o)7qCzey_(kIXyx8w%3My=0|tbS`NFQ$4+OOCnirG;Qjo$Juqyn{Pxc8 z6^>ryq2cpc(Qg}newl~qaZ9(EE|q03-E^F+RXT?3nvF9Q!FZ8=Bk5F`H~$G+Lt+GY z5!%q2JiFZ$U|l--b$UI)pYW2&5($%bSFV4D^Zna$kbrAYHV-UqCE01+KgJ2~)#&dZi8#x0>W|P5 zUX;ihNjlvMa#S5=Q$!4B6XZPm@D1y|M~Um3 zeWTcLgaJkY8Bs(<=|!nZ6_wsYlR&@%2nj`jfPxfJEGSCvozMcI*HD5D1*8Q?q=X zz`F6v)Q_LDbh-mAnr;LPdha?W^UsRPf+X$22E(dhF_XpSy4OPHo5bxgH*#J!D44ZB zaOVK!eJs??;#H<67eL06(&teQ1a^~C; z0s0A7!ouf#&&d*EXtmxfxv;PZVT<9{{5cXXCMj+;Ub2xa>-msL8>PG7ly3~S9e9Oy zmAO-;Acl~?L%m{+$TP5YKvR_M@~>@O3y==s{#SR9dbY3HeKXn7S~NB;CLhs-C=E*E zmk@0s+h^a9tz3#LQ`7@DY~c|URWeN^*k@!ky}N!d>>k7EgA4;svTm1Y_lx+@FPE3U z`+o2+hO_0zzhsH=$Ct5x1}X*TOk(sP&l5!>>I!m_`!SZ2mSc_QM8-#}B#qK*HE|_F zS$Q-eyDZC;)?V?VDN@&`v}EiZ^rTx#j#V$l$9pP;m;3PBOmd4Jhz`JTFr^vC5h4YH;>H8sM-7mZ?h1}d@SwhUEk$;oAc|rT_V4CO7I3x z9*w~-zwbs=ox7LeU-h!LM;*g+RKVAcG@xHB=LsP0!1cHKQshQk5>%o8EFusvDAY4A z<5Q!G^(eyitn2evOLI!xymR@9a7l*@GAo2d{9hn@Oc(4Z%#~Xj43i0VaNwBjwQCxB zf1GX!CT)22-M7Zf6%=lu@1s{5&)-vD2!Fg6+_=?^joKS@wg`s{_G{jB#I>ad*v!Fw zXaUHu{qB~wf5+r*wTe`S!r_=B-y1IXVflv|;-IbCZRCX&=%EQ-o*BTM&ZN{+2Fh(< zM9T@~)`2+BBbe+8_6pj~@mI->*DGcRiu12y9@j(V!d4R0e7Qqn{$;d86I@-H9G?10 zP(5DOOQAp~wP?VM^pRhAl!8s_nT8vg-)9?*(P5jim1G3OSc`1|6BPn>O&Up1(LlLH!k!U&VHH1~dMvyL~pzc~2nB#D7L zry-W@Tqbc%cF)uO`x(RD9r4z&`LLu0J50iQ;0EvX(E|Pl3OxLO!DV)h`Q%WJ{odZh zKItv@zTo9oIHzfyI;^b(8?galMBH#V$SMBCE-KBuDtNeWYMj5bCR;)4rr$znjUQK& z9k-)Vdvt+@<^6a4mZX1Y)~y^YGPhx&MliK5MTw!8qBs-P6$R%#egcT6=C3f@hr)AG^agc9C$;|-LFE`GeN{^AQ zzcSmSxwurBAo`&>5TBo+uS7Z>7B;B0-?=mTF=rg>pJnVU#)|*E-n0lnZTZfX3EsUH zdZN;9gE8Ostf(Y@p+b4hTfR|iDw4bv?j1Pub$yaq0e@r>^Phd?f-JbZtv$){5RzlZDdJ}xh>k?ZDH z6D=z9V9Vo6-MRCmTwx<-26Xl1i$7f_4PD1Biplp&D}#)C`H2QN)ARpD(z_J%&h(v0 z(DiI~a$y$(JxtA;*{(4<&$oqsz?>VFXTmwF>Foprh#uJJh$Z8kv3|P+3dvB~6?AirX ztw0DHW1`=!A)}=;thHY|B3ju`7|7s$2gGOpUa^tZpl2Rx4suusmenH%Drs@6ui3>o zOPck1jx&Y&;M4s_a+g=qe%a-j6+P@XldXKeQGZxM+OR!2kdfuZM*a1Qj-7H*?nruU zaPK`Nk}a;$qmX%oM?Va()P4SI;b`tPx>cX7fS3+HIpw+Yot!{of4)+zDN zWc!_;YdIO3S7~=U;wwDae-zjHAxN(9J6*Dd6fjfo@% zpBiI22RrpsW7@AN#rwwgS3=m9fD(Sa(?!+Q)%B-ZYSf#zOhi}kE@==J8P!z(l88s$B5{)&@-Kg(cPPpOjAdC_u@m zpRa3tzeZN4d(kKjA|imj!!8*Y1_z6sXpxQ=64Ucv)SFqI%AIxrmnkrV0IhP!uK%vu z$K%^T;QzwAp!|@BH=*F0(&dI7W-OH-JVppLfNQ$5^zdxx{!!wxR*I#Com=fUam_6g;$B*Q9hqi~vgx!bwUGnGEt;*>Wp zS=x%7c!rX^q&z*uJ|uCzhiqSQtQuk9*$77YgoJ^<5put|v)4GtYr#7ns)<`)2m1U^ z_Y|*(%HMdjbfQC7H?pJ-WS8f|{t5Igj5=XWm%D@Hbv9HK%&wc2GxG_YU9Y)7@<4UM z_e?V(*AJX)5BC3e@d2bu|9`vsw9OUF?I79pMZR^|F6N#tBt2JP)aE)ns;n(_6ESR% zCV56&T+-CTqXZ!?Dp?`Evp_rmOZT)sd8Bbb&mTE{KdrCg!RGyYTuxKG)9cbk1EuCd z`}Wp&+mi zi(P9^M_USA1==2h5uaa;heQu;?tEwRdA*`qo*A0nQkC0mgT8TMQN}H4)03S$mF7ai zG7I_7!uk&v8{vn^l2#pwq9hen`-2J(srC6?HN}_q>4X*OS!CW9N*0&Dh70%hEh_l@ zYq6&e0J^tsJ@gb)o8yOrp`AHS`H(G}j14|I`Y2-ZWVu|%KX1*3eOMSs)e4w6YN`{I zs(Rv*A+1sRP9(OcvR4sWX!ND0mIz)o^7UB4- z-A-x<2JFo5+g5-B%r^X3bsJXEYGj+oT8)@}P!y0sh-^D^R)0@vvjKPBdS*rtLoa6@ zXXj4YhfX~A@1wFQ%Q~X@Y|Mk3@@lh<{XSYeZgn3nw13M0_Jr*_liq7&`Qk{7YcJL@ z0yBPcJEvi3DF+W4dEXm(K~A{Oufsy4oipjpfgLvBBJE<2g%%IbVZ;|~8vha%qEH;j zb}4UsTsD6^`_#k~UqM}2!KYRG{Iauc-KBH)oQ#gw7T zFKom0=2>M0R}Ubf75v+8C=^;7&>cvWZ@vkXL36OHti8S-_WsOJA|;1c>!dQyIcs+E zSmaNt_Y)oChiPpwO!JC%#Ayea3(o#ndG};_w?vDa$1tB3H}m_A{pdI(tK3DN+u~RL zwR7w>%C|AQ^K7zoFsrs1iaLDG47-3{i3vv5ztX6&ulpD@=8UCE8I2VEC^F~8*XPV5 z4i+=s*FUj62xtNWtAl|I-OdzlaAN*Csga>+gD}#k`+Iu6)7S!# z!gbn|!!p*Z^l7IM(_DOhW@#=C?nY!ZR)HceEZJ&*sAVwxmwfC+uMdBxZRKUAuu~wJ zFaW?56N8VjDGmiccfg$52j;~1tw z)?08Z+XKTtJueX;E-U#t-Fx=iVV>C>L96LXkP3iB$Ao(p547V049Mn}yh8n3mo0L> zYyZUWTqnI3IWNEBG~uhZ)_aU&dc?xdZpi4Mf=S@V*fiTrA`Y7Qp5i+@yEIIRwwH>H zt~BtJ39?xo6Vcp`lU|g{MQ#2mwr?-uLlfE;BqYo zuw7|41Us)5J`bqs$&jA$hhEA9k|~nftV*uak_w)?|t(<_s6XA zN5*EQiFH;t16*0ozc{>YP+|sK2A=>{u(f`z1}I@mjEM$AS4@?1qWe&{7jP=Ff|QX^RW1YSZ9MwdUC0J4HW% z_}n561i!##C#3y3EPM?)z=;{Eu;!z?WVIsSPEaU0+0my0v9so|A$THug|$Oz?DWev zdG9=*t_w^9%dVEBkbkt7mU=g`c?4ygoPdH)LR!r1nZhb#rTxPPX{h1nZ&TiE(6hXJ z20+M`raZWh<<{2qEF?zrx!}BAx$v_E@=US zg7OHVT|&$`z;Zqa#4?4Asdi0X^uSppeNCTKueH@!@?`Tzi?{MsN15$!v6wPr&%*5J zLuXKvv)So)#Kq#_iZjKL50_$NJpadcSTr0ss6AIQ0?%1GG%gmT2hD3u6g&*wJ@+fj z6$iC=C3*kiDYnfBu&?h>?=|3_60bdNN|HHR5@~+>y7Kl9-gXAjuoHs+; zTJxW6k@he5NQ+GpqfK82`9oV&jk`D5v#&Lf@=kDbY;+S8yWJfkr};nPBg=1727o64 z{ydQH`S!AN8v=(OQ^?Txxxu=(CnG&}|?$?1hdo?ilf`O-vl0fd6di~${C(dnD zGUAw6XDUcr&PpY>zKG&iWE$a~+b3QVSA#KM?! zf4*0OR*KnZ;ar1Rx4&Yl@Rz)$<(btX?46|6hz(twv|WK<^BR16o}SP|DZWgPgn1+e%zb z$YJnaSjphdWU=JXG`HmCDM{4E3|!mtQlow2_Fu)ks*+Q1=$w5ryi?(t#X@T5$hB9N zikP>_e?QrYe|ivjG)tabII>oK|8*&}ih$<(R%GnPjug0E4jo{R1H_pOE_Sv*ib402 zS{Pu^AkKN9za8xR2_@?x>_8yS=qPv-VCh606+zBAGM7Pib~bQdf{&>>xbJs+jS}p| zNxmsa$NO{Hn1YK*7gohBGEX5`>mKIaTS7srQJeyEVT~ZK_VPl-O94uEbrqkkHcx#T zQT?3r1^*eN#1qJw#bG*2=Fo2p1w1TdD0?Q&Z!UDduuHOh8!6khg{5KoJr)VEBD8t- zE{_I)^yB~99G)FWHZ)yY>SprK@=a?cJlsMY0zj~JwZ>52B%w>CTNsO(Dtja0t z>!^^B9QYZ+O`^{gYL8>Qf>dUEGT^A=HJmr>MJhM8=iXQ`&;hZwnUD*g0oBRit#kt2 z+gd`RwkLfjb-TTIP~I~8kX%Xc3?wxxc$0cEaO10L+zQ`}px;QbXAmqe_05gn>mddd zPT!koCk9+0z~m5@nw-U<=c=z3i5Va7`|CW_u7Klpnh%K@+;^EvwS-TnW+0T-031^f zns$~!OPf}YPiloXdzI_0jXP&u`$-QKetISp-g_$wJcERV z?uE?Fv=ji|ciYceu;F2^RI@0hSPLAEX4Uk4g>0cw@lxNV|5vhlFf{Kg5AX5po-vld zC5rz>|?d%;4tccAj$nIkPZD^7A}_ zGuuJEkN{hf)k05?y_7_F9|}a`AE@ zKX5ZjuIw6sdAKaZ^AkQ)IWE>tSw*L*0UGp0PHPqoaE7R;VuaW(#r>=Iw z{g12+KQasp1AqwZduGAMrpCdSz@ji6GFU<>O-NSEMRMO}{YSwZv&VUCL9dcHOSBwT zsPdEGP{}@Ho-2!aYE>M`dAy1}oob*_ATwD!u(*CALbbLYOJv9J=UhR~jB{4H^zKbP z_s=2qO$(a0HtPidw%kD5hS0p2L$a2UYiPfsxH6CY$2PnJl?B6 zl2LG|FAUT|1fMaUQ!e5k9z49qaGQjKxm5I+?inyW>y>YtEFdcd%x?+H9)+5ul!i-r zkG}0~s$3BmC^9plQmU*o9Wpm|WR@Yo=u-G+(%>p^&FF7bIX({x4%)vV-R#86mPBxQ zJ@hT-avo}LgpI0p`ImCWhDI#d(t>LC?rNfyy4CG7iNZcUoaWMWNrB~zv9gNeb3$<1h!GyW|dQN ze3@P?=L{OyAWILO?A!cgXS99~6J+Dm8V>h%F%-7`Sd|#LEo))1;6NR!0W5UHs_(PB zPvn9I>4mK4*bic5Y>y0`FM9PwyAmoe{G+95tODo0(;J?XfB&8(YulsTI@A@<;7VPG zjS6FC1}!~3Wbt4#U&B%P_E~EtBmLri3bJ#R3j1OmF?LaEq`pVtyWiWg$IRU2(Y9)a zB~$-IT3MsI>jOk2^@GP;>1JB8XeRjWBZK!!B3;`XIk0!GiCFv9^S|B&ZS*c5wO_88 zB^H<3Vn?%u4;uaPE9Z{8O%UNJ4T{SAp;6NB9o(op{J#AR#KdTvKXS7u{Lg3oO-=KbhFAam zg)tO(b+uQ$;g#JeyW~mMFofAEMrJI`kU4;JjWJ84@hgaFz9RLLd1d$QTX8jN=Wmjy zp9$Odc;<^bSCM8X>*9|e<-dX?Q)DVqv#-dZ?s8slu);}mwbj-1&7M5avyS`;Ryw7g zoD;k;a|(9XSdMtrjABltka6p_S-Z0Q@3(wK+g3{dzM+aPbS9{)D`@PH)l28HBpw!a zRNnB!0dRu+i3A*HYdMJG0(Pt-(w&%BW#sSwvk&CDJ>GokQ~W7y9~fNQODz+<_}`)? zDsr*0u`d0neGHdYwx)Xve<2Yt1#Abe?J$idLqT>^$TK-x4G?$RN7Heur3IHsoD7dX zKalhGQE&mUFPdL|%CU?sKmE7IL)Xe-BjA$t|Jo6jd=?R5ztM3mtq%=44xO+Gg=Rh`T z8dgFdI%yuH8O7w~kMpZt7Tny>Pb1bpE281MUZf?LIfsI6EY=~mG;nau;>O0#bToy5 zYxT`d3@=mKsn{*F{VcJtoFeXF`5JH3K%3L?UdBC<9=Hcfu7lg`vneU+*w#0&s%CYU zZrb_z;2yrlZJ#_BtG!w|S(_0Kd9+|bEh3v4s4viPHHnSwljv9A;DX(DUY%4ck?3SX zkN4+}iOFf0zgqwPw8X_bOgg;bBTSX|)6WEty)1WIu8lEYVd{AakOV^{9i($nx)|tS z7`ORV$Tw_zs>Dy=AURO6zL6Vq;WqHa0E+>LgP4_6z<&YaJMSxPwg~@9LqEap2FQFm zktSchbcN=CVlliDC`EUaGIB0^zwme2Q>RcNEc8H6!$=y9xE-{yhzjoTL;y^BNh~m% z51H!K0f*yojh=0dZj-;>>(`*H3viNI+ed9KCR~J^mN~KIKX)lvog}^87=-y?=kMTkJ{p^lFjae!#3g;FZ1(s46#sfH zeeOxVSyqiZ*~wietHzDw>hAEMhWZ(EBcMbmk7nvpKo>iGg^f)-z}_b2K#pPU1#g6! zv}rS;7@GM?#2Eh}MtG)ZkUcihEHfHEVf4{4Ua8a^>b+guh=s)>JLb5&RH}kjMj)*z z8X{}QMFq$g&f#g}}2~`+km~9jEf*81pH5 zL*}ODo&5dy(2QVwmCXV1^Q4Bqm`}qp_J@d?%TR^7Szq&}g?D^0#M$`4PY>t>TN;}; zr_1YC=JG$A=*t6D_4=b_7rlw|5VPwKoCDViYvwx$uU|AVE?kd8sD)iPGE{yij3APa z@PlMecBf$aUr4%-VznrW?!EEV&uQ;P1ZSV?kzEZS;o){tdEr$qn>VNNCx#N@Jk^S>;EXpfbr3vyqZgX{`?{NQqyqYA@7ER(!_9%o za-Knbwg1KyyLc+Nn~TfEx{Lksah%DxFNPd`D4?+xflKH@SlN?3(T7ibtWq~ zH1x^BVAF>;<&7e`8#HAa*TXke>#`>EmHJ;-dsq9dT?#|i=@w0P663?z`#b;4bU*NC z5vGhG6<6c?axq-i^6yby1Lw~8?$?qNf~uJghvExQpN6Qfis@gifwYMoAylppl-@)E zGi&BdN5ueE)Fy!L-aET~zPf-<8h1Iz)!MxiT5YyqPl|247cnVile@eYI&tj1gLfsT zhfVH+wNruhlfUW8_d_it>hgA*TOscUWAHENt!DdNSk59>1Hn{U4U=K=G2Q+UxzUbN@4KVsJO0)69Tg4xa zZ{{$3-EUC0K~t6x^w-$xXN5MU5habM?bqbEL{(%QNDK#5XQg_N#__F&(NwHu!m?*+ z)*h(qNR`?wNzu3yk>_e+aZBOl+3T^kO+yM6rN*ducWE>F=VUf^E>k_9RDVB8LGuq7 z&tb{c0W{_%)waOi(TM0Bdeqly{-+a~+twki3#Yr3FI=EgYsL2GvR|i$G-yjCCI-2Y zz5MmnXg+Aa94{Fa#3-Cw{b0N_WdPXf0|%bKUmtir;O~iLOis@3&e)Co++?{+jygds zj*)aM4`2$jHdx&vdTUVe+OkS>=uzXqlgHDRhXGHYw zhoL<7rRB4VuDQplHwI98H>+KVnw|XbMXR(yg$gzv=gx)x@|YX5+HKuLokb3-&JY&l zwAagI1<#VmG3D9e+6H(StAuKC{7|iX$;a=1AmL<)S@o&@5~R7n%bND6^m)#R8n>uR zmvc!CY9=bax@~O``}8V5&%usk7u<)1F))dNf|E{8aZR71Vr&$JE{lr;-n_$p^0O;Z zn*NjQ6SI*AN=X4FbmOo3TT{TXu$tm5warGxiYZw$KwlWl%lXDWCYUzd44WOYWMiv% zempTAa`S_}(x_-P+zHt2CXcp}9cG8E(Uu*+JTUrJ=oRRH@j1-=y)tQ$uG_~q_$q=0 zu}0C4py*NghpI2R5`z#bfhgx*U(D{q8=}a08L1kNfIlldf+Mk9v4$&mzh^dt4c2cM zb{ny9{tueu1EOEluOm++y^I~Qn5@MZ@9?a;vE-`&C+R5JY1rL4S3S|-UQ~6jQsoae z&YFauEmfxeKeT3=*LM0@F%8PetXzsXR$!AD9K=r~81&^2hneSo_NUSaYiow>ZIOhl zQ_xxhVFL?EdyIDoz9p03Nqr&!dHjk;@D@>gY{?pR-A|wHaH2`p!2fO}axJDh<31@X z!?l{;d$;Ws>Ht$<3#L>Ew_R;<1rKVrsI4y+@^|*qei*9JeMup3^AJ@d5oG2{f?}fD zSpPctvJ51vV)Z;%+&D!~!#HNX&c=UUKup0_e@Mz*KRPH~l5_#$KYh-1hTl3zG$Er^ zA7KSuYrg6~zJ+=x1^KD$iiaaciB_Z``m-X`4Mb43r9@4J3-)Z+nhk@vhd?2T7&!>@ zI_r50>(|-|sjb9TU5g2@*`D=dpY=GCe^NGH;rhcZpZ&Zk5*~-V9dmq*sPpq?QFKBU ziiVq=;vJp~_cp+-U)1P?mAn|a)Zi73a_?>5(1Q0a?S=((R%45;s}$Yz@SDW|NUU4c z4f+CUsDTtsLNKg^4J!zVrSOCS|K0R&o}^8zW_y)K3_*`#ZQG#`H%pAKkmKaKFK*H#>r@{>8U8ye<&7z75udSl>O{y(_}^oGFviA*d$K6xz%3)VN2L_ zk=a?hsmg7d<|PCV-TsP<;2t93)e5EoZ{hfOx^1Lzp*by+OCz;_+E8g%|9UYghV~_a zETQHgE_yz5^*OQVtcK1o@e^?*SAsV1VSzF{BNx|*cvVxfZdvKv)myqm5EpZeY0h9I z2^*#7V)SOjKN|P0+mI2Ab>1PrvnGYlD6v&4maAd)$-w>qYFh;sXd33SVRFYpB`2JZ z^*rLj;UCHHQCePKTJ4eRNNO=H)bexvJOSx0!8iZur&dtHW9a~mIT1*ISS3Qe-NU1# zn~c+AFkmw#mr)ok{E{3>n}9XsyI}I>P43AA{fBF|r3j3t6MFeaEk4ClUog-uEzVu$(fQiDiCf=ZY}w^JlU^X% zFE!saH(CGc$$(GZsD@kU98?f^(YCiu!;~%JY{KE#OYq~zQ7TFX@DU3}$3y&gMTl>B ztaGi!V$m6aM5#boo$xs^qqX92`ezoFzpm+B(X`MS@@#!wk-lK0`K(Hb99Z3K6o8qs ztuCRWo(RTl{tWTiyg>L_$G3x6ccm_8ilMB`IqJuiNda3z=q5x=G=!^Q<3gHcWTgqt zcukKib+u%nIT4j5w9rSQtE1PR(Bs3O$JR(|b~m1dHc2-bcHW$&G_o@a-HD@U0gK|y z@V?R(_mN72XmJ zzUa&ioHRl~`L6oiK<$ai4Je5|^@eM|<-}lyXQ2Z!2S~Ioe3(G)lwhp-ihes+ z{5sWXI~)oT0s-kF=3rLh<8$yKRMMOK;TDNadgRS2Luz-u>DFE90R>J@h_-(ozal(4 zQM&zdel@`(xsCgI#~if)SSlYk&@5FN5m_=s_Ku4k@In?{i~A%vCgrtGbNH$ zH5ay~KuzRLF&d64wpx;uX+jL6q<{GVTs%4h(`t}Tx%laa-RjoP9MhMbnb9tUQb7@$oTv3yOjHGb#C$ z_8RNi3PQpl=%vW5n>l9nCbdRslJmqgpii%d>6vm87XtJnN zFiY6@0hd}C-y=mbE0EA0MNRhBGhE)lNsKk`>U-}?q47s@SA@fo&)vdcmuGWAHdJ^% zqn<#ub)Qde6(<=eir0A5%__O(VyoX)-D$f-m44cvsX0}6cj=TsF-aejqSXJQRNa!I zet7_WN5I-3pIa6lTZKpf-Y4JJ4+T_EQnsj-yJDgrrTxq9=o*3hJc}v zZZr)q^9|<)o_!-FJq`b6Z1RD`X3`3#RqE(1s$B5Kk5mn~>BxxzHs8NOcAdZZ3%DFV zz26AvgT$@$$`x!%$EOx#92^9B`FPP~1-k0Zo6!p08fP!Q-?u6*8NYk?o(YP1c4+9S zeS24IE1x@J-XIT_U!uG$&B(a_sr`N+X2S68F+{T^9biEE%_YM(ikvOKEi6p&FBHD} z03{?_TbN!`BR6q~eA;USY@6IBfEEFrHbI>aM)Cu+z@MDWzL@3l=geZNfDYE;QeSBi zkmooq8Rj_iUgS8@Hp8$o=txbEhP?m=!KgOZZ8;}ZXed$CA(N12Qp>J0oYCMALo^{I z=H9g1)t5$E=-29$hFmpGq?`+>{9Sv>*b7i2McJBtkBD0(`({xZ8$al5gBNTQMwjAR zgMU^G$-h*`He9;^(3I;hgLKz5ySsv{_AhcyS12YFnz#w_9_E|9_FB_v!ifo3*sR*L zil||m0g>gGp-MLJjs1m$19r32k|6xUnc_p1)?223R^5WOogH%))e9W z>t@)kwKW?2O%dZpCm#d(p>!y^S*u>FKKzfDro+=UOsN942rFF&p!(WIs) z?ptTRy`O{#0j50B`=|~aw3kn&eJS#vmZ^1_XoW6v{aH2TPn1RH3fn1YcFbP|;O#vF z>)HnBgP;dPLDw4Y2i_kj3=$!cmORvgdzbvPx45x5;s&GdLNFdFP|{as_0}%S9Oy=P zxsMBJ2(F2H>WGU)`*y`{(lAvwi}U=zq>20Ye8%R zN_*#upBko4Y(LpWCm z*Lc*;qFu8t$L&d>=(OJx^!J^Nf^+3o;Npz(#l#6qMb_AKzru*Q>&No@L^7@nvG3p+?H7A|@(#G7_HWWOFa{$f zGzyW@X{#*pj!e8mtgqO+!djr^$WH3{!P=y}VhOOt#jk>YjqKH=DeKENyn*j#8Rsr#H>l0ziz{5x#*d`i3-jv`qNKj9=0i>Eg<^a{+h z)Z+CKqqN|J=0HQX60wM6aSj&=sU!&)J>*E~PG??=L!o(ccKMrA65^`g3LdNH#~pZD z174}hYk^}5t}+7$;_#KZ3x`m;my>r4xUWYtYyLk8Eal%&dn()*1j>w-j zp0jV%@%?RhiLH1}DCN7_c8kQWj?cRuG;51Gk=N{Fsh7`|$xtny z68X@yc|>mRjhIEGOy}09f5r^t$x`tK#AK-27z(F$vorKl;`I!C_0zC=U-m)lOZw48 z-=-uc=A(o3A|b`p1&xd0uA-eARzs9qohDJNe^#b@zf(_K)Ns8O<@4qCj5S4}#7#OP z=Aw%xjGZh9hcYh&gB@FuJLD}k~vZ4!1LIt}c{Ku2(4kc2Ko zSc8H_hq!a;qcI*>J@`PowEy=`B~b1gcx`!(dw`-UopH>nE%CcT`2KU9Jc^w^cKIDQ zVD$UkJ(ipcJsr0F^kx5#t(}DQ_@Z5sk$+t z?>D1gS+rY7j!i?L<1Gf_~kSi-!vc|SygxHmpcRScn1{SKH6D2);HF7 zqH0pc{)XDE=;faXe10XWcJoZ&W_>kinU|j)6>L&>s?gR=$m;EN{jG%rH zLH0U9@x>Z6+*KrOO^-6Ew;#jdN;L4F_Mjk#hyHtOL8(oU1oHhRhMz|cdr715g$^8H z^H{*7P1aTPLFv^M-A&Et4BGk6$#_ov3-<`_SpntWFN!TbEn1$KkCKI;E)^Yz8@=C0 za8xUGeZ(^^^M1vKQW@WHEriGH@=&D-!>y5~OmGb%PvEoPZnswNp(rV-^4sI$rgVYVn;o}Je!RlHve#!-*{dsPb=zPUdL_b%s~Y#zPhz37*2B& zw1-y0mY3!5u?xAjB?&i@^|$V6G3Ip&TTp6FqCaBbd-e94=Qdq{K$2tA5Z$VwNAksp zP-#&p+MRlp+XY!||23Gv@Dx13ar|_IgD{87>5ZVwYQv`%wGaC9s;k`z727jxtPV&t zSrZ}}ZO;wm@vHPjVCtolM?L|F3|^7)}#c)i$XLoipF;M@N^3hGlf>6gHO!PPzlZ3`z^#u7~& z9lv>Mf6z0K5V(J2f?q)&Xm--?zLCBQ>?;6&Vk&5k&57rNhHDWj5X_U;`X-%LuXZ)@ z!m)uz5JY{MW>Jz~1}MZ1TONDJbvl^R2HL8dnSt8$b8a(>9l0}o)ZHwxGVL>d%()y= z$u9+zv;~hlc?AVayV6t;En$FI+a4;G0iGS6X4~1*_Y730@#<{pv(IZ(71O{mwa!67 zkQm{4q9|gsJf?mTY8JJIY)^Iox*6OTRytzmA{M(_U6g?zMWi!Dn*!=Lc%PoqMe(_t6&WWsqoJ|_s;JdEB@C^$`WGzYyZ3kYFBK3EZBB*kbtN8U;o8) tQ5;%R-?_l;5uk6_{`3D!b@dY)8Yd0OugWwZZ7b*Ww2ZHmT)Gzee*jqlOT7R9 diff --git a/docs/Recursion/Reversing_String.md b/docs/Recursion/Reversing_String.md deleted file mode 100644 index d896378d6..000000000 --- a/docs/Recursion/Reversing_String.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: reverse-string-recursion -title: Reverse String Using Recursion -sidebar_label: Reverse String -description: "The Reverse String problem involves reversing a given string using a recursive function. The solution efficiently utilizes recursion to achieve the desired result without using any iterative constructs." -tags: [reverse-string, recursion, dsa] ---- - -## Reverse String Using Recursion - -- Problem Statement: Given a string str, the task is to reverse the string using a recursive function. The function should return the reversed string as the output. - - -- Expected Time Complexity: 𝑂(𝑛) - -- Expected Auxiliary Space: 𝑂(𝑛) - -### C++ Implementation - -```cpp -#include -#include -using namespace std; - -class Solution { -public: - string reverseString(string str) { - // Base case: If the string is empty or has only one character - if (str.length() <= 1) { - return str; - } - // Recursive case: Reverse the substring and append the first character at the end - return reverseString(str.substr(1)) + str[0]; - } -}; - -int main() { - Solution solution; - string str = "hello"; - cout << "Reversed string: " << solution.reverseString(str) << endl; - return 0; -} -``` - -### Python Implementation - -```python -class Solution: - def reverse_string(self, s: str) -> str: - # Base case: If the string is empty or has only one character - if len(s) <= 1: - return s - # Recursive case: Reverse the substring and append the first character at the end - return self.reverse_string(s[1:]) + s[0] - -# Example usage -solution = Solution() -s = "hello" -print("Reversed string:", solution.reverse_string(s)) - -``` -### Java Implementation - -```java - -public class Solution { - public String reverseString(String str) { - // Base case: If the string is empty or has only one character - if (str.length() <= 1) { - return str; - } - // Recursive case: Reverse the substring and append the first character at the end - return reverseString(str.substring(1)) + str.charAt(0); - } - - public static void main(String[] args) { - Solution solution = new Solution(); - String str = "hello"; - System.out.println("Reversed string: " + solution.reverseString(str)); - } -} -``` \ No newline at end of file diff --git a/docs/Recursion/SmawkAlgorithm.md b/docs/Recursion/SmawkAlgorithm.md deleted file mode 100644 index 0a3e9e903..000000000 --- a/docs/Recursion/SmawkAlgorithm.md +++ /dev/null @@ -1,214 +0,0 @@ ---- -id: smawk-algorithm -title: Smawk Algorithm Using Recursion -sidebar_label: Generating Minima in matrix row -description: "The SMAWK algorithm is an efficient method for finding row minima in totally monotone matrices, a specific type of matrix where entries decrease or stay constant along each row and column. Developed for optimizing complex search operations, this algorithm leverages a unique recursive approach, reducing computation time to O(m+n) for an m×n matrix, making it ideal for applications in computational geometry, dynamic programming, and machine learning. With SMAWK, developers gain a powerful tool for solving matrix-based problems more effectively, significantly improving the performance of algorithms that depend on finding minimum values in large, structured datasets" -tags: [Smawk , recursion, dsa] ---- -## Smawk Algorithm Via Recursion - -**Problem Statement:** - -In various computational fields, including data analysis and optimization, the need to efficiently find minimum values in large matrices is critical. The **SMAWK algorithm** addresses this challenge by providing an efficient method for identifying row minima in **totally monotone matrices** , where the values decrease or remain constant along each row and column. - -Given an m×n matrix that meets the total monotonicity property, the objective is to implement the SMAWK algorithm to compute the index of the minimum value for each row. This algorithm is particularly useful in scenarios such as: - -1. **Data Processing** : Streamlining operations in machine learning pipelines that require quick access to row minima. -2. **Resource Allocation** : Optimizing tasks in operations research where minimizing costs or distances is crucial. -3. **Graph Algorithms** : Enhancing performance in dynamic programming solutions reliant on matrix representations. - -The SMAWK algorithm's efficient approach, with a time complexity of **O(m + n)** , makes it a powerful tool for developers and researchers needing to perform minimum value searches in structured datasets. The solution will provide a comprehensive implementation that adheres to best practices in computational efficiency and usability. - -#### Explanation: - -The **SMAWK algorithm** is a powerful and efficient technique for locating row minima in **totally monotone matrices** . A matrix is defined as totally monotone if the entries in each row and column are non-increasing or non-decreasing. This special property allows the SMAWK algorithm to significantly reduce the computational complexity involved in finding minimum values across large datasets. - -#### Key Features of the SMAWK Algorithm: - -**Time Efficiency** : - -* The SMAWK algorithm operates with a time complexity of **O(m + n)** , where m is the number of rows and n is the number of columns. This efficiency makes it particularly suitable for large matrices, surpassing the traditional O(m⋅n) complexity of naive approaches. - -**Recursive Approach** : - -* The algorithm employs a recursive strategy to eliminate unnecessary comparisons, thereby focusing only on relevant elements in the matrix. It reduces the number of columns to examine while maintaining the integrity of the search for minima. - -**Applications** : - -* The SMAWK algorithm is widely used in fields such as **data analysis** , **machine learning** , and **operations research** . It is especially beneficial in scenarios requiring quick retrieval of minimum values, such as optimizing costs, resource allocation, and dynamic programming problems. - -#### Step-by-Step Process: - -1. **Initialization** : The algorithm starts by setting up the row and column indices for the matrix. -2. **Reduction of Columns** : It iteratively examines columns to determine which can be eliminated from consideration without losing potential minima. -3. **Recursive Finding** : The algorithm recursively identifies and tracks the minimum values, refining the search space until all row minima are located. -4. **Output** : Finally, the algorithm outputs the indices of the minimum values for each row, providing a clear and efficient result. - -#### Why Choose the SMAWK Algorithm? - -* **Performance** : Its unique ability to process large matrices quickly makes it a preferred choice among data scientists and researchers. -* **Scalability** : The algorithm adapts well to varying sizes of matrices, ensuring that it remains effective even as data scales up. -* **Ease of Implementation** : The straightforward recursive logic allows for easy integration into existing systems and applications. - -### **Example Walkthrough:** - -Enter number of rows and columns: 3 4 -Enter matrix elements (row by row): -3 4 5 6 -2 3 4 5 -1 2 3 4 -Row-wise minimum indices: -Row 0: Column 0 -Row 1: Column 0 -Row 2: Column 0 - -#### Complexity : - -### Time Complexity - -The SMAWK algorithm has a time complexity of **O(m+n)**, where m is the number of rows and n is the number of columns in the matrix. This efficiency is achieved because the algorithm processes each row and column in a single pass, effectively discarding columns that do not contribute to the minima. - -### Space Complexity - -Regarding space complexity, SMAWK also requires **O(m+n)** additional space. This space is used for storing row and column indices, the reduced set of columns during processing, and result vectors that hold the minima for each row. - -Overall, the efficient time and space complexities make the SMAWK algorithm particularly well-suited for working with large matrices that have a totally monotonic property, enabling quick and effective results while minimizing computational overhead. - -### Limitations and Considerations - -The SMAWK algorithm, while efficient for certain types of problems, comes with its own set of limitations and considerations: - -**Matrix Requirements** : - -* The SMAWK algorithm requires the input matrix to be **totally monotone** , meaning that the minimum of each row must occur in a strictly increasing sequence down the columns. If the matrix does not satisfy this condition, the algorithm may produce incorrect results or fail to execute properly. - -**Handling Non-Monotone Matrices** : - -* If the input matrix is not totally monotone, the SMAWK algorithm cannot be applied directly. Alternative algorithms or preprocessing steps may be necessary to transform the matrix into a suitable form. - -**Implementation Complexity** : - -* While the theoretical performance is excellent, implementing the SMAWK algorithm correctly can be complex due to the intricate handling of indices and maintaining the monotonicity condition. Careful attention is needed to avoid errors such as segmentation faults or index out-of-bounds exceptions. - -**Practical Use Cases** : - -* The algorithm is particularly useful in specific scenarios like linear programming and optimization problems where matrices exhibit monotonic properties. However, it may not be the best choice for general-purpose matrix operations or for matrices where such properties are not guaranteed. - -**Memory Usage** : - -* The space complexity of **O(m+n)O(m + n)**O**(**m**+**n**)** , while efficient compared to other algorithms, can still be a concern with very large matrices. In situations where memory is limited, other strategies may need to be considered. - -**Scalability** : - -* While SMAWK is efficient for large matrices, it may not scale well if the problem constraints change, such as when the matrix becomes sparse or if different types of constraints are introduced. Alternative algorithms may perform better under those conditions. - -**Algorithm Assumptions** : - -* The algorithm assumes that the entire matrix fits into memory, which might not be feasible for extremely large datasets. In such cases, adaptations or different approaches, such as streaming algorithms, may be required. - -**C++ implementation :** - -**Output :** - -Enter number of rows and columns: 3 3 -Enter matrix elements (row by row): --1 -2 -3 --2 -3 -4 --3 -4 -5 -Row-wise minimum indices: -Row 0: Column 2 -Row 1: Column 2 -Row 2: Column 2 - -**Code :** - -```cpp -#include -#include -#include -using namespace std; - -bool is_totally_monotone(const vector>& matrix) { - int rows = matrix.size(); - int cols = matrix[0].size(); - for (int c = 1; c < cols; ++c) { - for (int r = 1; r < rows; ++r) { - if (matrix[r][c] < matrix[r - 1][c] && matrix[r][c - 1] > matrix[r - 1][c - 1]) { - return false; - } - } - } - return true; -} - -vector smawk_recursive(const vector& rows, const vector& cols, const vector>& matrix) { - if (rows.empty()) return {}; - - int rSize = rows.size(); - vector result(rSize, -1); - - vector reduced_cols; - for (int j : cols) { - while (!reduced_cols.empty() && matrix[rows.back()][j] <= matrix[rows.back()][reduced_cols.back()]) { - reduced_cols.pop_back(); - } - reduced_cols.push_back(j); - } - - for (size_t i = 0; i < rSize; ++i) { - if (i % 2 == 0) { - result[i] = reduced_cols.empty() ? -1 : reduced_cols[0]; - continue; - } - int min_col = -1; - for (int j : reduced_cols) { - if (min_col == -1 || matrix[rows[i]][j] < matrix[rows[i]][min_col]) { - min_col = j; - } - } - result[i] = min_col; - } - - return result; -} - -vector smawk(const vector>& matrix) { - int rows = matrix.size(); - int cols = matrix[0].size(); - - vector row_indices(rows); - vector col_indices(cols); - for (int i = 0; i < rows; ++i) row_indices[i] = i; - for (int i = 0; i < cols; ++i) col_indices[i] = i; - - return smawk_recursive(row_indices, col_indices, matrix); -} - -int main() { - int rows, cols; - cout << "Enter number of rows and columns: "; - cin >> rows >> cols; - - vector> matrix(rows, vector(cols)); - cout << "Enter matrix elements (row by row):\n"; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - cin >> matrix[i][j]; - } - } - - if (!is_totally_monotone(matrix)) { - cout << "The matrix is not totally monotone. SMAWK algorithm requires a totally monotone matrix.\n"; - return 1; - } - - vector minima_indices = smawk(matrix); - - cout << "Row-wise minimum indices is :\n"; - for (int i = 0; i < minima_indices.size(); ++i) { - cout << "Row " << i << ": Column " << minima_indices[i] << "\n"; - } - return 0; -} - -``` diff --git a/docs/Recursion/Sodoko.md b/docs/Recursion/Sodoko.md deleted file mode 100644 index 7891320da..000000000 --- a/docs/Recursion/Sodoko.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -id: Sudoko-problem-dsa -title: Sudoko Recursion -sidebar_label: Sudoko -sidebar_position: 4 -description: "The Sudoku problem is a popular puzzle where the objective is to fill a 9x9 grid with digits from 1 to 9 so that each column, each row, and each of the nine 3x3 subgrids contain all the digits from 1 to 9 without repetition." -tags: [sudoku, backtracking, recursion, puzzle-solving] ---- - - -## Sudoku Solver - -### Problem Statement: - - Given a 9x9 incomplete sudoku, solve it such that it becomes valid sudoku. Valid sudoku has the following properties. - - 1. All the rows should be filled with numbers(1 - 9) exactly once. - 2. All the columns should be filled with numbers(1 - 9) exactly once. - 3. Each 3x3 submatrix should be filled with numbers(1 - 9) exactly once. - - -## Approach: -- Let’s see the step by step approach. Our main recursive function(solve()) is going to just do a plain matrix traversal of the sudoku board. When we find an empty cell, we pause and try to put all available numbers(1 - 9) in that particular empty cell. -- We need another loop to do that. But wait, we forgot one thing - the board has to satisfy all the conditions, right? So, for that we have another function(isValid()) which will check whether the number we have inserted into that empty cell will not violate any conditions. -- If it is violating, we try with the next number. If it is not, we call the same function recursively, but this time with the updated state of the board. Now, as usual it tries to fill the remaining cells in the board in the same way. -- Now we'll come to the returning values. If at any point we cannot insert any numbers from 1 - 9 in a particular cell, it means the current state of the board is wrong and we need to backtrack. An important point to follow is, we need to return false to let the parent function(which is called this function) know that we cannot fill this way. This will serve as a hint to that function, that it needs to try with the next possible number. Refer to the picture below. - -### C++ implementation - -```cpp -#include -#include -using namespace std; -bool isValid(vector < vector < char >> & board, int row, int col, char c) { - for (int i = 0; i < 9; i++) { - if (board[i][col] == c) - return false; - - if (board[row][i] == c) - return false; - - if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) - return false; - } - return true; -} - -bool solveSudoku(vector < vector < char >> & board) { - for (int i = 0; i < board.size(); i++) { - for (int j = 0; j < board[0].size(); j++) { - if (board[i][j] == '.') { - for (char c = '1'; c <= '9'; c++) { - if (isValid(board, i, j, c)) { - board[i][j] = c; - - if (solveSudoku(board)) - return true; - else - board[i][j] = '.'; - } - } - - return false; - } - } - } - return true; -} -int main() { - vector>board{ - {'9', '5', '7', '.', '1', '3', '.', '8', '4'}, - {'4', '8', '3', '.', '5', '7', '1', '.', '6'}, - {'.', '1', '2', '.', '4', '9', '5', '3', '7'}, - {'1', '7', '.', '3', '.', '4', '9', '.', '2'}, - {'5', '.', '4', '9', '7', '.', '3', '6', '.'}, - {'3', '.', '9', '5', '.', '8', '7', '.', '1'}, - {'8', '4', '5', '7', '9', '.', '6', '1', '3'}, - {'.', '9', '1', '.', '3', '6', '.', '7', '5'}, - {'7', '.', '6', '1', '8', '5', '4', '.', '9'} - }; - - solveSudoku(board); - - for(int i= 0; i< 9; i++){ - for(int j= 0; j< 9; j++) - cout< -#include -#include -using namespace std; - -string determineWinner(char userChoice, char computerChoice) { - if (userChoice == computerChoice) { - return "Draw"; - } else if ((userChoice == 's' && computerChoice == 'p') || - (userChoice == 'p' && computerChoice == 'r') || - (userChoice == 'r' && computerChoice == 's')) { - return "Computer wins"; - } else { - return "User wins"; - } -} - -void playGame(int rounds, int &userWins, int &computerWins) { - if (rounds == 0) { - if (userWins > computerWins) { - cout << "User wins the game with " << userWins << " wins!" << endl; - } else if (computerWins > userWins) { - cout << "Computer wins the game with " << computerWins << " wins!" << endl; - } else { - cout << "It's a tie game!" << endl; - } - return; - } - - char userChoice; - cout << "Enter your choice (r for rock, p for paper, s for scissors): "; - cin >> userChoice; - - srand(time(0)); - int randomChoice = rand() % 3; - char computerChoice = (randomChoice == 0) ? 'r' : (randomChoice == 1) ? 'p' : 's'; - - cout << "Computer chose: " << computerChoice << endl; - - string roundResult = determineWinner(userChoice, computerChoice); - cout << roundResult << endl; - - if (roundResult == "User wins") { - userWins++; - } else if (roundResult == "Computer wins") { - computerWins++; - } - - playGame(rounds - 1, userWins, computerWins); -} - -int main() { - int rounds; - cout << "Welcome to Stone Paper Scissors Game!" << endl; - cout << "Enter the number of rounds: "; - cin >> rounds; - - int userWins = 0, computerWins = 0; - - playGame(rounds, userWins, computerWins); - - return 0; -} - -``` diff --git a/docs/Recursion/TowersOfHanoi.md b/docs/Recursion/TowersOfHanoi.md deleted file mode 100644 index 201eb6a29..000000000 --- a/docs/Recursion/TowersOfHanoi.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -id: Towers-of-Hanoi-dsa -title: Towers of Hanoi Recursion -sidebar_label: Towers of Hanoi -sidebar_position: 7 -description: "The Towers of Hanoi problem involves moving a stack of n disks from one rod to another, following specific rules. The problem is often solved using backtracking, a form of recursion." -tags: [towers-of-hanoi, recursion, dsa] ---- - -## Towers of Hanoi Problem | Return the Sequence of Moves to Solve the Puzzle - -- Problem Statement: The Towers of Hanoi problem consists of three rods and a number of disks of different sizes. Initially, all the disks are stacked on the first rod in ascending order of size. The objective is to move the entire stack to the last rod, obeying the following rules: -1. Only one disk can be moved at a time. -2. A disk can only be placed on top of a larger disk or on an empty rod. -3. A disk can only be moved from the top of its current rod to the top of another rod. - -```cpp -#include -#include -#include -using namespace std; - -class TowersOfHanoi { - public: - // Method to solve the Towers of Hanoi problem recursively - void solveHanoi(int n, char source, char destination, char auxiliary, vector &moves) { - // Base case: if there is only one disk, move it from source to destination - if (n == 1) { - moves.push_back("Move disk 1 from " + string(1, source) + " to " + string(1, destination)); - return; - } - - // Move the top (n-1) disks from source to auxiliary rod using destination as an intermediate - solveHanoi(n - 1, source, auxiliary, destination, moves); - - // Move the nth disk from source to destination rod - moves.push_back("Move disk " + to_string(n) + " from " + string(1, source) + " to " + string(1, destination)); - - // Move the (n-1) disks from auxiliary rod to destination rod using source as an intermediate - solveHanoi(n - 1, auxiliary, destination, source, moves); - } - - public: - // Method to return the sequence of moves to solve the Towers of Hanoi problem - vector getHanoiMoves(int n) { - vector moves; - solveHanoi(n, 'A', 'C', 'B', moves); // Initial rods: 'A' (source), 'C' (destination), 'B' (auxiliary) - return moves; - } -}; - -int main() { - int n = 3; // Number of disks - TowersOfHanoi obj; - vector moves = obj.getHanoiMoves(n); - - // Display the sequence of moves - cout << "Towers of Hanoi solution for " << n << " disks:" << endl; - for (int i = 0; i < moves.size(); i++) { - cout << "Step " << i + 1 << ": " << moves[i] << endl; - } - return 0; -} -``` \ No newline at end of file diff --git a/docs/Recursion/Unwinding_in_recursion.md b/docs/Recursion/Unwinding_in_recursion.md deleted file mode 100644 index f05ab72e3..000000000 --- a/docs/Recursion/Unwinding_in_recursion.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: unwinding-in-recursion -title: Unwinding in Recursion -sidebar_label: Unwinding in recursion -sidebar_position: 3 -description: "Unwinding in recursion is the phase where recursive calls return back up the call stack, resolving each call step by step in reverse order" -tags: [recursion, algorithms, dsa,unwinding] ---- - - -### Understanding Unwinding in Recursive Functions - -**Unwinding** in recursion refers to the phase in which the recursive calls start returning back up the call stack. This process is crucial for understanding how recursive functions complete their execution. When a function makes a recursive call, it typically "winds up" by going deeper into successive calls until it hits a base case. Once the base case is reached, the function begins "unwinding," resolving each call step by step in reverse order. - -### Unwinding in Practical Terms - -1. **Winding Phase**: The function keeps making recursive calls until it reaches the simplest case, usually called the base case. -2. **Unwinding Phase**: The function begins returning from the base case, using the results of deeper calls to resolve each level of recursion in reverse order. - -### Example 1: Computing Factorial with Unwinding - -Consider the classic factorial function, which is a common example used to illustrate recursion. Here, we observe both the winding and unwinding phases. - -```cpp -#include -using namespace std; - -int factorial(int n) { - if (n <= 1) { - return 1; // Base case: returns 1 when n is 1 or 0 - } - return n * factorial(n - 1); // Recursive call -} - -int main() { - int num = 5; - cout << "Factorial of " << num << " is: " << factorial(num) << endl; - return 0; -} -``` - -**Explanation**: -- **Winding**: `factorial(5)` calls `factorial(4)`, which calls `factorial(3)`, and so on until `factorial(1)` is reached. -- **Unwinding**: As each call returns, the results are multiplied: `1`, then `1 * 2 = 2`, then `2 * 3 = 6`, and so forth until `120`. - -### Example 2: Reversing a String Using Recursion - -String reversal is a great example to illustrate unwinding. The string is broken down character by character in the winding phase and then reconstructed in reverse order during the unwinding phase. - -#### C++ Implementation - -```cpp -#include -using namespace std; - -void reverseString(string& str, int index) { - if (index == 0) { - cout << str[0]; // Base case: print the first character - return; - } - cout << str[index]; // Print the current character - reverseString(str, index - 1); // Recursive call with reduced index -} - -int main() { - string input = "Recursion"; - cout << "Reversed string: "; - reverseString(input, input.length() - 1); - cout << endl; - return 0; -} -``` - -**Explanation**: -- **Winding**: The function continues calling itself with a decreasing index until it reaches `index = 0`. -- **Unwinding**: The characters are printed in reverse order as the function returns from each call. - -#### Python Implementation - -```python -def reverse_string(s, index): - if index == 0: - print(s[0], end="") # Base case: print the first character - return - print(s[index], end="") # Print the current character - reverse_string(s, index - 1) # Recursive call with reduced index - -# Example usage -input_str = "Recursion" -print("Reversed string: ", end="") -reverse_string(input_str, len(input_str) - 1) -print() -``` - -**Explanation**: -- The Python version similarly winds down until it reaches the base case and then unwinds to print each character in reverse. - -### Example 3: Ackermann Function (With a Focus on Unwinding) - -The Ackermann function, known for its deeply recursive structure, can also help demonstrate the concept of unwinding. The function makes multiple recursive calls, and the unwinding process is highly non-trivial. - -#### C++ Implementation - -```cpp -#include -using namespace std; - -int ackermann(int m, int n) { - if (m == 0) { - return n + 1; // Base case - } - if (m > 0 && n == 0) { - return ackermann(m - 1, 1); // Reduce m and reset n - } - return ackermann(m - 1, ackermann(m, n - 1)); // Nested recursive call -} - -int main() { - int m = 2, n = 3; - cout << "Ackermann(" << m << ", " << n << ") = " << ackermann(m, n) << endl; - return 0; -} -``` - -**Explanation**: -- **Winding**: The function makes several nested recursive calls until `m = 0` is reached. -- **Unwinding**: The function then begins returning values back up, resolving each recursive call. - -### Understanding Unwinding in Recursion - -1. **Function Calls**: Each recursive call adds a new frame to the call stack. -2. **Returning Values**: As the function unwinds, these frames are resolved, and values are returned step by step. -3. **Memory Consumption**: Deep recursion can consume significant memory due to the call stack growing with each winding step. - -### Benefits and Limitations of Unwinding - -- **Benefits**: Unwinding allows recursive algorithms to construct results elegantly, especially when solving problems like tree traversal, string reversal, or complex mathematical functions. -- **Limitations**: Deep unwinding may lead to stack overflow errors if the recursion depth exceeds the system's limits, highlighting the importance of understanding recursion's computational costs. - ---- diff --git a/docs/Recursion/VoseAlias.md b/docs/Recursion/VoseAlias.md deleted file mode 100644 index 72c472a5e..000000000 --- a/docs/Recursion/VoseAlias.md +++ /dev/null @@ -1,252 +0,0 @@ ---- -id: vose-alias -title: Vose Alias Method -sidebar_label: Generate Vose Alias Method Via Recursion -description: "The Recursive Vose's Alias Method is an efficient algorithm for fast random sampling from discrete probability distributions. With O(n) preprocessing and O(1) sampling, it's ideal for non-uniform distributions, widely used in areas like computer graphics, machine learning, and simulations. Perfect for applications needing quick, reliable sampling." -tags: [VoseAlias, recursion, dsa] ---- -## Vose Alias Via Recursion - -**Problem Statement:** - -In many applications, there is a need to sample randomly from a discrete probability distribution where each outcome has a different likelihood of being selected. Traditional methods of sampling, such as using inverse transform sampling or rejection sampling, can be inefficient, especially when dealing with large datasets or non-uniform distributions. - -The challenge is to develop an efficient algorithm that allows for quick sampling from a given set of probabilities while ensuring that the probabilities are accurately represented. Specifically, the algorithm should: - -1. Accept a set of probabilities that sum to 1, ensuring that they form a valid discrete probability distribution. -2. Build a data structure that allows for fast sampling of outcomes based on their respective probabilities. -3. Achieve a preprocessing time that scales linearly with the number of outcomes (O(n)), followed by constant-time (O(1)) sampling operations. -4. Handle edge cases, such as invalid probability inputs (e.g., probabilities not summing to 1) and extreme values (e.g., very small or very large probabilities). - -The goal is to create the **Recursive Vose's Alias Method** , which meets these requirements, allowing for efficient and accurate random sampling from arbitrary discrete probability distributions. This method will be particularly useful in scenarios such as computer graphics, machine learning, and simulations, where the need for rapid and reliable sampling is paramount. - -#### Explanation: - -The **Recursive Vose's Alias Method** is an advanced algorithm for efficient sampling from discrete probability distributions. It is particularly effective when dealing with non-uniform probabilities, enabling rapid selection of outcomes based on their respective likelihoods. Here’s a step-by-step explanation of how the method works: - -#### 1. **Input Probabilities** : - -* The algorithm starts by accepting a set of probabilities that represent the likelihood of each outcome. These probabilities must sum to 1 to ensure they form a valid probability distribution. For example, if there are four outcomes with probabilities of 0.1, 0.2, 0.3, and 0.4, the total should equal 1. - -#### 2. **Initialization** : - -* The method initializes two main structures: - * **Alias Table** : This will store the alias for each outcome, allowing for quick sampling. - * **Probability Table** : This holds the adjusted probabilities for each outcome, ensuring that each entry is either exactly 1/n or less. - -#### 3. **Categorization of Probabilities** : - -* The probabilities are divided into two lists: - * **Small List** : Contains probabilities less than `1/n`, where `n` is the number of outcomes. - * **Large List** : Contains probabilities greater than or equal to `1/n`. -* This classification is crucial for balancing the probabilities in the alias table. - -#### 4. **Recursive Construction** : - -* The algorithm utilizes a recursive approach to build the alias table. It follows these steps: - * For each probability in the small list, an alias from the large list is assigned. - * The probability of the selected alias is adjusted by transferring some of its weight to the small probability. - * If the adjusted alias probability drops below `1/n`, it moves to the small list for further processing. -* This process continues until all probabilities are appropriately assigned in the alias table. - -#### 5. **Sampling** : - -* Once the alias table is constructed, the sampling process is straightforward: - * Generate a random index to select an outcome. - * Generate another random number to decide whether to return the selected outcome or its alias. - * This results in a random selection that respects the original probability distribution. - -#### 6. **Efficiency** : - -* The preprocessing step takes **O(n)** time to construct the alias and probability tables, making it scalable for large datasets. -* The actual sampling operation is performed in **O(1)** time, allowing for rapid selection of outcomes, which is crucial in applications that require numerous samples in a short time. - -#### 7. **Applications** : - -* This method is widely applicable in various fields: - * **Computer Graphics** : For generating textures or selecting random elements in simulations. - * **Machine Learning** : In reinforcement learning algorithms, where sampling from distributions is common. - * **Simulations** : Where multiple random samples from different distributions are required quickly. - -**Example 1: Basic Probability Distribution** - -**Input:** - -* Number of Outcomes: **4** -* Probabilities: `0.1, 0.2, 0.3, 0.4` - -**Steps:** - -1. **Check Sum:** The sum of probabilities is `0.1 + 0.2 + 0.3 + 0.4 = 1.0` (valid). -2. **Initialization:** Create two lists `small` and `large`: - * `Small` list: [0.1, 0.2] (both < 0.25) - * `Large` list: [0.3, 0.4] (both ≥ 0.25) -3. **Construct Alias Table:** - * Pair elements from `small` and `large`. - * Resulting Alias Table: `[(0, 3), (1, 2), (2, 1), (3, 0)]` with probabilities adjusted accordingly. -4. **Sampling:** - * Randomly select an index and use the alias to sample outcomes based on their probabilities. - -**Output:** - -* The algorithm will sample outcomes, returning each outcome according to the defined probabilities. - -#### Complexity : - -The **Recursive Vose's Alias Method** boasts a highly efficient complexity profile, making it an attractive choice for random sampling from discrete probability distributions. The preprocessing phase of the algorithm operates in **O(n)** time, where **n** is the number of outcomes. This efficiency stems from the linear time required to construct the alias and probability tables, which involves categorizing the probabilities into small and large lists and then systematically pairing them. Once the preprocessing is complete, the sampling operation is performed in **O(1)** time, allowing for rapid selection of outcomes based on their probabilities. This combination of linear preprocessing and constant-time sampling ensures that the method is well-suited for scenarios requiring frequent and fast random sampling, particularly in applications like computer graphics, machine learning, and simulations. Overall, the Recursive Vose's Alias Method effectively balances computational efficiency with ease of implementation, making it a valuable tool for efficiently sampling from complex probability distributions. - -### Limitations and Considerations - -While the Recursive Vose's Alias Method is a powerful tool for efficient sampling from discrete probability distributions, there are some limitations and considerations to keep in mind: - -**Input Requirements** : - -* The algorithm requires that the input probabilities sum to exactly 1.0. If the probabilities are not normalized, additional steps are needed to handle normalization, which may add overhead. - -**Fixed Number of Outcomes** : - -* The method is designed for fixed discrete outcomes, making it less suitable for dynamic distributions where outcomes may change frequently. If the underlying probabilities or the number of outcomes change, the alias table must be reconstructed, leading to a potential performance hit. - -**Memory Usage** : - -* The alias method requires additional memory for the alias and probability tables, which can be a concern in memory-constrained environments or when dealing with a very large number of outcomes. The space complexity is **O(n)** , which, while efficient, may still be significant for large datasets. - -**Numerical Stability** : - -* In cases where probabilities are very small or very large, there could be issues related to numerical precision. This may affect the accuracy of the sampling, particularly in programming languages or environments with limited floating-point precision. - -**Complexity of Implementation** : - -* Although the algorithm is conceptually straightforward, implementing it correctly can be complex, especially for beginners. Understanding the recursive structure and ensuring that probabilities are accurately represented in the alias table can require careful attention to detail. - -**Non-Uniformity** : - -* While the algorithm excels with non-uniform distributions, extreme variations in probabilities (e.g., one probability being significantly larger than others) might still lead to inefficiencies in certain edge cases, particularly if the distribution is highly skewed. - -**Sampling Distribution** : - -* The method is designed specifically for discrete distributions. If you need to sample from continuous distributions, other techniques like rejection sampling or stratified sampling may be more appropriate. - -**Concurrency Issues** : - -* In multithreaded environments, care must be taken to manage access to the alias and probability tables, as concurrent modifications may lead to inconsistent states unless proper synchronization mechanisms are employed. - -**C++ implementation :** - -**Output :** - -Enter the number of probabilities: 5 -Enter the probabilities (space-separated, must sum to 1): -0.1 0.2 0.25 0.15 0.3 -Sampled index: 3 - -Enter the number of probabilities: 4 -Enter the probabilities (space-separated, must sum to 1): -0.1 0.2 0.3 0.4 -Sampled index: 3 - -**Code :** - -```cpp -#include -#include -#include -struct AliasTable { - std::vector alias; - std::vector prob; - int n; -}; - -AliasTable* initAliasTable(int n) { - AliasTable* table = new AliasTable(); - table->alias.resize(n); - table->prob.resize(n); - table->n = n; - return table; -} - -void freeAliasTable(AliasTable* table) { - delete table; // Automatic cleanup of vector memory -} - -void buildAliasTableRecursively(std::vector& small, std::vector& large, AliasTable* table, std::vector& prob) { - int smallSize = small.size(); - int largeSize = large.size(); - - while (smallSize > 0 && largeSize > 0) { - int l = small.back(); - small.pop_back(); - int g = large.back(); - large.pop_back(); - - table->prob[l] = prob[l] * table->n; - table->alias[l] = g; - - prob[g] = prob[g] + prob[l] - 1.0 / table->n; - - if (prob[g] < 1.0 / table->n) { - small.push_back(g); - } else { - large.push_back(g); - } - - smallSize = small.size(); - largeSize = large.size(); - } -} - -AliasTable* createAliasTable(std::vector& prob, int n) { - AliasTable* table = initAliasTable(n); - std::vector small, large; - - for (int i = 0; i < n; i++) { - if (prob[i] < 1.0 / n) { - small.push_back(i); - } else { - large.push_back(i); - } - } - - buildAliasTableRecursively(small, large, table, prob); - - return table; -} - -int sampleAlias(AliasTable* table) { - int i = rand() % table->n; - return (static_cast(rand()) / RAND_MAX < table->prob[i]) ? i : table->alias[i]; -} - -int main() { - int n; - - std::cout << "Enter the number of probabilities: "; - std::cin >> n; - - if (n <= 0) { - std::cout << "Invalid number of probabilities.\n"; - return 1; - } - - std::vector prob(n); - double sum = 0.0; - - std::cout << "Enter the probabilities (space-separated, must sum to 1):\n"; - for (int i = 0; i < n; i++) { - std::cin >> prob[i]; - sum += prob[i]; - } - - if (sum < 0.999 || sum > 1.001) { - std::cout << "Error: Probabilities must sum to 1. Sum provided: " << sum << std::endl; - return 1; - } - - AliasTable* aliasTable = createAliasTable(prob, n); - std::cout << "Sampled index: " << sampleAlias(aliasTable) << std::endl; - - freeAliasTable(aliasTable); - return 0; -} - -``` diff --git a/docs/Recursion/WaterJug.md b/docs/Recursion/WaterJug.md deleted file mode 100644 index 55924e880..000000000 --- a/docs/Recursion/WaterJug.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -id: water-jug -title: Water Jug Problem Using Recursion -sidebar_label: Generate Water Jug Problem Solution -description: "The Recursive Water Jug Problem Solver is an engaging algorithmic approach to a classic puzzle involving two jugs of different capacities. This solver efficiently utilizes recursion to explore all possible states, allowing users to achieve a specific target volume of water through a series of defined operations, such as filling, pouring, and emptying the jugs. Ideal for computer science enthusiasts and learners, this solution highlights the power of recursive problem-solving techniques while demonstrating state management and optimization strategies. Whether you're looking to deepen your understanding of algorithms or tackle a fascinating combinatorial challenge, the Recursive Water Jug Problem Solver offers a practical and insightful experience." -tags: [WaterJug, recursion, dsa] ---- - -## Water Jug Problem Via Recursion - -**Problem Statement:** - -You are given two jugs with different capacities: Jug A with a maximum capacity of mm**m** liters and Jug B with a maximum capacity of nn**n** liters. You also have an unlimited supply of water. The objective is to measure exactly dd**d** liters of water using these two jugs by performing a series of allowed operations. - -**Allowed Operations** : - -1. Fill Jug A completely. -2. Fill Jug B completely. -3. Empty Jug A. -4. Empty Jug B. -5. Pour water from Jug A to Jug B until Jug B is full or Jug A is empty. -6. Pour water from Jug B to Jug A until Jug A is full or Jug B is empty. - -**Constraints** : - -- You must find a sequence of operations that leads to exactly d liters of water in either jug. -- The target volume d must be less than or equal to the maximum capacity of either Jug A or Jug B i.e. d≤max⁡(m,n). -- It is assumed that both jugs are initially empty. - - **Output** : - -- The algorithm should output the sequence of operations required to achieve exactly d liters in one of the jugs or indicate if it is impossible to measure that amount given the initial capacities. - -### Example: - -**Given** : - -- Jug A capacity: 5 liters -- Jug B capacity: 3 liters -- Target amount: 4 liters - - **Expected Output** : - -- Sequence of operations to achieve 4 liters in one of the jugs: - 1. Fill Jug A (5 liters in Jug A, 0 liters in Jug B) - 2. Pour from Jug A to Jug B (2 liters in Jug A, 3 liters in Jug B) - 3. Empty Jug B (2 liters in Jug A, 0 liters in Jug B) - 4. Pour from Jug A to Jug B (0 liters in Jug A, 2 liters in Jug B) - 5. Fill Jug A (5 liters in Jug A, 2 liters in Jug B) - 6. Pour from Jug A to Jug B (4 liters in Jug A, 3 liters in Jug B) - -This problem not only challenges the solver's algorithmic thinking but also serves as a practical example of using recursion to explore state spaces effectively. - -### Explanation of the Recursive Water Jug Problem Solver - -The Recursive Water Jug Problem Solver tackles a classic algorithmic challenge that involves measuring a specific volume of water using two jugs of different capacities. The solution employs a recursive approach to explore all possible states of the jugs and determine the sequence of operations needed to achieve the target volume. Here’s a breakdown of how the algorithm works: - -1. **Initial State** : - -- Start with both jugs empty: Jug A=0 liters, Jug B=0 liters. -- Define the maximum capacities of the jugs: Jug A with m liters and Jug B with n liters. -- Set the target volume d liters that you want to measure. - -1. **Allowed Operations** : - The algorithm can perform several operations to manipulate the water levels in the jugs: - -- **Fill Jug A** : Set the amount in Jug A to m. -- **Fill Jug B** : Set the amount in Jug B to n. -- **Empty Jug A** : Set the amount in Jug A to 0. -- **Empty Jug B** : Set the amount in Jug B to 0. -- **Pour from Jug A to Jug B** : Transfer water from Jug A to Jug B until Jug B is full or Jug A is empty. -- **Pour from Jug B to Jug A** : Transfer water from Jug B to Jug A until Jug A is full or Jug B is empty. - -**Recursive Exploration** : - -- The core of the algorithm is a recursive function that takes the current state of the jugs as input. -- Each recursive call attempts to apply all possible operations, generating new states of the jugs. -- For each new state, the function checks if it matches the target volume d: - - If a jug contains exactly d liters, the algorithm has successfully found a solution. - - If not, the function continues to explore further states by recursively calling itself. - -**Base Case and Termination** : - -- The base case of the recursion is when the target volume d is found in either jug. -- If all possible states have been explored without finding the target volume, the algorithm concludes that it is impossible to measure d liters with the given jug capacities. - -**Visited States** : - -- To optimize the algorithm and avoid infinite loops, a set of visited states can be maintained. This set tracks which combinations of water amounts in the jugs have already been processed. -- If a state has already been visited, the algorithm does not explore it again. - -**Output** : - -- The algorithm returns the sequence of operations leading to the target amount, including each step taken (e.g., filling, pouring, or emptying the jugs). -- If the target volume cannot be achieved, the algorithm informs the user that it is impossible based on the initial capacities and the desired measurement. - -### Time and Space Complexity - -The time complexity of the **Recursive Water Jug Problem Solver** primarily depends on the number of distinct states that can be generated based on the capacities of the two jugs. Each jug can hold a maximum of m and n liters respectively, which means the total number of possible states is O(m×n) The algorithm explores each state through recursive calls, applying all possible operations for each state. In the worst case, the algorithm may end up visiting all possible states before determining whether the target volume can be achieved, leading to a time complexity of O(m×n). - -The space complexity is influenced by the depth of the recursion and the storage of visited states. In the worst-case scenario, the maximum depth of the recursion can reach O(m+n) (the sum of the capacities), as each call corresponds to a unique state of the jugs. Additionally, the algorithm maintains a set of visited states, which can also grow up to O(m×n). Therefore, the overall space complexity is O(m×n) due to the storage of state information and the recursion stack. - -In summary, the algorithm operates with a time complexity of O(m×n) and a space complexity of O(m×n) , making it efficient for reasonably sized jug capacities but potentially challenging for very large values of m and n. - -### Limitations and Considerations - -The **Recursive Water Jug Problem Solver** presents an elegant approach to solving the jug problem but has several limitations and considerations that users should be aware of: - -1. **Scalability** : The algorithm's time and space complexity is O(m×n) which means that it can become inefficient with larger jug capacities. For significantly large values of m and n, the number of possible states can grow rapidly, leading to increased computation time and memory usage. -2. **Integer Volumes Only** : This solution is designed to work with integer capacities and target volumes. It does not handle scenarios involving fractional measurements or capacities, which may limit its applicability in real-world problems that require precise measurements. -3. **Exhaustive Search** : The recursive approach explores all possible states, which can lead to performance issues in cases where the target volume is unreachable. While the visited set mitigates some inefficiency, the algorithm still performs exhaustive searching, which may not be optimal for more complex or larger-scale problems. -4. **Lack of Optimization** : The basic algorithm does not implement any heuristic methods or optimization strategies to guide the search process more efficiently. This may result in unnecessary exploration of states that do not contribute to reaching the target volume. -5. **Stack Overflow Risk** : The recursive nature of the algorithm poses a risk of stack overflow errors for very deep recursive calls, especially in environments with limited stack size. Iterative approaches or tail recursion optimizations could be considered as alternatives to mitigate this issue. -6. **User Input Validation** : The algorithm assumes valid input for jug capacities and the target volume. It does not handle invalid scenarios (e.g., negative capacities, non-integer values) gracefully, which may lead to unexpected behavior or errors. -7. **Target Volume Feasibility** : The algorithm does not inherently check if the target volume d is feasible based on the capacities of the jugs (e.g., using the greatest common divisor). Users should validate that d can be achieved before executing the algorithm, as certain combinations of m and n may make it impossible to reach dd**d**. - -**C++ implementation :** - -**Output :** - -Enter the capacity of Jug 1: 5 -Enter the capacity of Jug 2: 3 -Enter the target amount of water: 4 -Steps to measure 4 liters: -Fill Jug 1 -Fill Jug 2 -Empty Jug 1 -Pour Jug 2 into Jug 1 -Fill Jug 2 -Pour Jug 2 into Jug 1 -Empty Jug 1 -Pour Jug 2 into Jug 1 -Fill Jug 2 -Pour Jug 2 into Jug 1 - -**Code :** - -```cpp -#include -#include -#include -#include - -using namespace std; - -bool waterJugSolver(int jug1, int jug2, int target, int current1, int current2, - set>& visited, vector& steps) { - if (current1 == target || current2 == target) { - return true; - } - if (visited.count(make_tuple(current1, current2))) { - return false; - } - visited.insert(make_tuple(current1, current2)); - - steps.push_back("Fill Jug 1"); - if (waterJugSolver(jug1, jug2, target, jug1, current2, visited, steps)) { - return true; - } - steps.pop_back(); - - steps.push_back("Fill Jug 2"); - if (waterJugSolver(jug1, jug2, target, current1, jug2, visited, steps)) { - return true; - } - steps.pop_back(); - - steps.push_back("Empty Jug 1"); - if (waterJugSolver(jug1, jug2, target, 0, current2, visited, steps)) { - return true; - } - steps.pop_back(); - - steps.push_back("Empty Jug 2"); - if (waterJugSolver(jug1, jug2, target, current1, 0, visited, steps)) { - return true; - } - steps.pop_back(); - - int pour1to2 = min(current1, jug2 - current2); - steps.push_back("Pour Jug 1 into Jug 2"); - if (waterJugSolver(jug1, jug2, target, current1 - pour1to2, current2 + pour1to2, visited, steps)) { - return true; - } - steps.pop_back(); - - int pour2to1 = min(current2, jug1 - current1); - steps.push_back("Pour Jug 2 into Jug 1"); - if (waterJugSolver(jug1, jug2, target, current1 + pour2to1, current2 - pour2to1, visited, steps)) { - return true; - } - steps.pop_back(); - - return false; -} - -int main() { - int jug1, jug2, target; - - cout << "Enter the capacity of Jug 1: "; - cin >> jug1; - cout << "Enter the capacity of Jug 2: "; - cin >> jug2; - cout << "Enter the target amount of water: "; - cin >> target; - - if (target > max(jug1, jug2) || target < 0) { - cout << "Target volume is not achievable with the given jug capacities." << endl; - return 0; - } - - set> visited; - vector steps; - - if (waterJugSolver(jug1, jug2, target, 0, 0, visited, steps)) { - cout << "Steps to measure " << target << " liters:" << endl; - for (const string& step : steps) { - cout << step << endl; - } - } else { - cout << "No solution exists to measure " << target << " liters." << endl; - } - - return 0; -} - -``` diff --git a/docs/Recursion/_category_.json b/docs/Recursion/_category_.json deleted file mode 100644 index 035ea68fa..000000000 --- a/docs/Recursion/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Recursion", - "position": 7, - "link": { - "type": "generated-index", - "description": "Recursion is a programming technique where a function calls itself directly or indirectly in order to solve a larger problem by breaking it down into smaller, more manageable sub-problems. It is commonly used in algorithms involving divide and conquer strategies, tree traversal, and dynamic programming." - } -} diff --git a/docs/Recursion/catalannumber.md b/docs/Recursion/catalannumber.md deleted file mode 100644 index 1d37d3ebd..000000000 --- a/docs/Recursion/catalannumber.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -id: catalan-number -title: Catalan Number Using Recursion -sidebar_label: Generate Catalan Number -description: "The Catalan number sequence is a cornerstone in combinatorics, often arising in problems like counting valid parentheses expressions, binary search trees, and polygon triangulations." -tags: [CatalanNumber, recursion, dsa] ---- - -**Problem Statement:** - -Catalan numbers are a sequence of natural numbers with numerous applications in combinatorics. They are defined based on recursive relationships and can be interpreted in problems involving counting structures like valid sequences of parentheses, binary search trees, paths in grids, and polygon triangulations. - -For example: - -**Balanced Parentheses:** The nth Catalan number counts how many valid ways to arrange `n` pairs of parentheses. For `n = 3`, there are 5 valid sequences: `((())), ()(()), (())(), ()()(), (()())`. - -**Binary Search Trees:** It represents the number of distinct binary search trees that can be constructed with `n` distinct elements. - -**Recursive Definition:** - -The recursive formula for Catalan numbers is: - -$C(n) [i=0 to n−1] = [C(i)×C(n−i−1)]$ with the base case C(0)=1. - -## Explanation: - -- The recursive nature reflects how larger structures can be built from smaller ones. For example, in the case of valid parentheses sequences, placing a pair of parentheses at the outermost positions leaves a smaller valid subsequence inside and another valid subsequence after the outer parentheses. -- This recursive division is mirrored in the summation, where C(i) represents the number of valid structures in the left subsequence, and C(n−i−1) represents the right subsequence. - -## Complexity : - -**Dynamic Programming:** A more efficient approach is to use **dynamic programming** to store the results of previous computations in a table and reuse them, reducing the time complexity to $O(n^2)$. This avoids recalculating previously computed values and significantly improves performance. - -**Closed-Form Formula:** Another alternative is to use the closed-form formula for Catalan numbers : - -$C(n) = ( 1/n+1 ) \* ( 2n )$ - -Using this formula with precomputed binomial coefficients can provide a faster, non-recursive solution with $O(n)$ time complexity - -### Limitations and Considerations - -1. **Performance:** For larger values of `n`, the recursive approach will take significantly longer to compute. This is because of the exponential time complexity and the repeated computation of subproblems. -2. **Optimization:** If efficiency is a concern, switching to dynamic programming or using the closed-form formula is recommended for values of `n` larger than 20. These methods reduce the computational overhead and are more practical for larger inputs. -3. **Stack Depth:** Recursive approaches are also limited by the system's recursion depth limit, which may cause a stack overflow for very large values of `n` (though this is less of a concern for values up to 20). - -**C++ implementation :** - -**Output:** -``` -Enter a value for n: 3 -Catalan number C_3 is 5 -``` -``` -Enter a value for n: 5 -Catalan number C_5 is 42 -``` -**Code:** - -```cpp - #include - -unsigned long long catalan(int n) -{ - if (n == 0) - return 1; - - unsigned long long result = 0; - - for (int i = 0; i < n; i++) - { - result += catalan(i) * catalan(n - 1 - i); - } - - return result; -} - -int main() -{ - int n; - - std::cout << "Enter a value for n: "; - std::cin >> n; - - if (n < 0) - { - std::cout << "n must be a non-negative integer." << std::endl; - return 1; - } - - std::cout << "Catalan number C_" << n << " is " << catalan(n) << std::endl; - - return 0; -} - -``` diff --git a/docs/Recursion/fibonacci.md b/docs/Recursion/fibonacci.md deleted file mode 100644 index 3d27137f4..000000000 --- a/docs/Recursion/fibonacci.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -id: fibonacci-recursion -title: Generate Fibonacci Sequence with Recursion -sidebar_label: Fibonacci Recursion -sidebar_position: 2 -description: "This post explores generating the Fibonacci sequence using recursion. We'll delve into the recursive approach and provide code implementations in multiple languages, including C++, Java, Python, JavaScript, and Go." -tags: [recursion, fibonacci, algorithms] ---- - -## Fibonacci Sequence with Recursion - -The Fibonacci sequence is a famous series of numbers where each number is the sum of the two preceding numbers. Starting from 0 and 1, the sequence goes like this: - -0, 1, 1, 2, 3, 5, 8, 13, 21, ... - -This sequence has numerous applications in mathematics, computer science, and even nature. Here, we'll implement a recursive approach to generate the Fibonacci sequence. - -### Recursive Approach - -Recursion is a programming technique where a function calls itself. In the context of the Fibonacci sequence, we can define a function that takes an integer `n` as input and returns the `n`th Fibonacci number. - -The recursive definition can be broken down as follows: - -- **Base Case:** If `n` is 0 or 1, the corresponding Fibonacci numbers are 0 and 1, respectively. -- **Recursive Case:** For `n` greater than 1, the `n`th Fibonacci number is the sum of the `(n-1)`th and `(n-2)`th Fibonacci numbers. - -This approach leverages the fact that each Fibonacci number depends on the two preceding ones. - -### Code Implementation - -Here's the code implementation in various languages: - -**C++** - -```c++ -#include - -int fibonacci(int n) { - if (n <= 1) { - return n; - } else { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} - -int main() { - int n; - std::cout << "Enter the number of terms: "; - std::cin >> n; - - std::cout << "Fibonacci sequence: "; - for (int i = 0; i < n; i++) { - std::cout << fibonacci(i) << " "; - } - std::cout << std::endl; - - return 0; -} -``` - -**Java** - -```java -public class Fibonacci { - - 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 n = 10; // Change this to desired number of terms - - System.out.println("Fibonacci sequence: "); - for (int i = 0; i < n; i++) { - System.out.print(fibonacci(i) + " "); - } - System.out.println(); - } -} -``` - -**Python** - -```python -def fibonacci(n): - if n <= 1: - return n - else: - return fibonacci(n - 1) + fibonacci(n - 2) - -# Get the number of terms from the user -n = int(input("Enter the number of terms: ")) - -# Print the Fibonacci sequence -print("Fibonacci sequence: ") -for i in range(n): - print(fibonacci(i), end=" ") -print() -``` - -**JavaScript** - -```javascript -function fibonacci(n) { - if (n <= 1) { - return n; - } else { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} - -// Get the number of terms from the user -const n = parseInt(prompt("Enter the number of terms: ")); - -// Print the Fibonacci sequence -console.log("Fibonacci sequence: "); -for (let i = 0; i < n; i++) { - console.log(fibonacci(i)); -} -``` diff --git a/docs/Recursion/generate-parantheses.md b/docs/Recursion/generate-parantheses.md deleted file mode 100644 index 31dd3d497..000000000 --- a/docs/Recursion/generate-parantheses.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -id: Generate-Parentheses-problem-dsa -title: Generate Parentheses Recursion -sidebar_label: Generate Parentheses -description: "The Generate Parentheses problem requires generating all combinations of well-formed parentheses given n pairs. The solution uses recursion and backtracking to ensure that each combination is valid." -tags: [generate-parentheses, backtracking, recursion, dsa] ---- - -## Generate Parentheses Problem | Return All Combinations of Well-Formed Parentheses - -- Problem Statement: Given n pairs of parentheses, the task is to generate all possible combinations of well-formed parentheses. A well-formed parentheses string must have an equal number of opening and closing brackets, with every opening bracket correctly paired with a closing one. - -- The solution involves recursively constructing valid strings by adding opening and closing brackets while maintaining balance. - -``` -- Example: -For n = 3, the output should be: ["((()))", "(()())", "(())()", "()(())", "()()()"] -``` - -### C++ implementation - -```cpp -#include -#include -#include -using namespace std; - -class Solution { -public: - vector generateParenthesis(int n) { - vector res; - dfs(0, 0, "", n, res); - return res; - } - -private: - void dfs(int openP, int closeP, string s, int n, vector& res) { - if (openP == closeP && openP + closeP == n * 2) { - res.push_back(s); - return; - } - - if (openP < n) { - dfs(openP + 1, closeP, s + "(", n, res); - } - - if (closeP < openP) { - dfs(openP, closeP + 1, s + ")", n, res); - } - } -}; - -int main() { - Solution solution; - int n; - cout << "Enter the number of pairs of parentheses: "; - cin >> n; - - vector result = solution.generateParenthesis(n); - - cout << "All combinations of well-formed parentheses are:\n"; - for (const string& str : result) { - cout << str << endl; - } - - return 0; -} -``` diff --git a/docs/Recursion/josephus.md b/docs/Recursion/josephus.md deleted file mode 100644 index ba1b953d0..000000000 --- a/docs/Recursion/josephus.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: Josephus-problem-dsa -title: Josephus Problem Recursion -sidebar_label: Josephus Problem -sidebar_position: 7 -description: "The Josephus problem is a theoretical problem related to a certain elimination game. It is often solved using recursion, where the goal is to determine the safe position in a group of people standing in a circle, eliminating every k-th person." -tags: [josephus, recursion, dsa] ---- - -## Josephus Problem | Return the Safe Position - -Problem Statement: The Josephus problem is a famous theoretical problem. There are n people standing in a circle, and every k-th person is eliminated until only one person remains. The task is to find the position of the last person standing (safe position). The positions are numbered from 0 to n-1. -Recursive Solution -The idea is to use a recursive approach to find the position of the safe person. We know that when only one person remains, the safe position is 0. Then we build the solution backwards, considering the elimination of every k-th person. - -Recursive Solution -The idea is to use a recursive approach to find the position of the safe person. We know that when only one person remains, the safe position is 0. Then we build the solution backwards, considering the elimination of every k-th person. - -### C++ implementation -```cpp -#include -using namespace std; - -class Josephus { - public: - // Recursive function to find the safe position - int josephus(int n, int k) { - // Base case: only one person is left - if (n == 1) - return 0; - - // Recursive case: Reduce the problem by eliminating one person - // The position returned by josephus(n-1, k) is adjusted for the new circle size. - return (josephus(n - 1, k) + k) % n; - } -}; - -int main() { - int n = 7; // Total number of people in the circle - int k = 3; // Every k-th person is eliminated - - Josephus obj; - int safe_position = obj.josephus(n, k); - - cout << "The safe position is: " << safe_position << endl; - return 0; -} -``` \ No newline at end of file diff --git a/docs/Recursion/look-and-say.md b/docs/Recursion/look-and-say.md deleted file mode 100644 index c287bfdaf..000000000 --- a/docs/Recursion/look-and-say.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -id: look-and-say-problem-dsa -title: Look and Say Recursion -sidebar_label: Look and Say -sidebar_position: 7 -description: "The Look and Say sequence is a sequence of numbers where each term is generated by reading off the digits of the previous term. The sequence starts with 1, and each subsequent number describes the digits in the previous number. The problem can be solved recursively by processing each number and generating the next in the sequence." -tags: [look-and-say, recursion, sequence, dsa] ---- - - -### Introduction - -The **Look and Say sequence** is a mathematical sequence in which each term is generated by describing the digits of the previous term. The first term in the sequence is always "1", and each subsequent term is constructed by reading consecutive digits and saying how many of each digit are present. - -For example, starting with "1": -- The next term is "11" (one 1). -- The following term is "21" (two 1s). -- The next term is "1211" (one 2, one 1), and so on. - -### Problem Statement - -Given an integer `n`, return the `n`th term of the Look and Say sequence. - -### Approach - -The Look and Say sequence can be generated recursively. We observe that each term is derived from the previous term by counting consecutive occurrences of digits and constructing the next term based on these counts. - -For example: -- Term 1: "1" → "11" (one 1) -- Term 2: "11" → "21" (two 1s) -- Term 3: "21" → "1211" (one 2, one 1) - -### Pseudo Code - -1. Base Case: If `n == 1`, return "1". -2. Recursive Call: Get the `(n-1)`th term. -3. Process the previous term: - - Iterate through the term and count consecutive occurrences of digits. - - Append the count and the digit to the result string. -4. Return the result for the `n`th term. - -### Algorithm - -1. **Base Case**: The first term is always "1". -2. **Recursive Construction**: For each subsequent term, use the previous term to generate the current one by counting consecutive digits. -3. **Iterate**: Loop through the digits of the previous term, counting how many times each digit appears consecutively. -4. **Form the New Term**: For each group of consecutive digits, append the count followed by the digit itself to form the next term. -5. **Return the `n`th term**: Repeat this process recursively or iteratively until the `n`th term is generated. - -### Implementation in C++ - -```cpp -#include -#include -using namespace std; - -class Solution { -public: - // Function to recursively generate the nth term of the Look and Say sequence - string lookAndSay(int n) { - // Base case: the first term is "1" - if (n == 1) return "1"; - // Get the previous term - string prevTerm = lookAndSay(n - 1); - string result = ""; - int count = 1; - - // Iterate through the previous term and generate the current term - for (int i = 1; i < prevTerm.length(); i++) { - // If the current digit matches the previous one, increment the count - if (prevTerm[i] == prevTerm[i - 1]) { - count++; - } else { - // Append the count and the digit to the result string - result += to_string(count) + prevTerm[i - 1]; - count = 1; // Reset the count for the next group - } - } - - // Append the last group to the result - result += to_string(count) + prevTerm[prevTerm.length() - 1]; - return result; - } -}; - -int main() { - Solution obj; - int n = 5; // Let's find the 5th term in the Look and Say sequence - string result = obj.lookAndSay(n); - - // Output the result - cout << "The " << n << "th term of the Look and Say sequence is: " << result << endl; - return 0; -} -``` diff --git a/docs/Recursion/n-queen.md b/docs/Recursion/n-queen.md deleted file mode 100644 index b50be12e5..000000000 --- a/docs/Recursion/n-queen.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -id: N-Qyeen-problem-dsa -title: N Queen Recursion -sidebar_label: N Queen -sidebar_position: 2 -description: "The N-Queen problem is a classic combinatorial problem in which the goal is to place N queens on an N×N chessboard such that no two queens threaten each other. This means that no two queens can share the same row, column, or diagonal. The problem is often solved using backtracking, a form of recursion." -tags: [n-queen, backtracking, recursion, dsa] ---- - -## N Queen Problem | Return all Distinct Solutions to the N-Queens Puzzle - -- Problem Statement: The n-queens is the problem of placing n queens on n × n chessboard such that no two queens can attack each other. Given an integer n, return all distinct solutions to the n -queens puzzle. - Each solution contains a distinct boards configuration of the queen's placement, where ‘Q’ and ‘.’ indicate queen and empty space respectively. - -```cpp -#include -using namespace std; -class Solution { - public: - bool isSafe1(int row, int col, vector < string > board, int n) { - // check upper element - int duprow = row; - int dupcol = col; - - while (row >= 0 && col >= 0) { - if (board[row][col] == 'Q') - return false; - row--; - col--; - } - - col = dupcol; - row = duprow; - while (col >= 0) { - if (board[row][col] == 'Q') - return false; - col--; - } - - row = duprow; - col = dupcol; - while (row < n && col >= 0) { - if (board[row][col] == 'Q') - return false; - row++; - col--; - } - return true; - } - - public: - void solve(int col, vector < string > & board, vector < vector < string >> & ans, int n) { - if (col == n) { - ans.push_back(board); - return; - } - for (int row = 0; row < n; row++) { - if (isSafe1(row, col, board, n)) { - board[row][col] = 'Q'; - solve(col + 1, board, ans, n); - board[row][col] = '.'; - } - } - } - - public: - vector < vector < string >> solveNQueens(int n) { - vector < vector < string >> ans; - vector < string > board(n); - string s(n, '.'); - for (int i = 0; i < n; i++) { - board[i] = s; - } - solve(0, board, ans, n); - return ans; - } -}; -int main() { - int n = 4; // we are taking 4*4 grid and 4 queens - Solution obj; - vector < vector < string >> ans = obj.solveNQueens(n); - for (int i = 0; i < ans.size(); i++) { - cout << "Arrangement " << i + 1 << "\n"; - for (int j = 0; j < ans[0].size(); j++) { - cout << ans[i][j]; - cout << endl; - } - cout << endl; - } - return 0; -} -``` diff --git a/docs/Recursion/recursion.md b/docs/Recursion/recursion.md deleted file mode 100644 index 58e601c05..000000000 --- a/docs/Recursion/recursion.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: recusrion-in-dsa -title: Recursion data structure -sidebar_label: Recursion -sidebar_position: 1 -description: "Recursion is a programming technique where a function calls itself directly or indirectly in order to solve a larger problem by breaking it down into smaller, more manageable sub-problems. It is commonly used in algorithms involving divide and conquer strategies, tree traversal, and dynamic programming." -tags: [recursion, algorithms, dsa] ---- - -# Recursion - -## Introduction -Recursion is a programming technique in which a function calls itself directly or indirectly to solve a problem. It involves breaking down a problem into smaller sub-problems that are easier to solve. Recursion is widely used in problems involving trees, graphs, backtracking, and dynamic programming. - -## How Recursion Works -Every recursive function consists of two main parts: -1. **Base Case**: This condition stops the recursion. It prevents the function from calling itself indefinitely. -2. **Recursive Case**: The part where the function calls itself with modified arguments, moving towards the base case. - -```cpp -// Example: Factorial of a number using recursion -int factorial(int n) { - if (n == 0) - return 1; // Base case - else - return n * factorial(n - 1); // Recursive case -} -``` -In the above example, the base case is when n == 0, and the recursive case multiplies n with factorial(n - 1) until the base case is reached. - -## Types of Recursion -1. Direct Recursion -When a function calls itself directly, it's called direct recursion. -```cpp -void function() { - // Some code - function(); // Direct recursive call -} -``` - -## 2. Indirect Recursion -In indirect recursion, a function calls another function, which in turn calls the original function. -```cpp -void functionA() { - // Some code - functionB(); // Calls functionB -} - -void functionB() { - // Some code - functionA(); // Calls functionA -} -``` - -## Key Concepts in Recursion -1. Stack Memory -Recursion uses the call stack to keep track of the recursive calls. Each function call is stored in the stack until it reaches the base case. After that, the calls are resolved in reverse order, one by one. - -2. Recursive Depth -The number of times a recursive function calls itself is known as recursive depth. Too many recursive calls may lead to a stack overflow error. - -3. Tail Recursion -If the recursive call is the last operation in the function, it's known as tail recursion. Tail-recursive functions are often optimized by compilers to prevent stack overflow. -```cpp -// Example: Tail recursion -int tailFactorial(int n, int result = 1) { - if (n == 0) return result; // Base case - return tailFactorial(n - 1, result * n); // Tail recursive case -} -``` - -## Advantages of Recursion -- Simplifies the solution for problems that can be broken down into similar sub-problems. -- Makes code more elegant and easier to understand for certain problems (e.g., tree traversal, Fibonacci sequence). - -## Disadvantages of Recursion -- Recursive solutions are often less efficient than their iterative counterparts due to the overhead of function calls and the use of stack memory. -- May cause stack overflow errors if the recursion depth is too large. - -## Common Applications of Recursion -- Tree and Graph Traversal: Depth-First Search (DFS), Inorder, Preorder, and Postorder traversals. -- Backtracking Algorithms: Solving puzzles like Sudoku, N-Queens Problem, etc. -- Divide and Conquer Algorithms: Merge Sort, Quick Sort. -- Mathematical Problems: Factorials, Fibonacci numbers, Greatest Common Divisor (GCD). - -## Example Problems -1. Fibonacci Sequence -```cpp -int fibonacci(int n) { - if (n <= 1) - return n; // Base case - return fibonacci(n - 1) + fibonacci(n - 2); // Recursive case -} -``` - -2. Sum of Natural Numbers -```cpp -int sumOfNaturalNumbers(int n) { - if (n == 0) - return 0; // Base case - return n + sumOfNaturalNumbers(n - 1); // Recursive case -} -``` - -## Conclusion -Recursion is a powerful tool in programming that can simplify complex problems by breaking them into sub-problems. However, it requires careful handling of base cases and optimization (like tail recursion) to avoid issues like stack overflow. diff --git a/docs/Recursion/ulamsequence.md b/docs/Recursion/ulamsequence.md deleted file mode 100644 index d20fa8bb8..000000000 --- a/docs/Recursion/ulamsequence.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: ulam-sequence -title: Ulam Sequence Generation Via Recursion -sidebar_label: Generate Ulam Sequence -description: "The Recursive Ulam Sequence Generator is a feature that generates the Ulam sequence—a unique integer sequence—using a recursive algorithm. The Ulam sequence starts with two predefined numbers, 1 and 2, and each subsequent number is the smallest integer that can be expressed as the sum of two distinct earlier numbers in exactly one way. This feature provides a recursive approach to find Ulam numbers up to a given integer, maxN." -tags: [UlamSequence, recursion, dsa] ---- -## Ulam Sequence Generation - -**Problem Statement:** - -Design a recursive algorithm to generate the Ulam sequence up to a given integer `maxN`. The Ulam sequence begins with two predefined integers, **1** and **2** , and each subsequent number is the smallest integer that can be expressed uniquely as the sum of two distinct earlier numbers in exactly one way. The task is to implement a recursive function that, given an upper limit `maxN`, generates and outputs the Ulam sequence up to this number. - -### Constraints: - -* The generated number must only be expressible as a sum of two distinct previous Ulam numbers in exactly one way. -* The sequence should start with 1 and 2, with each subsequent number satisfying the Ulam sequence properties. - -### Input: - -* A single integer `maxN` representing the upper bound for the Ulam sequence generation. - -### Output: - -* A list of Ulam numbers up to the value of `maxN`. - -#### Example : - -For an input of `maxN = 20`, the output should be: - -1 2 3 4 6 8 11 13 16 18 - -#### Complexity : - -The time complexity of the recursive Ulam Sequence generation is primarily influenced by the need to evaluate each number up to `maxN` and check whether it can be represented as the sum of two distinct Ulam numbers in exactly one way. For each candidate number, the algorithm must iterate over all pairs of previously generated Ulam numbers to count how many distinct pairs sum to the candidate. - -In the worst case, this results in checking **O**(**n**2**)** pairs for each of the numbers up to `maxN`. Thus, for generating `m` Ulam numbers, where `m` is the number of valid Ulam numbers up to `maxN`, the overall time complexity becomes approximately **O(m * n^2)** , where `n` is the current number being evaluated. However, depending on the implementation details, such as using optimized data structures to store sums or checking distinct pairs, the complexity may be slightly improved, but it remains quadratic in nature due to the pair-checking process. - -The space complexity is **O(m)** , where `m` is the number of Ulam numbers stored, as the sequence must be stored to check future sums. - -### Limitations and Considerations - -* **Time Complexity:** - * The recursive Ulam Sequence generation, while conceptually elegant, has a high time complexity, especially for large values of `maxN`. As each candidate number needs to be checked against all previously generated Ulam numbers, this can lead to quadratic time complexity. For large sequences, this results in slower performance and makes the algorithm inefficient compared to iterative or optimized approaches. -* **Memory Usage:** - * The algorithm requires storing the Ulam numbers generated up to `maxN` for future use in the recursive calls. This can lead to high memory consumption for larger sequences as every Ulam number up to the limit needs to be kept in memory, contributing to space complexity concerns. -* **Limited Scalability:** - * Due to the combination of quadratic time complexity and increasing memory requirements, the recursive Ulam Sequence generation may not scale well for large values of `maxN`. As `maxN` increases, the time to generate the sequence grows significantly, making it impractical for very large inputs. -* **Recursive Call Overhead:** - * The recursive nature of the solution can lead to increased overhead from repeated function calls. In some languages, recursion also introduces the risk of stack overflow for very deep recursion when `maxN` is large, making the algorithm less suitable for cases where iterative or tail-recursive optimizations are not applied. -* **Distinct Pair Checking:** - * Ensuring that each candidate Ulam number can be expressed as the sum of two distinct earlier numbers in exactly one way requires careful checking of all possible pairs. This process is not easily parallelizable, which limits potential optimization through concurrency or multi-threading. - -**C++ implementation :** - -**Output :** - -Enter the maximum value for the Ulam sequence: 20 -1 2 3 4 6 8 11 13 16 18 - -Enter the maximum value for the Ulam sequence: 100 -1 2 3 4 6 8 11 13 16 18 26 28 36 38 47 48 53 57 62 69 72 77 82 87 97 99 - -**Code :** - -```cpp - #include -#include - -using namespace std; - -vector ulam = {1, 2}; - -bool isUlam(int n) { - int count = 0; - - for (size_t i = 0; i < ulam.size(); i++) { - for (size_t j = i + 1; j < ulam.size(); j++) { - if (ulam[i] + ulam[j] == n) { - count++; - if (count > 1) { - return false; // More than one way to represent the sum - } - } - } - } - return count == 1; -} - -void generateUlam(int current, int maxN) { - if (current > maxN) { - return; - } - - if (isUlam(current)) { - ulam.push_back(current); - } - - generateUlam(current + 1, maxN); -} - -int main() { - int maxN; - - cout << "Enter the maximum value for the Ulam sequence: "; - cin >> maxN; - - generateUlam(3, maxN); - - for (int num : ulam) { - cout << num << " "; - } - cout << endl; - - return 0; -} - - - -``` diff --git a/docs/Segment-Trees/Dynamic Segment Trees.md b/docs/Segment-Trees/Dynamic Segment Trees.md deleted file mode 100644 index c1c1b3411..000000000 --- a/docs/Segment-Trees/Dynamic Segment Trees.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: dynamic-segment-tree -sidebar_position: 13 -title: Dynamic Segment Tree -sidebar_label: Dynamic Segment Tree -description: "This post covers dynamic segment trees, their use-cases, code examples, and how they differ from regular segment trees." -tags: [dsa, segment tree, range queries, recursion, c++] ---- - -# Dynamic Segment Tree - -In this post, we’ll cover **Dynamic Segment Trees**, a data structure that extends the capabilities of static segment trees to handle larger ranges efficiently. This is especially useful when the input size is too large to fit into memory at once, or when dealing with dynamic ranges that are sparsely populated. - ---- - -## Problem Definition - -A **Dynamic Segment Tree** is a type of segment tree where nodes are created **on-demand** during updates. It allows us to efficiently perform range queries and updates for very large ranges, without pre-allocating memory for all nodes. - -### Example Use Case -Suppose you need to manage a large range of values, such as from `1` to `10^9`, but only a small fraction of the elements within the range are relevant. A **dynamic segment tree** only creates the necessary nodes, making it space-efficient. - ---- - -## Approach - -The idea behind a dynamic segment tree is to **lazily initialize** nodes as they are accessed during updates or queries. Instead of building the entire tree upfront, we create only the nodes that are necessary. - -### Key Characteristics: -1. **Sparse Representation:** Nodes are created on-demand to save space. -2. **Recursive Structure:** Similar to a regular segment tree but with dynamic memory allocation. -3. **Memory Efficient:** Ideal for problems with large ranges but sparse data. - ---- - -## Dynamic Segment Tree Operations - -### 1. **Node Structure** - -```cpp -struct Node { - int value; // Stores the sum or relevant data for the range - Node* left; // Pointer to the left child - Node* right; // Pointer to the right child - - Node(int v = 0) : value(v), left(NULL), right(NULL) {} -}; - -``` - -### 2. **Update Operation** - -``` -void update(Node*& node, int start, int end, int idx, int val) { - if (!node) node = new Node(); // Create node if it doesn't exist - - if (start == end) { - node->value += val; // Update the value at the leaf node - return; - } - - int mid = (start + end) / 2; - if (idx <= mid) - update(node->left, start, mid, idx, val); - else - update(node->right, mid + 1, end, idx, val); - - // Update the current node value based on children - node->value = (node->left ? node->left->value : 0) + - (node->right ? node->right->value : 0); -} - -``` -### 3. **Range Query Operation** - -``` -int query(Node* node, int start, int end, int l, int r) { - if (!node || l > end || r < start) - return 0; // Return 0 if out of range or node doesn't exist - - if (l <= start && end <= r) - return node->value; // Return value if the current segment is fully in range - - int mid = (start + end) / 2; - int leftQuery = query(node->left, start, mid, l, r); - int rightQuery = query(node->right, mid + 1, end, l, r); - - return leftQuery + rightQuery; -} - -``` - -## Example Usage -### Code Implementation -``` -#include -using namespace std; - -struct Node { - int value; - Node* left; - Node* right; - Node(int v = 0) : value(v), left(NULL), right(NULL) {} -}; - -void update(Node*& node, int start, int end, int idx, int val) { - if (!node) node = new Node(); - if (start == end) { - node->value += val; - return; - } - int mid = (start + end) / 2; - if (idx <= mid) - update(node->left, start, mid, idx, val); - else - update(node->right, mid + 1, end, idx, val); - node->value = (node->left ? node->left->value : 0) + - (node->right ? node->right->value : 0); -} - -int query(Node* node, int start, int end, int l, int r) { - if (!node || l > end || r < start) return 0; - if (l <= start && end <= r) return node->value; - int mid = (start + end) / 2; - int leftQuery = query(node->left, start, mid, l, r); - int rightQuery = query(node->right, mid + 1, end, l, r); - return leftQuery + rightQuery; -} - -int main() { - Node* root = NULL; // Initialize an empty segment tree - - // Update some elements - update(root, 0, 9, 2, 5); - update(root, 0, 9, 4, 10); - - // Perform range queries - cout << "Sum in range [0, 5]: " << query(root, 0, 9, 0, 5) << endl; - cout << "Sum in range [3, 8]: " << query(root, 0, 9, 3, 8) << endl; - - return 0; -} - -``` -### Output -``` -Sum in range [0, 5]: 15 -Sum in range [3, 8]: 10 -``` - -## Time Complexity - -- **Update Operation:** `O(log N)` in the average case. -- **Query Operation:** `O(log N)` in the average case. -- **Space Complexity:** Depends on the number of nodes created, which is proportional to the number of updates. - ---- - -## When to Use a Dynamic Segment Tree - -- **Very large ranges:** When the range size is too large to pre-allocate. -- **Sparse updates:** When only a few elements in the range are updated. -- **Memory constraints:** When space efficiency is critical. - ---- - -## Conclusion - -Dynamic Segment Trees are a powerful variation of segment trees, useful in scenarios with large but sparse datasets. They provide the same query and update performance as regular segment trees, but with improved memory efficiency by allocating nodes on demand. diff --git a/docs/Segment-Trees/Practice Porblem.md b/docs/Segment-Trees/Practice Porblem.md deleted file mode 100644 index d673c6d53..000000000 --- a/docs/Segment-Trees/Practice Porblem.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -id: segment-tree-practice-problems -sidebar_position: 12 -title: Segment Tree Practice Problems -sidebar_label: Segment Tree Problems -description: "A curated list of practice problems to enhance your understanding and skills in using segment trees." -tags: [dsa, segment trees, practice problems] ---- - -## Segment Tree Practice Problems - -Below is a collection of problems that can be effectively solved using segment trees. Each problem focuses on different aspects of segment tree functionalities, including range queries and updates. - -### Easy - -- [Range Minimum Query - LeetCode](https://leetcode.com/problems/range-minimum-query-immutable/) -- [Range Sum Query - Immutable - LeetCode](https://leetcode.com/problems/range-sum-query-immutable/) -- [Count of Range Sum - LeetCode](https://leetcode.com/problems/count-of-range-sum/) -- [Find the Duplicate Number - LeetCode](https://leetcode.com/problems/find-the-duplicate-number/) -- [Majority Element - LeetCode](https://leetcode.com/problems/majority-element/) -- [Maximum Average Subarray I - LeetCode](https://leetcode.com/problems/maximum-average-subarray-i/) - -### Medium -- [Length of Longest Increasing Subsequences (LIS) Using Segment Tree](https://www.geeksforgeeks.org/length-longest-increasing-subsequences-lis-using-segment-tree/) -- [Maximize Length of Longest Subarray Consisting of Same Elements by at Most K Decrements](https://www.geeksforgeeks.org/maximize-length-longest-subarray-consisting-same-elements-k-decrements/) -- [Generate Original Permutation from Given Array of Inversions](https://www.geeksforgeeks.org/generate-original-permutation-given-array-inversions/) -- [Maximum of All Subarrays of Size K Using Segment Tree](https://www.geeksforgeeks.org/maximum-of-all-subarrays-of-size-k-using-segment-tree/) -- [Length of Longest Subarray with Same Elements in At Most K Increments](https://www.geeksforgeeks.org/length-longest-subarray-same-elements-least-k-increments/) -- [Count Number of Increasing Sub-Sequences: O(NlogN)](https://www.geeksforgeeks.org/count-number-increasing-sub-sequences-o-nlogn/) -- [Calculate the Sum of GCD Over All Subarrays](https://www.geeksforgeeks.org/calculate-sum-gcd-subarrays/) -- [Kth Largest Element in an Array - LeetCode](https://leetcode.com/problems/kth-largest-element-in-an-array/) -- [Find K Closest Elements - LeetCode](https://leetcode.com/problems/find-k-closest-elements/) -- [Number of Subarrays with Bounded Maximum - LeetCode](https://leetcode.com/problems/number-of-subarrays-with-bounded-maximum/) -- [Querying Maximum Number of Divisors that a Number in a Given Range Has - GeeksforGeeks](https://www.geeksforgeeks.org/querying-maximum-number-divisors-number-given-range-has/) -- [Range Queries for Longest Correct Bracket Subsequence - GeeksforGeeks](https://www.geeksforgeeks.org/range-queries-longest-correct-bracket-subsequence/) - -### Hard - -- [Build a Segment Tree for N-ary Rooted Tree](https://www.geeksforgeeks.org/build-segment-tree-n-ary-rooted-tree/) -- [Length of Longest Subarray with Same Elements in At Most K Increments](https://www.geeksforgeeks.org/length-longest-subarray-same-elements-least-k-increments/) -- [Maximum Length of Repeated Subarray - LeetCode](https://leetcode.com/problems/maximum-length-of-repeated-subarray/) -- [Cartesian Tree from Inorder Traversal](https://www.geeksforgeeks.org/cartesian-tree-inorder-traversal/) -- [LIS Using Segment Tree](https://www.geeksforgeeks.org/lis-using-segment-tree/) -- [Reconstructing Segment Tree](https://www.geeksforgeeks.org/reconstruct-segment-tree/) -- [Range and Update Query for Chessboard Pieces - GeeksforGeeks](https://www.geeksforgeeks.org/range-update-query-chessboard-pieces/) -- [Queries to Evaluate the Given Equation in a Range - GeeksforGeeks](https://www.geeksforgeeks.org/queries-evaluate-given-equation-range/) -- [Flipping Sign Problem - GeeksforGeeks](https://www.geeksforgeeks.org/flipping-sign-problem/) - - -## Tips for Solving Segment Tree Problems - -- **Understand the Basics**: Familiarize yourself with segment tree concepts and operations. -- **Start Simple**: Begin with basic problems before tackling complex ones. -- **Visualize the Tree**: Draw the segment tree to comprehend data structure and query flow. -- **Practice Lazy Propagation**: Focus on problems that involve lazy propagation for efficient updates. -- **Break Down Problems**: Deconstruct complex problems into manageable parts. -- **Explore Edge Cases**: Test your implementation with various inputs to handle edge cases effectively. -- **Refer to Resources**: Use online tutorials and videos for additional insights and explanations. -- **Practice Regularly**: Consistent practice helps reinforce understanding and skill. -- **Join Discussion Forums**: Engage with communities for support and shared solutions. -- **Stay Patient and Positive**: Keep a positive mindset; persistence leads to improvement! - -Happy coding! 😊 - - -## Conclusion - -These practice problems will help you strengthen your understanding of segment trees and their applications. Implementing solutions to these problems will enhance your problem-solving skills and prepare you for competitive programming challenges. diff --git a/docs/Segment-Trees/Segment Trees Introduction.md b/docs/Segment-Trees/Segment Trees Introduction.md deleted file mode 100644 index e6c80755a..000000000 --- a/docs/Segment-Trees/Segment Trees Introduction.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -id: segment-tree-intro -title: Segment Trees -sidebar_label: Segment Trees -description: "In this blog post, we'll explore Segment Trees, a powerful data structure for efficiently solving range query problems." -tags: [dsa, data structures, segment trees] ---- - -## Introduction -**Segment Trees** are a versatile data structure that allows for efficient querying and updating of an array. They are particularly useful for problems that involve range queries, such as finding the sum or minimum of elements in a specified range, and for efficiently updating elements in the array. The main advantage of segment trees over other data structures, like binary indexed trees (BIT), is their ability to handle both queries and updates in logarithmic time. - -![Segment Tree](Segment-Tree-img.png) - - -## Definition and Structure -A Segment Tree is a binary tree where each node represents an interval or segment of an array. The leaf nodes represent individual elements of the array, while each internal node represents the aggregation (sum, minimum, maximum, etc.) of its child segments. - -Key components of a Segment Tree: -- **Leaf Nodes**: Represent individual elements of the array. -- **Internal Nodes**: Represent the aggregation of their child nodes. -- **Root Node**: Represents the entire array. - -**Example Segment Tree for the array [1, 3, 5, 7, 9, 11]:** -``` - [1, 3, 5, 7, 9, 11] - / \ - [1, 3, 5] [7, 9, 11] - / \ / \ -[1, 3] [5] [7, 9] [11] - / \ -``` - -## Properties -- **Efficient Range Queries**: Segment trees can answer range queries in **O(log n)** time. -- **Dynamic Updates**: They allow for efficient updates to elements in the array, also in **O(log n)** time. -- **Space Complexity**: A Segment Tree requires **O(n)** space, where **n** is the size of the input array. - -## Types of Segment Trees -1. **Standard Segment Tree**: Used for range queries where the operation is additive or multiplicative. - ``` - Example for range sum: - Given array: [1, 3, 5, 7, 9, 11] - Range sum for [1, 3]: 3 + 5 = 8 - ``` - -2. **Lazy Propagation Segment Tree**: An optimized segment tree that handles range updates efficiently by deferring updates to avoid unnecessary recalculations. - ``` - Example for range update: - Increment elements in the range [1, 3] by 5. - ``` - -## Operations on Segment Trees - -### 1. **Building the Segment Tree** -The tree is built from the array in **O(n)** time, where each node is initialized with the corresponding segment's aggregation. - -### 2. **Querying** -To get the sum (or any aggregation) over a range, we traverse the tree from the root and combine the results of relevant segments. - -### 3. **Updating** -To update an element, we locate the leaf node corresponding to the element and update its value, then propagate the change up the tree to maintain the correct segment values. - -## Implementation - -Here’s an example of how you can implement a Segment Tree in C++: - -```cpp -#include -#include -using namespace std; - -class SegmentTree { -public: - vector tree; - int n; - - SegmentTree(vector& arr) { - n = arr.size(); - tree.resize(4 * n); - build(arr, 0, 0, n - 1); - } - - void build(vector& arr, int node, int start, int end) { - if (start == end) { - tree[node] = arr[start]; // Leaf node - } else { - int mid = (start + end) / 2; - build(arr, 2 * node + 1, start, mid); - build(arr, 2 * node + 2, mid + 1, end); - tree[node] = tree[2 * node + 1] + tree[2 * node + 2]; // Sum of children - } - } - - int query(int l, int r) { - return query(0, 0, n - 1, l, r); - } - - int query(int node, int start, int end, int l, int r) { - if (r < start || end < l) return 0; // No overlap - if (l <= start && end <= r) return tree[node]; // Total overlap - int mid = (start + end) / 2; - int leftSum = query(2 * node + 1, start, mid, l, r); - int rightSum = query(2 * node + 2, mid + 1, end, l, r); - return leftSum + rightSum; // Sum of both halves - } - - void update(int idx, int val) { - update(0, 0, n - 1, idx, val); - } - - void update(int node, int start, int end, int idx, int val) { - if (start == end) { - tree[node] = val; // Leaf node - } else { - int mid = (start + end) / 2; - if (start <= idx && idx <= mid) { - update(2 * node + 1, start, mid, idx, val); - } else { - update(2 * node + 2, mid + 1, end, idx, val); - } - tree[node] = tree[2 * node + 1] + tree[2 * node + 2]; // Update current node - } - } -}; - -int main() { - vector arr = {1, 3, 5, 7, 9, 11}; - SegmentTree segmentTree(arr); - cout << segmentTree.query(1, 3) << endl; // Output: 15 (3 + 5 + 7) - segmentTree.update(1, 10); // Update index 1 to 10 - cout << segmentTree.query(1, 3) << endl; // Output: 22 (10 + 5 + 7) -} -``` - -## Advantages of Segment Trees - -- **Efficient Range Queries**: Segment trees enable efficient querying of range sums, minimums, maximums, and other aggregate functions in **O(log n)** time, making them suitable for dynamic datasets. - -- **Dynamic Updates**: They allow for efficient updates to the array elements, where updates can also be done in **O(log n)** time, providing flexibility in data manipulation. - -- **Flexible Range Queries**: Segment trees can be customized to handle various types of queries beyond basic range queries, including lazy propagation for efficient range updates. - -- **Space Complexity**: Although segment trees require **O(n)** space, they efficiently use space compared to other data structures when considering the additional features they provide. - -## Applications of Segment Trees - -- **Range Sum Queries**: Segment trees are widely used in scenarios where frequent range sum queries are required, such as in competitive programming. - -- **Interval Overlap**: They can be used to solve problems involving overlapping intervals, allowing for efficient counting of overlaps within a specific range. - -- **Dynamic Programming**: Segment trees can assist in optimizing dynamic programming problems that involve range queries and updates, especially in scenarios with large input sizes. - -- **Frequency Count**: They can be adapted to maintain frequencies of elements within a range, enabling efficient queries regarding the count of elements within specified bounds. - -- **Image Processing**: Segment trees can be applied in image processing algorithms, particularly in operations that involve pixel values and require efficient region queries. - - --- \ No newline at end of file diff --git a/docs/Segment-Trees/Segment-Tree-img.png b/docs/Segment-Trees/Segment-Tree-img.png deleted file mode 100644 index f1bc69dc4672fd49a8259d5d6448e48e5cc58b38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191675 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¥>SUgX8wn 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%0DAlPihpB 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

    !J#k|0B{b}JtP4-|&dJKGsJm?T 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 diff --git a/docs/Sliding-Window/IntroductionToSlidingWindow.jpg b/docs/Sliding-Window/IntroductionToSlidingWindow.jpg deleted file mode 100644 index 153a0277214c58d0b8867be21dd7e4d613a3f294..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50651 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 OQMIEX01pBF|2F}dQ2bZ` diff --git a/docs/Sliding-Window/Problem-Practice.md b/docs/Sliding-Window/Problem-Practice.md deleted file mode 100644 index fa3d234ad..000000000 --- a/docs/Sliding-Window/Problem-Practice.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -id: Practice-Problems-on-sliding-window -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 2 -description: Here are some practice problems for the Sliding Window technique, divided into topic-wise and difficulty-wise categories. -tags: [DSA, algorithms, sliding window] ---- - -### Fixed Size Window: - -- [Maximum Sum of a Subarray of Size K](https://leetcode.com/problems/maximum-sum-of-distinct-subarrays-with-length-k/description/) -- [Minimize the Maximum of Two Arrays](https://leetcode.com/problems/minimize-the-maximum-of-two-arrays/) -- [Longest Substring with K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) -- [Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) -- [Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/) - -### Variable Size Window: - -- [Minimum Size Subarray Sum](https://leetcode.com/problems/minimum-size-subarray-sum/) -- [Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) -- [Find All Anagrams in a String](https://leetcode.com/problems/find-all-anagrams-in-a-string/) -- [Permutation in String](https://leetcode.com/problems/permutation-in-string/) -- [Fruit Into Baskets](https://leetcode.com/problems/fruit-into-baskets/) - -### Advanced Problems: - -- [Count Number of Nice Subarrays](https://leetcode.com/problems/count-number-of-nice-subarrays/) -- [Subarrays with K Different Integers](https://leetcode.com/problems/subarrays-with-k-different-integers/) -- [Number of Subarrays with At Least K Ones](https://leetcode.com/problems/number-of-subarrays-with-at-least-k-ones/) -- [Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) - -### Additional Problems: - -- [K Concatenation Maximum Sum](https://leetcode.com/problems/k-concatenation-maximum-sum/) -- [Count Subarrays with Fixed Bounds](https://leetcode.com/problems/count-subarrays-with-fixed-bounds/) -- [Maximum Erasure Value](https://leetcode.com/problems/maximum-erasure-value/) - -### Challenges: - -- [Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) -- [Subarray Product Less Than K](https://leetcode.com/problems/subarray-product-less-than-k/) diff --git a/docs/Sliding-Window/_category_.json b/docs/Sliding-Window/_category_.json deleted file mode 100644 index 69ca8ce03..000000000 --- a/docs/Sliding-Window/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Sliding Window", - "position": 7, - "link": { - "type": "generated-index", - "description": "The Sliding Window is an efficient technique used to solve problems involving arrays or strings where we need to find a subrange that satisfies a particular condition. Instead of recomputing the entire range from scratch every time, we slide a window over the array/string and update the solution incrementally." - } -} diff --git a/docs/Sliding-Window/character-replacement.md b/docs/Sliding-Window/character-replacement.md deleted file mode 100644 index 7cbf2a84c..000000000 --- a/docs/Sliding-Window/character-replacement.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: character-replacement -title: Character Replacement -sidebar_label: Character Replacement -sidebar_position: 4 -description: "In this blog post, we'll explore how to solve the character replacement problem using the sliding window technique." -tags: [dsa, algorithms, sliding window, strings] ---- - -## Character Replacement - -### Problem Definition: - -You are given a string consisting of uppercase English letters and an integer `k`. Your task is to find the length of the longest substring that can be obtained by replacing at most `k` characters in the string. - -### Example: - -Let's consider the string `s = "AABABBA"` and `k = 1`. - -The longest substring we can form by replacing at most `k` characters is `"AABAB"` or `"ABABB"`, both of which have a length of **5**. - -### Approach: Sliding Window Technique - -To solve this problem efficiently, we can use the **sliding window technique**. This technique allows us to maintain a window that represents a substring and expand or contract this window based on certain conditions. - -### Steps: - -1. **Initialize Variables**: - Use two pointers (`left` and `right`) to represent the window, and maintain a count of the most frequently occurring character within the window. - -2. **Expand the Right Pointer**: - Move the `right` pointer to the right, expanding the window to include new characters. Update the count of the characters as you do this. - -3. **Check Validity**: - If the number of characters that need to be replaced (calculated as the total number of characters in the window minus the count of the most frequent character) exceeds `k`, move the `left` pointer to shrink the window from the left side until the condition is satisfied. - -4. **Update the Maximum Length**: - During the process, keep track of the maximum length of valid substrings found. - -### Time Complexity: -- **O(n)**, where `n` is the length of the string, since each character is processed at most twice (once by the right pointer and once by the left pointer). - -### Space Complexity: -- **O(1)**, since we only need a fixed amount of space for the character count (26 for uppercase letters). - -### C++ Code Implementation: - -```cpp -#include -#include -#include -using namespace std; - -int characterReplacement(string s, int k) { - unordered_map count; - int left = 0, max_count = 0, max_length = 0; - - for (int right = 0; right < s.size(); right++) { - count[s[right]]++; - max_count = max(max_count, count[s[right]]); - - while (right - left + 1 - max_count > k) { - count[s[left]]--; - left++; - } - - max_length = max(max_length, right - left + 1); - } - - return max_length; -} - -int main() { - string s = "AABABBA"; - int k = 1; - - int result = characterReplacement(s, k); - cout << "The length of the longest substring is: " << result << endl; - - return 0; -} -``` - - -### Java Code Implementation: -```java -import java.util.HashMap; - -public class CharacterReplacement { - - public static int characterReplacement(String s, int k) { - HashMap count = new HashMap<>(); - int left = 0, maxCount = 0, maxLength = 0; - - for (int right = 0; right < s.length(); right++) { - char rightChar = s.charAt(right); - count.put(rightChar, count.getOrDefault(rightChar, 0) + 1); - maxCount = Math.max(maxCount, count.get(rightChar)); - - while (right - left + 1 - maxCount > k) { - char leftChar = s.charAt(left); - count.put(leftChar, count.get(leftChar) - 1); - left++; - } - - maxLength = Math.max(maxLength, right - left + 1); - } - - return maxLength; - } - - public static void main(String[] args) { - String s = "AABABBA"; - int k = 1; - - int result = characterReplacement(s, k); - System.out.println("The length of the longest substring is: " + result); - } -} -``` diff --git a/docs/Sliding-Window/introduction-to-sliding-window.md b/docs/Sliding-Window/introduction-to-sliding-window.md deleted file mode 100644 index d4f66f3b5..000000000 --- a/docs/Sliding-Window/introduction-to-sliding-window.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -id: sliding-window -title: Sliding Window Algorithm -sidebar_label: Sliding Window Algorithm -sidebar_position: 1 -description: "In this blog post, we'll explore the Sliding Window Algorithm, an efficient technique for solving problems related to arrays or strings." -tags: [dsa, algorithms, sliding window] ---- - -## Sliding Window Algorithm - -![alt text](IntroductionToSlidingWindow.jpg) - -### Definition: -The **Sliding Window** is an efficient technique used to solve problems involving arrays or strings where we need to find a subrange that satisfies a particular condition. Instead of recomputing the entire range from scratch every time, we slide a window over the array/string and update the solution incrementally. - -This technique reduces the time complexity significantly for problems that involve working with subarrays or substrings. - -### Characteristics: - -- **Window Definition**: - - The sliding window represents a subarray or substring of a fixed or variable size that slides over the data structure (array or string) one element at a time. - -- **Efficiency**: - - Sliding window helps in solving problems where recalculating the entire range for each position would be inefficient. By sliding the window and updating only the necessary elements, it can reduce the time complexity. - -- **Fixed vs. Dynamic Window**: - - The window size can either be fixed, where the window is of constant length, or dynamic, where the window grows or shrinks based on the problem requirements. - -### Common Use Cases: - -- **Finding the maximum/minimum sum of a subarray of size k**. -- **Finding the longest substring with k distinct characters**. -- **Finding an anagram of one string within another string**. -- **Finding a subarray with a sum equal to a target**. - -### Time Complexity: -- **O(n)**, where n is the size of the array or string. The sliding window ensures that we traverse the array/string only once. - -### Space Complexity: -- **O(1)** for most problems if we're just calculating sums or counts. -- **O(k)** for problems where additional space is required to store intermediate results, like distinct elements in the window. - -### C++ Implementation (Fixed Window Example): - -Let's take the example of finding the **maximum sum of any subarray of size k** in an array. - -```cpp -#include -#include -#include -using namespace std; - -int maxSumSubarray(const vector& arr, int k) { - int n = arr.size(); - if (n < k) { - cout << "Invalid input, array size is smaller than k." << endl; - return -1; - } - - int max_sum = INT_MIN, current_sum = 0; - - // Compute the sum of the first window - for (int i = 0; i < k; i++) { - current_sum += arr[i]; - } - - max_sum = current_sum; - - // Slide the window across the array - for (int i = k; i < n; i++) { - current_sum += arr[i] - arr[i - k]; // Slide the window - max_sum = max(max_sum, current_sum); // Update max sum - } - - return max_sum; -} - -int main() { - vector arr = {2, 1, 5, 1, 3, 2}; - int k = 3; - - int result = maxSumSubarray(arr, k); - cout << "Maximum sum of subarray of size " << k << ": " << result << endl; - - return 0; -} -``` - -### Python Code Implementation - -```python - -def max_sum_subarray(arr, k): - n = len(arr) - if n < k: - print("Invalid input, array size is smaller than k.") - return -1 - - max_sum = -1 #set max sum - current_sum = sum(arr[:k]) # Compute the sum of the first window - - max_sum = current_sum - - # Slide the window across the array - for i in range(k, n): - current_sum += arr[i] - arr[i - k] # Slide the window - max_sum = max(max_sum, current_sum) # Update max sum - - return max_sum - -# Test the function -arr = [2, 1, 5, 1, 3, 2] -k = 3 -result = max_sum_subarray(arr, k) -print(f"Maximum sum of subarray of size {k}: {result}") -``` - -### Java Code Implementation - -```java -public class MaxSumSubarray { - - public static int maxSumSubarray(int[] arr, int k) { - int n = arr.length; - if (n < k) { - System.out.println("Invalid input, array size is smaller than k."); - return -1; - } - - int maxSum = -1; // Set max sum - int currentSum = 0; - - // Compute the sum of the first window - for (int i = 0; i < k; i++) { - currentSum += arr[i]; - } - maxSum = currentSum; - - // Slide the window across the array - for (int i = k; i < n; i++) { - currentSum += arr[i] - arr[i - k]; // Slide the window - maxSum = Math.max(maxSum, currentSum); // Update max sum - } - - return maxSum; - } - - public static void main(String[] args) { - int[] arr = {2, 1, 5, 1, 3, 2}; - int k = 3; - int result = maxSumSubarray(arr, k); - System.out.println("Maximum sum of subarray of size " + k + ": " + result); - } -} -``` - -### Explanation: -The first `for` loop calculates the sum of the first subarray (window) of size `k`. -The second `for` loop slides the window one element at a time, adjusting the sum by adding the new element and removing the element that is no longer in the window. -This ensures the sum of each subarray of size `k` is calculated in **O(1)** time after the initial window, resulting in an overall time complexity of **O(n)**. - -### Summary: -The Sliding Window technique is a powerful optimization method for problems where subarray or substring operations are frequent. It reduces the brute-force time complexity from **O(n * k)** to **O(n)** by keeping track of changes incrementally. diff --git a/docs/Sliding-Window/longest-repeating-character-replacement.md b/docs/Sliding-Window/longest-repeating-character-replacement.md deleted file mode 100644 index 69e4898b6..000000000 --- a/docs/Sliding-Window/longest-repeating-character-replacement.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -id: longest-repeating-character-replacement -title: Longest Repeating Character Replacement -sidebar_label: Longest Repeating Character Replacement -sidebar_position: 4 -description: "In this blog post, we will explore an efficient solution to the Longest Repeating Character Replacement problem using sliding window and frequency count." -tags: [dsa, algorithms, sliding window, strings] ---- - - - -### Problem Definition: - -You are given a string `s` and an integer `k`. You can choose any character from the string and replace it with any other character up to `k` times. The task is to find the length of the longest substring that contains the same character after performing at most `k` character replacements. - -### Example: - -Let's consider the string `s = "AABABBA"` and `k = 1`. - -We want to find the longest substring where at most one character can be replaced, such that all characters in that substring are the same. - -For the above example: - -- After replacing one character, the longest valid substring would be `"AABA"`, with length 4. - -### Approach: Sliding Window and Frequency Count - -To solve this problem efficiently, we use the **sliding window** technique along with a frequency count of characters within the current window. We aim to maximize the length of a substring where the majority of the characters are the same, and we replace the rest. - -### Steps: - -1. **Initialize Two Pointers**: - Use two pointers `left` and `right` to define a sliding window over the string. Start both pointers at the beginning of the string. - -2. **Track Character Frequency**: - Maintain a frequency count for each character within the current window, and keep track of the maximum frequency of any character in the window. - -3. **Check Valid Substring**: - For each new window (i.e., each new position of `right`), check if the number of replacements needed to make the entire window uniform (i.e., `right - left + 1 - maxFreq`) is less than or equal to `k`. If yes, the window is valid, and you can expand it. If not, shift the `left` pointer to shrink the window. - -4. **Maximize the Window Length**: - Keep track of the maximum valid window length during the entire process. - -### Time Complexity: -- **O(n)**, where `n` is the length of the string. Each character is processed once by the sliding window, and the character count is updated in constant time. - -### Space Complexity: -- **O(1)**, since the frequency count array size is fixed (for 26 possible characters). - -### C++ Code Implementation: - -```cpp -#include -#include -#include -using namespace std; - -int characterReplacement(string s, int k) { - int maxLen = 0; // Tracks the length of the longest valid substring - int maxFreq = 0; // Tracks the frequency of the most common character in the window - vector charCount(26, 0); // Frequency count for each character - int left = 0; // Left pointer for the sliding window - - for (int right = 0; right < s.size(); ++right) { - // Update the frequency of the current character - charCount[s[right] - 'A']++; - maxFreq = max(maxFreq, charCount[s[right] - 'A']); // Update maxFreq - - // Check if the current window is valid - int windowSize = right - left + 1; - if (windowSize - maxFreq > k) { - // If the window is not valid, shrink the window from the left - charCount[s[left] - 'A']--; - left++; - } - - // Update the maximum valid window size - maxLen = max(maxLen, right - left + 1); - } - - return maxLen; -} - -int main() { - string s = "AABABBA"; - int k = 1; - - int result = characterReplacement(s, k); - cout << "The length of the longest repeating character substring is: " << result << endl; - - return 0; -} -``` - - -### Java Code Implementation: - -```java -import java.util.*; - -public class CharacterReplacement { - - public static int characterReplacement(String s, int k) { - int maxLen = 0; // Tracks the length of the longest valid substring - int maxFreq = 0; // Tracks the frequency of the most common character in the window - int[] charCount = new int[26]; // Frequency count for each character - int left = 0; // Left pointer for the sliding window - - for (int right = 0; right < s.length(); ++right) { - // Update the frequency of the current character - charCount[s.charAt(right) - 'A']++; - maxFreq = Math.max(maxFreq, charCount[s.charAt(right) - 'A']); // Update maxFreq - - // Check if the current window is valid - int windowSize = right - left + 1; - if (windowSize - maxFreq > k) { - // If the window is not valid, shrink the window from the left - charCount[s.charAt(left) - 'A']--; - left++; - } - - // Update the maximum valid window size - maxLen = Math.max(maxLen, right - left + 1); - } - - return maxLen; - } - - public static void main(String[] args) { - String s = "AABABBA"; - int k = 1; - - int result = characterReplacement(s, k); - System.out.println("The length of the longest repeating character substring is: " + result); - } -} -``` - -## Explanation: -Sliding Window: -We maintain a sliding window using two pointers, left and right, to explore the string and check valid substrings. As we move the right pointer, we add the new character to our frequency count and adjust the window size to find the longest valid substring. - -Max Frequency and Validity: -The key idea is that the longest valid window will have the majority of one character, and the rest can be replaced (up to k replacements). We keep track of the maximum frequency of any character in the current window, and if the number of replacements required (i.e., window size - max frequency) exceeds k, we shift the left pointer to shrink the window. - -Example Walkthrough: -For the string s = "AABABBA" and k = 1: - -Window [0, 3] → "AABA" has 1 replacement and max frequency 3 → valid. -Window [1, 4] → "ABAB" has 1 replacement and max frequency 2 → valid. -Window [2, 5] → "BABB" has 1 replacement and max frequency 2 → valid. -The maximum length is 4, as achieved by the window "AABA". - -## Time Complexity: -The sliding window ensures that we only traverse each character of the string once, making the solution linear in time. \ No newline at end of file diff --git a/docs/Sliding-Window/longest-substring-with-K-different-characters.md b/docs/Sliding-Window/longest-substring-with-K-different-characters.md deleted file mode 100644 index 5c690c54c..000000000 --- a/docs/Sliding-Window/longest-substring-with-K-different-characters.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -id: longest-substring-k-distinct-characters -title: Longest Substring with K Distinct Characters -sidebar_label: Longest Substring with K Distinct Characters -sidebar_position: 4 -description: "In this blog post, we will explore how to find the longest substring containing exactly K distinct characters using the sliding window technique." -tags: [dsa, algorithms, sliding window, strings] ---- - -## Longest Substring with K Distinct Characters - -### Problem Definition: - -Given a string `s` and an integer `k`, the task is to find the length of the **longest substring** of `s` that contains **exactly k distinct characters**. - -### Example: - -Let's consider the string `s = "araaci"` and `k = 2`. - -The possible substrings with exactly 2 distinct characters are: - -- `"ara"` → Length = 3 -- `"araa"` → Length = 4 -- `"aci"` → Length = 3 - -The longest of these is `"araa"`, which has length **4**. - -### Approach: Sliding Window - -To solve this problem efficiently, we can use the **Sliding Window** technique combined with a **Hash Map** (or frequency counter). The idea is to maintain a window of characters that contains at most `k` distinct characters, and adjust the window dynamically as we traverse through the string. - -### Steps: - -1. **Initialize Pointers and Data Structures**: - Use two pointers `left` and `right` to represent the window's boundaries, and a hash map (or object) to store the frequency of characters in the current window. - -2. **Expand the Window**: - Move the `right` pointer to expand the window by including the next character. - -3. **Shrink the Window**: - When the number of distinct characters in the window exceeds `k`, move the `left` pointer to shrink the window until there are exactly `k` distinct characters. - -4. **Update Maximum Length**: - Keep track of the maximum length of the valid window that contains exactly `k` distinct characters. - -### Time Complexity: -- **O(n)**, where `n` is the length of the string. Each character is added to and removed from the sliding window at most once. - -### Space Complexity: -- **O(k)**, where `k` is the number of distinct characters, because the hash map will contain up to `k` characters. - -### C++ Code Implementation: - -```cpp -#include -#include -#include -using namespace std; - -int longestSubstringKDistinct(const string& s, int k) { - if (s.empty() || k == 0) { - return 0; - } - - unordered_map charFreq; - int maxLength = 0, left = 0; - - for (int right = 0; right < s.size(); right++) { - char rightChar = s[right]; - charFreq[rightChar]++; - - // Shrink the window if we have more than 'k' distinct characters - while (charFreq.size() > k) { - char leftChar = s[left]; - charFreq[leftChar]--; - - if (charFreq[leftChar] == 0) { - charFreq.erase(leftChar); // Remove from map if frequency becomes 0 - } - left++; // Move the left pointer - } - - // Update the maximum length of the valid window - maxLength = max(maxLength, right - left + 1); - } - - return maxLength; -} - -int main() { - string s = "araaci"; - int k = 2; - cout << "Longest substring with " << k << " distinct characters: " - << longestSubstringKDistinct(s, k) << endl; - - return 0; -} -``` - -### Python Code Implementation: -```python -def longest_substring_k_distinct(s, k): - if not s or k == 0: - return 0 - - char_freq = {} - max_length = 0 - left = 0 - - for right in range(len(s)): - right_char = s[right] - char_freq[right_char] = char_freq.get(right_char, 0) + 1 - - # Shrink the window if we have more than 'k' distinct characters - while len(char_freq) > k: - left_char = s[left] - char_freq[left_char] -= 1 - - if char_freq[left_char] == 0: - del char_freq[left_char] # Remove from map if frequency becomes 0 - left += 1 # Move the left pointer - - # Update the maximum length of the valid window - max_length = max(max_length, right - left + 1) - - return max_length - -# Test the function -s = "araaci" -k = 2 -print(f"Longest substring with {k} distinct characters: {longest_substring_k_distinct(s, k)}") -``` - - -### Java Code Implementation: -```java -import java.util.HashMap; - -public class LongestSubstringKDistinct { - - public static int longestSubstringKDistinct(String s, int k) { - if (s == null || k == 0) { - return 0; - } - - HashMap charFreq = new HashMap<>(); - int maxLength = 0; - int left = 0; - - for (int right = 0; right < s.length(); right++) { - char rightChar = s.charAt(right); - charFreq.put(rightChar, charFreq.getOrDefault(rightChar, 0) + 1); - - // Shrink the window if we have more than 'k' distinct characters - while (charFreq.size() > k) { - char leftChar = s.charAt(left); - charFreq.put(leftChar, charFreq.get(leftChar) - 1); - - if (charFreq.get(leftChar) == 0) { - charFreq.remove(leftChar); // Remove from map if frequency becomes 0 - } - left++; // Move the left pointer - } - - // Update the maximum length of the valid window - maxLength = Math.max(maxLength, right - left + 1); - } - - return maxLength; - } - - public static void main(String[] args) { - String s = "araaci"; - int k = 2; - System.out.println("Longest substring with " + k + " distinct characters: " + longestSubstringKDistinct(s, k)); - } -} -``` - - -## Explanation: -We use a sliding window that moves over the string by adjusting the right pointer to include more characters. -The charFreq map keeps track of the frequency of characters in the window. -When the number of distinct characters exceeds k, the left pointer is moved to the right until the window has exactly k distinct characters. -The maximum window size is updated at each valid window. \ No newline at end of file diff --git a/docs/Sliding-Window/maximum-sum-subarray-size-K.md b/docs/Sliding-Window/maximum-sum-subarray-size-K.md deleted file mode 100644 index cf63a4eb6..000000000 --- a/docs/Sliding-Window/maximum-sum-subarray-size-K.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -id: maximum-sum-subarray-of-size-k -title: Maximum Sum Subarray of Size K -sidebar_label: Maximum Sum Subarray of Size K -sidebar_position: 2 -description: "In this blog post, we'll explore how to find the maximum sum of any subarray of size K using the Sliding Window Algorithm." -tags: [dsa, algorithms, sliding window, arrays] ---- - -## Maximum Sum Subarray of Size K - -### Problem Definition: - -Given an array of integers, the goal is to find the **maximum sum** of any contiguous subarray of size `K`. This is a common problem that can be solved efficiently using the **Sliding Window Algorithm**. - -### Problem Example: - -Let's consider an array: -`[2, 1, 5, 1, 3, 2]` and a subarray size `K = 3`. - -The possible subarrays of size `K` are: -- `[2, 1, 5]` → Sum = 8 -- `[1, 5, 1]` → Sum = 7 -- `[5, 1, 3]` → Sum = 9 -- `[1, 3, 2]` → Sum = 6 - -The **maximum sum** of any subarray of size `K` is `9`. - -### Approach: Sliding Window Algorithm - -This problem can be efficiently solved using the **Sliding Window** technique. Instead of recalculating the sum of each subarray from scratch, we can slide the window across the array and adjust the sum incrementally by adding the new element and removing the element that goes out of the window. - -### Algorithm Steps: - -1. **Initialize the window**: Start by calculating the sum of the first subarray (the first window) of size `K`. -2. **Slide the window**: Move the window one element at a time across the array. For each new position, adjust the sum by adding the new element at the right and subtracting the element that is no longer in the window on the left. -3. **Track the maximum sum**: After each window slide, compare the current sum with the maximum sum and update the maximum sum accordingly. -4. **Return the maximum sum** after sliding through the entire array. - -### Time Complexity: -- **O(n)**, where `n` is the size of the array. Each element is processed once when entering the window and once when leaving it. - -### Space Complexity: -- **O(1)**, since we only need a few variables to keep track of the current sum and the maximum sum. - -### C++ Code Implementation: - -```cpp -#include -#include -#include -using namespace std; - -int maxSumSubarray(const vector& arr, int k) { - int n = arr.size(); - if (n < k) { - cout << "Invalid input, array size is smaller than k." << endl; - return -1; - } - - int max_sum = INT_MIN, current_sum = 0; - - // Compute the sum of the first window - for (int i = 0; i < k; i++) { - current_sum += arr[i]; - } - - max_sum = current_sum; - - // Slide the window across the array - for (int i = k; i < n; i++) { - current_sum += arr[i] - arr[i - k]; // Slide the window - max_sum = max(max_sum, current_sum); // Update max sum - } - - return max_sum; -} - -int main() { - vector arr = {2, 1, 5, 1, 3, 2}; - int k = 3; - - int result = maxSumSubarray(arr, k); - cout << "Maximum sum of subarray of size " << k << ": " << result << endl; - - return 0; -} -``` -### Python Code Implementation: -```python -def max_sum_subarray(arr, k): - n = len(arr) - if n < k: - print("Invalid input, array size is smaller than k.") - return -1 - - max_sum = float('-inf') - current_sum = sum(arr[:k]) # Compute the sum of the first window - - max_sum = current_sum - - # Slide the window across the array - for i in range(k, n): - current_sum += arr[i] - arr[i - k] # Slide the window - max_sum = max(max_sum, current_sum) # Update max sum - - return max_sum - -# Test the function -arr = [2, 1, 5, 1, 3, 2] -k = 3 -result = max_sum_subarray(arr, k) -print(f"Maximum sum of subarray of size {k}: {result}") -``` - -### Java Code Implementation: -```java -public class MaxSumSubarray { - - public static int maxSumSubarray(int[] arr, int k) { - int n = arr.length; - if (n < k) { - System.out.println("Invalid input, array size is smaller than k."); - return -1; - } - - int maxSum = Integer.MIN_VALUE; - int currentSum = 0; - - // Compute the sum of the first window - for (int i = 0; i < k; i++) { - currentSum += arr[i]; - } - maxSum = currentSum; - - // Slide the window across the array - for (int i = k; i < n; i++) { - currentSum += arr[i] - arr[i - k]; // Slide the window - maxSum = Math.max(maxSum, currentSum); // Update max sum - } - - return maxSum; - } - - public static void main(String[] args) { - int[] arr = {2, 1, 5, 1, 3, 2}; - int k = 3; - int result = maxSumSubarray(arr, k); - System.out.println("Maximum sum of subarray of size " + k + ": " + result); - } -} -``` - - ## Explanation: -Initialize the window: -The first for loop calculates the sum of the first subarray of size K by adding the first K elements. - -Slide the window: -The second for loop slides the window across the array by adjusting the sum. It adds the new element coming into the window and removes the element going out of the window. - -Update the maximum sum: -After each slide, we update the maximum sum if the current window sum is larger than the previous maximum sum. \ No newline at end of file diff --git a/docs/Sliding-Window/minimize-maximum-of-two-arrays.md b/docs/Sliding-Window/minimize-maximum-of-two-arrays.md deleted file mode 100644 index f93692c08..000000000 --- a/docs/Sliding-Window/minimize-maximum-of-two-arrays.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -id: minimize-the-maximum-of-two-arrays -title: Minimize the Maximum of Two Arrays -sidebar_label: Minimize the Maximum of Two Arrays -sidebar_position: 3 -description: "In this blog post, we'll explore how to solve the problem of minimizing the maximum value between two arrays using binary search and mathematical reasoning." -tags: [dsa, algorithms, binary search, arrays] ---- - -## Minimize the Maximum of Two Arrays - -### Problem Definition: - -You are given two sorted arrays of integers, and the task is to minimize the maximum element between the two arrays after selecting exactly one element from each array. The goal is to **minimize the maximum** of these two selected elements. - -### Example: - -Let's consider two sorted arrays: - -- Array `A = [1, 4, 6]` -- Array `B = [2, 5, 8]` - -We want to find a pair of elements, one from each array, such that the maximum of the two selected elements is minimized. - -For the pair `(A[i], B[j])`, the **maximum** values for different pairs are: - -- Max of `(1, 2)` → `2` -- Max of `(1, 5)` → `5` -- Max of `(1, 8)` → `8` -- Max of `(4, 2)` → `4` -- Max of `(4, 5)` → `5` -- Max of `(4, 8)` → `8` -- Max of `(6, 2)` → `6` -- Max of `(6, 5)` → `6` -- Max of `(6, 8)` → `8` - -The smallest maximum value is **4**, which corresponds to the pair `(4, 2)`. - -### Approach: Binary Search and Mathematical Reasoning - -To solve this problem efficiently, we can use **binary search** combined with properties of sorted arrays. By searching for a minimum "maximum" in a specified range, we avoid brute force calculations that would take too much time on larger arrays. - -### Steps: - -1. **Define the Range of Search**: - The maximum element lies between the minimum element of both arrays and the maximum element of both arrays, i.e., - `minRange = min(A[0], B[0])` and - `maxRange = max(A[n-1], B[m-1])` (where `n` and `m` are the lengths of arrays `A` and `B`). - -2. **Binary Search**: - Perform binary search on this range to find the minimum value of the maximum element by checking mid-points. For each mid-point, verify whether it can be the possible minimum maximum by ensuring that the selected elements from both arrays are smaller than or equal to the mid-point. - -3. **Adjust Search**: - If the mid-point is valid, continue searching on the lower half. Otherwise, adjust the search towards the higher half of the range. - -### Time Complexity: -- **O(log(maxRange - minRange))**, where `maxRange` and `minRange` represent the search space. - -### Space Complexity: -- **O(1)**, since we are only using constant space for variables during binary search. - -### C++ Code Implementation: - -```cpp -#include -#include -#include -using namespace std; - -// Helper function to check if x can be the minimum maximum -bool canMinimize(int x, const vector& A, const vector& B) { - int idxA = upper_bound(A.begin(), A.end(), x) - A.begin(); - int idxB = upper_bound(B.begin(), B.end(), x) - B.begin(); - - return (idxA > 0 && idxB > 0); // There exists elements <= x in both arrays -} - -int minimizeMaxOfTwoArrays(const vector& A, const vector& B) { - int low = min(A[0], B[0]); // Lower bound of the search space - int high = max(A.back(), B.back()); // Upper bound of the search space - int result = high; - - while (low <= high) { - int mid = low + (high - low) / 2; - if (canMinimize(mid, A, B)) { - result = mid; // mid can be a candidate for the minimum maximum - high = mid - 1; // Try to minimize further - } else { - low = mid + 1; // Increase the lower bound - } - } - - return result; -} - -int main() { - vector A = {1, 4, 6}; - vector B = {2, 5, 8}; - - int result = minimizeMaxOfTwoArrays(A, B); - cout << "The minimum maximum value is: " << result << endl; - - return 0; -} -``` - -### Python Code Implementation: - -```python -from bisect import bisect_right - -# Helper function to check if x can be the minimum maximum -def can_minimize(x, A, B): - idxA = bisect_right(A, x) - idxB = bisect_right(B, x) - return idxA > 0 and idxB > 0 # There exists elements <= x in both arrays - -def minimize_max_of_two_arrays(A, B): - low = min(A[0], B[0]) # Lower bound of the search space - high = max(A[-1], B[-1]) # Upper bound of the search space - result = high - - while low <= high: - mid = low + (high - low) // 2 - if can_minimize(mid, A, B): - result = mid # mid can be a candidate for the minimum maximum - high = mid - 1 # Try to minimize further - else: - low = mid + 1 # Increase the lower bound - - return result - -# Test the function -A = [1, 4, 6] -B = [2, 5, 8] -result = minimize_max_of_two_arrays(A, B) -print(f"The minimum maximum value is: {result}") -``` - -### Java Code Implementation: - -```java -import java.util.Arrays; - -public class MinimizeMaxOfTwoArrays { - - // Helper function to check if x can be the minimum maximum - private static boolean canMinimize(int x, int[] A, int[] B) { - int idxA = bisectRight(A, x); - int idxB = bisectRight(B, x); - return idxA > 0 && idxB > 0; // There exists elements <= x in both arrays - } - - // Custom binary search helper to find the first element greater than x - private static int bisectRight(int[] array, int x) { - int low = 0, high = array.length; - while (low < high) { - int mid = low + (high - low) / 2; - if (array[mid] <= x) { - low = mid + 1; - } else { - high = mid; - } - } - return low; - } - - public static int minimizeMaxOfTwoArrays(int[] A, int[] B) { - int low = Math.min(A[0], B[0]); // Lower bound of the search space - int high = Math.max(A[A.length - 1], B[B.length - 1]); // Upper bound of the search space - int result = high; - - while (low <= high) { - int mid = low + (high - low) / 2; - if (canMinimize(mid, A, B)) { - result = mid; // mid can be a candidate for the minimum maximum - high = mid - 1; // Try to minimize further - } else { - low = mid + 1; // Increase the lower bound - } - } - - return result; - } - - public static void main(String[] args) { - int[] A = {1, 4, 6}; - int[] B = {2, 5, 8}; - int result = minimizeMaxOfTwoArrays(A, B); - System.out.println("The minimum maximum value is: " + result); - } -} -``` - - -## Explanation: -Binary Search on Maximum Value: -We perform binary search on the possible values for the maximum between the two selected elements from the arrays. - -Helper Function: -The canMinimize function checks whether a given maximum value x can be minimized by confirming that there are elements in both arrays that are smaller than or equal to x. - -Update Range: -During each iteration, the binary search either reduces the search space by moving towards the lower half if a valid solution is found or shifts towards the upper half otherwise. \ No newline at end of file diff --git a/docs/Stack/Balanced-Parenthesis.md b/docs/Stack/Balanced-Parenthesis.md deleted file mode 100644 index 67f32f18b..000000000 --- a/docs/Stack/Balanced-Parenthesis.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: balanced-parentheses -title: Balanced Parentheses -sidebar_label: Balanced Parentheses -description: "The Balanced Parentheses problem involves determining whether a given string of parentheses is valid, meaning every opening bracket has a corresponding closing bracket in the correct order." -tags: [dsa, algorithms, stack] ---- - -### Definition: -The Balanced Parentheses problem is a classic problem in computer science that checks if a string containing parentheses is valid. A string is considered valid if every opening parenthesis has a corresponding closing parenthesis and they are properly nested. - -### Problem Statement: -Given a string `s` consisting of parentheses (i.e., `(`, `)`, `{`, `}`, `[`, `]`), determine if the input string is valid. An input string is valid if: -- Open brackets are closed by the same type of brackets. -- Open brackets are closed in the correct order. - -### Algorithm Steps: - -1. **Initialize a Stack:** Use a stack to keep track of opening parentheses. -2. **Iterate through the string:** For each character in the string: - - If it is an opening bracket, push it onto the stack. - - If it is a closing bracket, check if the stack is not empty and the top of the stack is the corresponding opening bracket; if so, pop the stack. If not, return false. -3. **Final Check:** After processing all characters, if the stack is empty, return true (all brackets are matched); otherwise, return false. - -### Steps Involved: -**1. Stack Structure:** - - Use a stack data structure to store opening brackets. - -**2. Functions:** - - `isValid(s: str) -> bool:` Checks if the parentheses in the string are balanced. - -### Time Complexity: -- The time complexity of the `isValid` function is `O(n)`, where `n` is the length of the string. This is because we scan through the string once, and each push/pop operation on the stack takes constant time. - -### Space Complexity: -- The space complexity is `O(n)` in the worst case, where all characters in the string are opening brackets, and they are stored in the stack. - -### Sample Input: -"()" "()[]{}" "(]" "([)]" "{[]}" - -### Sample Output: -true true false false true - -### Explanation of Sample: -- The input strings are evaluated for balanced parentheses. -- `()`, `()[]{}`, and `{[]}` are valid, while `(]` and `([)]` are not, due to mismatched or improperly nested brackets. - -### Python Implementation: - -```python -def isValid(s: str) -> bool: - stack = [] - mapping = {")": "(", "}": "{", "]": "["} - - for char in s: - if char in mapping: - top_element = stack.pop() if stack else '#' - if mapping[char] != top_element: - return False - else: - stack.append(char) - - return not stack - -# Sample Test Cases -test_cases = ["()", "()[]{}", "(]", "([)]", "{[]}"] -for case in test_cases: - print(f"{case}: {isValid(case)}") - -``` - -### C++ Implementation: -```cpp -#include -#include -#include -using namespace std; - -bool isValid(string s) { - stack stack; - unordered_map mapping = {{')', '('}, {'}', '{'}, {']', '['}}; - - for (char &c : s) { - if (mapping.count(c)) { - char top_element = stack.empty() ? '#' : stack.top(); - stack.pop(); - if (mapping[c] != top_element) { - return false; - } - } else { - stack.push(c); - } - } - - return stack.empty(); -} - -// Sample Test Cases -int main() { - string test_cases[] = {"()", "()[]{}", "(]", "([)]", "{[]}"}; - for (const string& case : test_cases) { - cout << case << ": " << (isValid(case) ? "true" : "false") << endl; - } - return 0; -} -``` diff --git a/docs/Stack/Balanced-parentheses-checker.md b/docs/Stack/Balanced-parentheses-checker.md deleted file mode 100644 index ab3800b25..000000000 --- a/docs/Stack/Balanced-parentheses-checker.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: balanced-parentheses-checker -title: Balanced-parentheses-checker -sidebar_label: Balanced-parentheses-checker -description: "This algorithm checks if the parentheses in a given expression are balanced using a stack to ensure each opening parentheses has a corresponding closing one." -tags: [dsa, algorithms, stack] ---- - -### Problem Definition -The goal of this program is to check if an expression containing parentheses is balanced. The expression may contain three types of parentheses: -- Round brackets `()` -- Curly brackets `{}` -- Square brackets `[]` - -An expression is said to be balanced if every opening parenthesis has a corresponding closing parenthesis in the correct order. - -### Approach -This program uses a stack data structure to solve the problem of checking whether the parentheses in an expression are balanced. The stack is ideal for this task as it allows tracking unmatched opening parentheses, which are then compared with the closing parentheses. - -### Algorithm Steps -Scan the expression: -1. If an opening parenthesis `((, {, or [)` is encountered, push it onto the stack. -2. If a closing parenthesis `(), }, or ])` is encountered, check if it matches the top of the stack: -3. If the stack is empty or the parentheses don't match, the expression is unbalanced. -4. At the end: If the stack is empty, the expression is balanced; otherwise, it's unbalanced. - -### Steps Involved - -1. **Initialization**: - - Create an empty stack to hold opening parentheses. - -2. **Iterate Through the Expression**: - - For each character in the expression: - - **If the character is an opening parenthesis** (`(`, `{`, `[`): - - Push the character onto the stack. - - **If the character is a closing parenthesis** (`)`, `}`, `]`): - - Check if the stack is empty: - - If it is empty, return `false` (unmatched closing parenthesis). - - If the stack is not empty, pop the top character from the stack: - - Check if the popped character matches the corresponding opening parenthesis for the current closing parenthesis: - - If it does not match, return `false` (mismatched parentheses). - -### Time Complexity -For each character in the expression, insertion and deletion operations (push and pop) on the stack take constant time `O(1)`. The algorithm scans through the expression once, making the time complexity `O(n)`, where `n` is the length of the expression. - -### Space Complexity -The stack can hold at most `n` characters in the worst case (when all characters are opening parentheses), so the space complexity is `O(n)`. - -### Sample Input - - Enter an expression: `a+(b+c)-d+[e*f+{g-h+(x-y)}]` - -### Sample Output - - The parentheses are balanced. - - -### C++ Implementation - -```cpp - -#include -#include -#include - -bool isBalanced(const std::string& expression); - -int main() { - std::string expression; - std::cout << "Enter an expression: "; - std::getline(std::cin, expression); - - if (isBalanced(expression)) { - std::cout << "The parentheses are balanced.\n"; - } else { - std::cout << "The parentheses are not balanced.\n"; - } - - return 0; -} - -// Function to check if the parentheses in the expression are balanced -bool isBalanced(const std::string& expression) { - std::stack stack; - - for (char ch : expression) { - if (ch == '(' || ch == '{' || ch == '[') { - stack.push(ch); - } else if (ch == ')' || ch == '}' || ch == ']') { - if (stack.empty()) { - return false; // Unmatched closing parenthesis - } - char top = stack.top(); - stack.pop(); - if ((ch == ')' && top != '(') || - (ch == '}' && top != '{') || - (ch == ']' && top != '[')) { - return false; // Mismatched parentheses - } - } - } - return stack.empty(); // If stack is empty, parentheses are balanced -} - -``` diff --git a/docs/Stack/Conversion.md b/docs/Stack/Conversion.md deleted file mode 100644 index a57501a2e..000000000 --- a/docs/Stack/Conversion.md +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: conversions-using-stack -title: Conversions -sidebar_label: Introduction to conversions in Infix, Postfix and Prefix -description: 'Converting between infix, postfix, and prefix notations involves understanding how operators and operands are organized.' -tags: [dsa, data-structures, Conversions , C language] ---- - -### Header Files - -```text - #include - #include - #include - #include -``` -### Operations on Stack - -**Structure of stack** - -```text - typedef struct stack - { - char a[max]; - int top; - }stack; -``` - -**Initialise** -```text - void init(stack*s) - { - s->top=-1; - } - ``` -**Pop** -```text - void init(stack*s) - { - s->top=-1; - } -``` -**Push** -```text - void push(stack*s,char x) - { - if(!full(s)) - { - s->top++; - s->a[s->top]=x; - } - else - printf("OVERFLOW"); - } - ``` -**Check Full** - ```text - int full(stack*s) - { - if(s->top==max-1) - return(1); - else - return(0); - } - ``` -**Check Empty** - ```text - int empty(stack*s) - { - if(s->top==-1) - return(1); - else - return(0); - } - ``` - -**Precedence function** -```text - int prec(char x) - { - if(x=='*'||x=='/'||x=='%') - return(2); - if(x=='+'||x=='-') - return(1); - if(x=='(') - return(0); - return(-1); - } -``` - -### Infix to Postfix Conversion - -```text - void ITP(char infix[],char postfix[]) - { - stack*n; - init(n); - char t,x; - int i,j; - j=0; - for(i=0;infix[i]!='\0';i++) - { - t=infix[i]; - if(t=='(') - push(n,'('); - else - if(t==')') - { - while((x=pop(n))!='(') - postfix[j++]=x; - } - else - if(isalnum(t)) - postfix[j++]=t; - else{ - while(prec(t)<=prec(top(n))) - postfix[j++]=pop(n); - push(n,t); - } - } - while(!empty(n)) - postfix[j++]=pop(n); - postfix[j++]='\0'; - printf("\npostfix expression is...\n"); - puts(postfix); - } - -``` - -### Infix to Prefix Conversion -```text - void ITPr(char infix[],char prefix[]) - { - stack*s1,*s2;init(s1);init(s2); - int i,j; - char t,x; - j=0; - for(i=(strlen(infix)-1);i>=0;i--) - { - t=infix[i]; - if(isalnum(t)) - push(s1,t); - else - if(t==')') - push(s2,')'); - else - if(t=='(') - { - x=pop(s2); - push(s1,x); - } - else - { - if(empty(s2)) - push(s2,t); - else - //if(prec(t)>=prec(s2->top)) - { - x=pop(s2); - push(s1,x); - push(s2,t); - } - //else - //push(s2,t); - } - } - while(!empty(s2)) - { - x=pop(s2); - push(s1,x); - } - while(!empty(s1)) - { - if((x=pop(s1))!=')') - prefix[j++]=x; - } - prefix[j++]='\0'; - printf("\nprefix expression is...\n"); - puts(prefix); - } -``` -### Postfix to Infix Conversion -```text - char stack[max][20]; - int top; - void PTI(char postfix[],char infix[]) - { - int i,j;top=-1; - char a[max],b[max],t; - for(i=0;postfix[i]!='\0';i++) - { - t=postfix[i]; - if(isalnum(t)) - { - a[0]=t; - a[1]='\0'; - top++; - strcpy(stack[top],a); - } - else - { - a[0]='('; - a[1]='\0'; - strcat(a,stack[top-1]); - b[0]=t; - b[1]='\0'; - strcat(a,b); - strcat(a,stack[top]); - b[0]=')'; - b[1]='\0'; - strcat(a,b); - top--; - strcpy(stack[top],a); - } - } - strcpy(infix,stack[top]); - printf("\npostfix to infix expression is....\n"); - puts(infix); - } -``` - -### Prefix to Infix Conversion -```text - void PrTI(char prefix[],char infix[]) - { - int i; - char t,a[max],b[max]; - top=-1; - for(i=(strlen(prefix)-1);i>=0;i--) - { - t=prefix[i]; - if(isalnum(t)) - { - a[0]=t; - a[1]='\0'; - top++; - strcpy(stack[top],a); - } - else - { - a[0]='('; - a[1]='\0'; - strcat(a,stack[top]); - b[0]=t; - b[1]='\0'; - strcat(a,b); - top--; - strcat(a,stack[top]); - b[0]=')'; - b[1]='\0'; - strcat(a,b); - strcpy(stack[top],a); - } - } - strcpy(infix,stack[top]); - printf("\nprefix to infix expression...\n"); - puts(infix); - } - -``` - -### Postfix to Prefix Conversion -```text - void PoTPr(char postfix[],char prefix[]) - { - int i; - char a[max],t; - top=-1; - for(i=0;postfix[i]!='\0';i++) - { - t=postfix[i]; - if(isalnum(t)) - { - a[0]=t; - a[1]='\0'; - top++; - strcpy(stack[top],a); - } - else - { - a[0]=t; - a[1]='\0'; - strcat(a,stack[top-1]); - strcat(a,stack[top]); - top--; - strcpy(stack[top],a); - } - } - strcpy(prefix,stack[top]); - printf("\npostfix to prefix expression...\n"); - puts(prefix); - } - -``` - -### Prefix to Postfix Conversion -```text - void PrTPo(char prefix[],char postfix[]) - { - int i; - top=-1; - char a[max],b[max],t; - for(i=(strlen(prefix)-1);i>=0;i--) - { - t=prefix[i]; - if(isalnum(t)) - { - a[0]=t; - a[1]='\0'; - top++; - strcpy(stack[top],a); - } - else - { - strcpy(a,stack[top]); - top--; - strcat(a,stack[top]); - b[0]=t; - b[1]='\0'; - strcat(a,b); - strcpy(stack[top],a); - } - } - strcpy(postfix,stack[top]); - printf("\nprefix to postfix expression is...\n"); - puts(postfix); - } -``` diff --git a/docs/Stack/Evaluation.md b/docs/Stack/Evaluation.md deleted file mode 100644 index a400475ab..000000000 --- a/docs/Stack/Evaluation.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -id: evaluation-in-stack -title: Evaluation -sidebar_label: Evaluation of Postfix and Prefix expression -description: 'Evaluation of expressions using a stack is a common technique, especially for handling mathematical expressions in postfix (Reverse Polish Notation) or infix notation.' -tags: [dsa, data-structures, Evaluation , C language] ---- - -### Postfix Evaluation -```text - int Eval(int x,int y, char t) - { - if(t=='+') - return(x+y); - if(t=='-') - return(x-y); - if(t=='*') - return(x*y); - if(t=='/') - return(x/y); - return(0); - } - -``` -```text - //evaluation function - void EvalPo(char postfix[]) - { - stack*p; - int i,t,x,y,temp; - init(p); - for(i=0;postfix[i]!='\0';i++) - { - t=postfix[i]; - if(isalnum(t)) - push(p,t-48); - else - { - y=pop(p); - x=pop(p); - temp=Eval(x,y,t); - push(p,temp); - } - } - temp=pop(p); - printf("\nEvaluation of postfix expression is..\n"); - printf("%d",temp); - } -``` - -### Prefix Evaluation -```text - void EvalPr(char prefix[]) - { - stack*m; - init(m); - int i,t,x,y,temp; - for(i=(strlen(prefix)-1);i>=0;i--) - { - t=prefix[i]; - if(isalnum(t)) - push(m,t-48); - else - { - x=pop(m); - y=pop(m); - temp=Eval(x,y,t); - push(m,temp); - } - } - temp=pop(m); - printf("\nEvaluation of prefix expression is...\n"); - printf("%d",temp); - } -``` - -### main function -```text - void main() - { - //max can be any value - char prefix[max],postfix[max]; - printf("evaluation of expressions:\nEnter postfix expression..\n"); - gets(postfix); - EvalPo(postfix); - printf("\nEnter prefix expression...\n"); - gets(prefix); - EvalPr(prefix); - } - -``` \ No newline at end of file diff --git a/docs/Stack/Introduction_to_Stack.png b/docs/Stack/Introduction_to_Stack.png deleted file mode 100644 index a294a464f236534c3aa83f3824f68ff28fbdeb23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50019 zcmcG$1yo$i)-KvK?u|>3MuNLLjk{|?aCg!)4#C|TcM>c>a18`^2u^?iK|*i~1cyMl zY&rX!|Gl&S^WS&xTca7HR@FD9W_@$6s_r$2)>K!(#vsQ4007uZin7`O03sLwK!Bqm zKK7XZJVyZlu;%S`4Pl0Asv?%I&K%}et`^oD-p+21;{bq|q_>;7rK2?rY+-F{?;=in z+}1@4wzm?eHQ-m{Qgf5BwzF6Cg<9+Qs_R<%I$8=_(Mn2y#k@rx6*ybN%)#EyPA={u z-r}^s>lJxy|JKb(3;rDfa}=kQ`pqENP)!po;|jF~^K%HWTXOU9fCYs)xCOX`dHC4C zJY3v@oLqvO+`Q~u+#*~8BD})jKQG!xYfvj25p7xdKW#nUiPPG_U~VFuoL*jD9A3N} zu25S}Zed|zPA(o!9v=2b1iQPB3(VY`-Nl{m9~xw>-7TT^ZZLaS7w~Ty%`IF#VB)lo zp8hcfXScu9y14%trpJJBdYij(a&vI~Hl^QzR+fL^+&rL8zZ!QF3vInY&n8E6Iw} zK03)^Z*L_cD9B?WXvJg2ZYjuX&dz1YXT@$I%+14YVZ*~~VQI;0&TA?B4|!QvOOM}{ z{WtkPGQi5!@=?cM@e&c{73Ai7%o}!oD?wp)er`T~c3~THD|Q}kEE2~G1+yVl8<~&?n>_S$&Htc*{d|d42*8CRimcqQ;Ts&5m!Z!Ru zwBUc*m2q`)g{rw)Jw}`Nw-orDiXw{k?vG36^Jh}&Sik(Ur|9{B5$A^r_V@>?4O8)QFvp?*+{-4&x-w5*;mqc`}yS+y1kd{1f*(M*Wee;rFfz)toy)_zhNtmnK z-^l(p@}HvQ=HYJlH{!n!{YUw~weI#mu+INCruqM)-~Zp^1c@1Xp-}v(P_}^mld$su^y*U3#rvH+FzeE0IbN&yh#~uG~&A*Nsk2ilER;*nf zpPSIfqlnMl@!jJw2Hj2ZnL7Z0N$}er0w6n=^zj@7&{WlxQ*cv7_^;O^{I8Bb+K7mV zNJvOPAn>t)jEwx)e(Vno4FxC%0X&Ny9v%REFUeE7`#ZaP+B<&zdiZ&HaCd!lclYc5 z_B1``H69*bYG&S0cki#ei?jWu>$BbZhL-E=`=i6-{`xnl$Vl>RB=EE>Z$*lls%m;l zVgNi#;3=^VFPWP(d0R`{m+6nj!o&|l{uSQbfLCFeHq5g0K!nVK?yB@(@9h9FNhv0@ zZ=gK3qGS`DO-~7dA?g$eVKKkfe11(tJU26c=y_QiA|9(peLchDXlGj;Wi-36rmkxk z15d4uR-PN_&3RqqtHa1kfmjkCdpj?K@TQUw1E|f8xUu;o+e6w~f!@&#S{Z~|!Ycy!Kiwk(*E8P;>S0#PUOnUUs1Va5mm%tF&)ORC~O1L;FZ+arwii^p%yZ zlU(_C$qrX18$bF`mTjG0*txalxqL3eDr!jyfAO?2FUVCHnffVXfQjHnGsCozNo!3V zf~)&|g~Zj2eUKTNjs*MG@_1jVSB$fgn1br)@Yvh>J|7Ry3^#OufQYG{W`Ci@dc2Uc z78in*y)+-|bSckNI6se=WLnv)rlHaw$5*YT#o@j_s89HQWHE-jnJra4KOE50SCH)X z<9Ny=0FRC<%E%hc)#m14EzOKR*xA5jkj)5noOJW(R#$d6(;oFj14zj(^)@y*<7dSL zzl-%x$g0{83|gx8-}?wfFf^HN$$C@TQaG@PP}y$Hh5Ws~T*SaJB(CVGjL{oYtmTq| z1a0KT7}mMCh*fnZ1GiYmz}z3hZw|X-1M(ar=$zXh=5~QAV4eF-(dBQdQ#_U_2f>mNY000Ik$x7*ZFCFG}BrJa* z8j38o(t0Z!0BajC>GL!vA*ueZQapzI0!4A-qXwJ<0%y6GPh}X!+k>k`flMR3&&(a0dGx5E>vx>b-%_V~3%04KflC65-1XKtlqc z8e;^h!4=SoIY>8N)K@=i6J!APO%9Z(k-Cvjm3{f`LENys%7Z0$TJ)aB8J|H&wkSvFRMuH zK|8(&Ea!1Co!e?DFxn>zmFSj0c`oHNykL+>q^MRNhh!08Xmu1K3r1F^It)+X+`gDc zo&k;YC1nvP{s=0@55{8htfj_~oOzdsK~I((4m8&wK--?|sgA?jnWi1e_M=I!qt_r% zoLq+aB}$|EX)97UT{*ckw#rI90$&&Hkzr6C+NWA~s2q&146s~UD^$qr5BN4hSdwJz z5o(3Ww}RrIxTlh_ep)sz1b1Pu5G!6my11?ck)kVm=FLY3$EZQWv|6CiR-e&G-)%U1jDx=$0Q~uQLP0@X|S5e0kHcLc}Bvl_-ao_5}ki9(TI4xHl{}%)sH}t5<6)@ z`T3g@#VliLT51~54$l)jSKuWroTnbM5|VDO6f{D7+0`b8vLnBYLP+`^%`qWlgO+ANG50h#H}X<<%{e}u!-w%QTb&yrwGFPF=G&G zd-lZ{ob4BkJz9kWB{3wtyYd#?~vH0dW8^jy6=>MJ$RmC*0C-6#S-<=+(+cn#)VtrLshU0*J`0O@pC+{RsS0To}H39#lPMJf)sj zS;Tt2Lp_!M!BGLP3iIDp2M9z@jKUAG8y6X!7i=HVlzN_L=rW1iorsO;zH482w2j7T zd<0fXP{l03J&bNK;6LkcOBEJQ}5FX13PkWQ47 zLuXCrh-{)M|{M_NlSl;JF$SDNGpm#ffVQ3O@l_E#&Z z02`wz z@>;)Wg;s{d+cysHvNiPvh%M)oguy+tef$;mZ8%&?u7N1mzAqxm6*k3Z( z3Zo0d3sXc7j0J2hgDm-o1_6OLgTQFawXxX7WbRjQA-4lmxCRVx2_i)@jA9X5P!>+z z?o4kqk~Rc9DcB!_X?j6jFYy_L=Cgekqgu=JJ#D+qfsdqnM-FQ#cxaI%2RBIdYpKrSqZDv5xiVXHOz2-WGj=dORU5h??;v`m%?rGUMRZ1riF(DDH?4Cu6 zSLMypk``n ztqv{U0)~}0o%yKVFoef#$RD3;8$$P2DD+$i;P4VmZva3FH<@7>2msV#I%KP_BLKt@ zwPA?0IO~u57lnn_5M4z>@n=_Ytv%)|-1B;iI)E2BkW@==u9r*Nk&9WfXN9A=z_0sA z(ygR^H0MY~&yAll^4DsY4Pfmt1N6&0RNd#ewW-@1l;a^zPVO?K1?u3r^S*ql#~MGP zZ!A}mj=WdWD!(_)3`l4!NP@X2QSnZ&>=RQNEOV0UsN{#4Xg60pyl@`UA26>~S!lu8 zjZsIajeu%2S=NwHllWdx8;lP5(t#wJk<;|So^#e+tihQ*=@=S&N2E!656@v3L6(Ez zCTlBMx{C9&TvcV$$Fmr+iwz!<-Iy!7Sc}t8C>^`KAeJJxPaj(lUx0g4rFtQ$bMn= z&iPz|gipL_1gDthC^qAZ4aGog2B&8z>8>!4TPCptXI~$8$%_SU7J13Dd@U-`Bp0lC zX@Nu{2fHA91mNb(=RDyg=8UIQ@nQvSwdn6n5F#5yPuYE+MM2h1;UVc+DQp`u)02w{B?b^)^&e;wf1nf{;Ti){vLIxgYo(@diTld&!0DCny!(W*5!(`C9_&w!{E#e>GMigcdrx{efx5F2_;~gHQ|H_Fs4Y4* zZK4-D_?#YH8|@EV{3#kW5}nUaZkv7@oqg=MzdNf5yy@GS?7Ba=dU$oSb?NE5qPqO< zb5-CVX}f0?!YQ&OHRXzOQz4d}=>)&AMV6lAyT9xzIM1T&(djt%68& z-jY^W;fH=2ImlF^dHt(W1n+4Qr>Vs9L*bY2%e`yMD9>B8mNYHA-3c7G$8%%}A8e1E zq?ew55?U>1FLHDCC@xR}i!&f>bdwpBYS!}*lAsQFs}B#vZ}N-@DGrwze- zPBHe*k{+I=2SE&mejC8gQQN9s9uNBR)aZDQc3T? z8_9>AfQe~J2`@3dSE%57ae$O$2jDw4%pcJ>xM}D48hd&woV9MXQ=X&27kT)z4u}n$ ziS0*HOB5Q5a@&vlDe=|LMRvx|Z|^+wnO9(Fh&2Dm=cmZ6#kSHH1rI&loZ0?Mr4!U(B+QQ}w`fCPGYW{H zlk@@@_mdi_vm~z&o%v4=twgl@2t27)1nhayJPzo zqe60Nt1ycmZ!>>y=bICJZ|MS0w-&<9f}qIHe#lX*)eq&C(%xe_J2-GZAe}i2rBy97 zJPPR=5y+j?O$KZr@!Z9m$Hq%UTd_bM+5f;c3P31+#co0Ml7w z;lActa_#|ZhEW7@#kDt+p}*WaSyT^;4Cxvm0<(u}3|xMhNDVkGWTRN zWnMA}$WpGm2CWe|qS+$Hk{ZA*v_iRHN)uA4^{tiWq>H&uez0!FT~E4tdX0>nacFC^ zW#EG3`7}2*)Cg)MC!!SbhVq3>dq@@rpvdgUsZ$AKQy^K)8}T)awyTRn~FI`eJY+aS;6uQ`;!tHO0j+ge}(-(DU;a9 zsn0XwEu3#^xmkK;&JJ=!NI&FRExU$7&s%<}P3h%|BI6;4F^IsvS~Ni13tgCoxLdeL zdIJgd2Uwn`r%&1@g>16wYmHZcnTS;8Qr=<|>$(xLX791s&6VcBE$7IOXTn25;y-+5 zR1E#(>vj)54RJJf;iHJ`)K96-#fD2HJHCi;Bw60m&TS(cRlkdtvgOG8iR+^LfepMK z)l&K;NJomV!cKYNHDjp50Q{+9xm6J`86QbaslXpon%zdpIra3`uor=D z+p*9ma!tAWYJX;)u_oO~l{9x>mE8+b6GZkY7=fGqSrbHHtTLLYAC197FRdq$ zlt%|{EM_F6n{hCQ&tmO7ze)t6!0k|lERQo(`4Brx*&B?VYHhuNd;7%bwE#DHfV8P8 zw9?XBUiculIA8AJhTV%-KP&DIrG6!=!_kC|>CGmIEf_wOdYgAEX zEFR4hiPrCN&L5t>_p4o$KM-%9YKdIyo#guQr3}VLi}y39K?Fey?k`6GsAF@aT*NJA zdPDbIYfc*ipURTkQ8?Ew7va-gGbT5BPR_~{BffrQ9i8^RDMk)A>{Y7fPbEArS zEz1#jeaq?tk6n2P7bID#uRcZ&6ES4GHLJIQcKDUzrIQGXEC*SMw!Iz63B;eNa(y!s zKi%(i%CDX1}`2Hp-S?Y1vjoRiE>>?FE{mS?$-S%2M}$R1PcO z;5EiUzFI;Rzb7$H6H8*GhBbc=C8tsDZub)_bleMyT(}uPm=*@N#OP@~YioO^dr@5J zV52Pvov1cxoxM9Kk|(P4btA#k*2EAMwU5dWn-LWa;vM@R-+h7kmls78d`3K6zbzC=Mr z%?B#mpgpC+P>TGZpV@TDBfHuN&_;la`KMp7B!6?6m`Zu3ss=ak-P+&Y=wDjXCyyWO z`PkFbGn#?Q%K9VCo1%tIU;nGHmpL!_gxzu%yH={?ams=R~99Ly*1YSv+j8&MyLJR^t;PSGw2sW3L!odg?X z6Te4#A&aqf90b?BIoeN@tOn9YB{?MUev?N^4D1wU0MOQ?B;!P^$XlhJTM)U6>}JxB z$Yhr!37Fuc!NI~t{bie>hqLfE^q)HeC{RW4U#g?Vgd*36B2Fb-1N%^h$T2i?ZF4jP zUi0HzdLGWpHCn30cyNVfevGyvZ(ed?PYg3(3!OWeDk7T;r?2sT$my+X zeR*C(2S(yPZH}Ns_lL^VZ>bl8iKmrU?xLVT7Ukipr$?kc_QZSJ#->9ZQA)z5b@Np* z@7y8XH6&+c1gwsPTBif5iuJcgv9_d%Ei%$e{lIu?VxAw1b})Yn3kM1d3F26)S{p(e zaZ)M`pOufcJI_}*&V0ol#CNDRbIe7fsD-l<*J#}%Ni?L8Fuz@~8Fb0`r>-4SQ&J*O zS4cYFHBPJAzY}q`a)&#cD}>Ov*`X;lF;NUbq;<>mRF~!g6chj;Og-plov(d*vu%#t z5D4Sx{Ot!hqpt%lCglP@=sP16B$Lq_V{K1DaCmCj0JwIEOxbzy15^VR8`HaYcXy#X z(PL*LJCnSV)cyJxMl`QtIC!a@)tm0|8SY6Eca{z6A}G1NHwc5qyd|higpgmt;=R9X zSVFR0@xX7Wo>V*-2AD?VV&*j$Z==&QtvHC@ktjrEvNi8U^mT1GkPxS^AFlNUMN<=J zB%49vUf>V{c`Dvyjc-HCe#GRdXX^38IMBk9_?;7}QppM67DLy6Qw`Koe5btaHIcZ!8!D;`OJTGq&jtOfK`>QGB$Q;4-+tI2_;q=I>#adLS@ zUUcMu_V)WPIm)Bg=SO&1a3%?TB-xH{j+!1vtlz?5OaL{L12roX5z@m zA}SNZM)b{)XfN}7rYzrGcTtdpLD}^OOhtNNV0<3|+we+$Pw=_`_qE)E;5K#5+V@ue zg@fA(!~n)0KMp)MKV#x5qOlGiT%p0^?~4Ken*pt8cBx5Wc81EjX7si^Pqn>NbdPRVtT z%j?5qN{V)Vp@qqaqwetoQ@e%p_cBoLuQ`s4qUU|0BorV?CdGHE2#Z4p`-2R1N6+^I zH;qm02=<6SJCxT~=~?wTJATO=tW?HVNft>Zq>0|9F?`P3N_qAsh32UQAFg_VQD%7e z3zc$^`6fz$mNxSyK1K*JMhDY}bKKOAolY-Jfw#IYZL^WzXjvlC@#WZPzq6+Ar|-i4 zaD;33&-Y8aZ|##`M@B@FD&aSdLgoZ#3+E=L$zChy;-@he;zM z)*>=7u?&xH%6|QJ;r=4*WysBoR~mf&rJ~touG1eVF!j#ktrfG#HZl4Qs9!rV&-HNQ z>Pc&sm*%K^+xiTM|28yNR( zKEH(WzY#DejK+wWbsu^7d8_L7;0-#Zk?==}#w?&ka=!2DA`FieqO7VSq^LSSbTcID zV*GKwcYiw*zV{Hzmi|^2D>hIhR?kRBKT4N+I^2B-XI7tL)!P%KN@i2bp3 zV+?o%N?#Vu`Ht$haq=(&UfzbsTBq|8x+_)4g5Qk>DP|==8~iyvIO2m*`Sq3{g}@He zj??s8qs(E5h~H%-HHS(2wO8ZW4mJK0f1!nCGp1?q{<4tod6@-ec~PkX=i-?j%t$0n zvA6-NJ}6Iz5Esn@*Up_Uac0k}_0Y46+KeVfS>Riv2nD(OT|?TE5(en?H|(>*>-wpv zwBx=dNJMJW+-6^-hA9>(mr1t$Jw>p-UWq)>5YFc7A8z2+1Z7L=1t(rJq79>@#ju-{ zb=V5&t9^~Gkt(SueqK@0FN@xG2OE&_e1syaz1J#MPaWR}VO^*kfnz3e82-U>Eq3}zfyXQv(C zKT!balhm!r2nm8vNU~QZUb>A6RlVURF?MOD_ z3mQjX7{C2R0EB~M2o{-8L+cFPba}Fh&D;o0YSD{Mz97#>e5y-U3f8;nYlMH(X4WDU z6>ejUS!4rawM{C(zgd#L#?{(*-{#+`h(si;9p#|UT0q&hwh;lUTv^$>I-~P)U9RDb zyJdccc}h~n^nx!J#me8;!uvElyqD#c+4M$^UOOP_?Z7)hHX^F3h4&c4e)Lr!H_=o3OJJ;zulN?fm zQX`BR{kX(tC^3d)o&evAu1=4dZ)?p5EBx8+577uOevaUltrY8eS30bzBb>ez=nhY;3Og)Tn+pOa3n@4=?*0@E$-O0LTmT%oVC5c!G)&_{o1DI$&&_EnFE@4D`D`#hiCpM`6co%^EibbYg`~E30 zBNO^y=_+6m6hG9h(o zl?ikFH75wd@Jd##Z4=~9PEf5T*jqBIOx~g~J&uv?1=5p>U}c*#`W6Fqf7Piy=seYk zSc?S|xL3yDS&WqAC8$uU9NYGMA8$7*X#IkEzu`b^fSP>08``ujuV>|WU2FHIb~m^l z8!?D)YX`X;kmMT?C!KthME^-s6}Xoa24YQ5jpq(Nk}?MZ@aR2qzx^0N3e$24L)&%M zT$yO?=c^`fck{~LQTRY$=jE~-F51flR)fTa($i2H<Jv#@<;%=@=IH^DPG9BhKsBmQsF+Xm z!&CmY0W#kU@UJ*|_YyN`_oTo9B+P(JPmqHYjC0#Ji~{6grME1TgzFooptsQ5(6KYv zGZNs{-F>!aTx6l%IFqX{ck+dDBr9vEt9SW&ob`s6+D@9ZyxbUEX`_SC8j8kQbP;Pu zQ*Wu1GA?~@7PY_pyxz!znW(IgL#W;E9NxKF8!l503!KY^P(+l2GJ|w7~mu* z*I8-y8nRMh4F_dT129FxmgAM#?C^@>y}0$|@%-vG;C$a%T#(({3@?K=dO{Tia7 zlf2_n1at3-Ce7ypE@Yl)s^(VGT*Mto zWchdL(>^@dfI`VMlh(+|T_$(*4GaRak*z>c-FptKRRrzcKP>$3ke$NR(Ub=>P{&^r zZRQki2`n-}*jRpUMvmb{X<~y#gYu z!z?Xb+TMRY`c6ayMror&M~-WqpPn}NfSL7xu2H&^)z3O|^EQH23Rla9EQdN%^tFj! z-U=leZN3%E{`w|I?D_jAZ?koYL}YNBNT?${btM;bu%yT0_@vcA=6FGszs_I3AEv4i zHR*a4us1VTVZa|1B#uJm6Z~T4!Q1~PwUrRj2pxwAAL()1J9LjUf<EEWM zza~;c%;UG1iY1(9sy0&wR})$jWJ8f$v&o4FnRA^z@QA<6Sty{{wA)!*K2;@WA6{w- z=SoN`8I_p)*(of%R7~w&C+e^^JWZk5F4T4R`r)U4J2X$GYI=b}hO(S~(~aexMDlVc z6*4^3uV(7cLOnzV5`dBOZ#q8MS(2hJ_V9_|L$_wqMl+J|uFcr>#u&+@6troX(9TGN zVLL1eVan@L0*W(8i`OwT!6e0q-?!?sAhgK#e(#m*_VR97UyL%ygiqUQ{TwsY3;_Z@ z<9|>dkujB*l?fLbR>F><$iv7c(j{SKR?5mI2Ug%XSk#fSkv9#ZaMIG;FsoaP;$sfu zWyU@odv+aVHC!VpK`2TVw3*CIhd*NQaa!alUXtD24=+-?`;9Lu88s$y@>5Mv3K^uQ zVI&Br)t-bgoP1g#rn;P<6sZES*r#7G(ZJCe0L4%1%2$Xxp2>t!Y&G*!k$bLell&=# ztOXI9n&m|L4Qp~1LB#CaMDg;JtkOw80XQU=n*xq*GA)a5n-{^qpw>9Jwk727G@nM4 zA$0uH0aSO!uC!M^g&K(XKJYNn$)`Npq*yEm`*4u<)X%%N9XokV*=m!wXAZx1`92Okr*#yYOp-xE=VIzIH636jNul=fiq z*E}K8W_EI62;-<)pcplLqA4OGR=ZhqEPeGpZnpW5uc|v-mMhA7XNOb6(jR}sJX079 zje3VEnTvHZp7FXd&?62(sm0x&PYXhy*o#Mx)LZE-_Mzc)XQwubtQC5*A6}u&oRp*; zfhHMvrDraMpP1YCq&1xOlazHx63rdBy>E$7zarB_Dm&AgLgbPRP1vuZM%r>3{_&E9 zr!Xvzxktii$8_ra3qUvbg5B0dLpAtvy2RaQCh(z3XvjT@WF`> zO`(;!&AgUS$dSQFdVidBJ(bZGQtAXDV z=HCaQao{_=RFzjY!6uICR%H07V=a%8^&kYM{>F5mYO!5N3V*9h4n6s5I}1nlqu!Q; zIbf6Z2I(0Dob(Q!eRrYwXx59*nu6~2o`uiw9qZ?Mi0ap3)z}HyNMrrtmZavS>#?QN zcQL`Pr@T5!QE;BSEd(gb#(6M5=RQKE@O}P(O37#KM0do+_88jd&xMOB;D zP8=QefZ%@q_v8D`#libkl`uSAyv@*@oYy%+Vv6;dELuXz?%*tm;ar~rkT#xd@>YE1 zop>oEQ<(*$4vpH!N80VF#6Dp1oZh?pbg4}(Lfgye;UxKU~ATS0Vc-il|EJOK5 z_llQC-6AS2hh4c85uCGrqFzkiTX}blff02&9Y42X3_)s$_$m*c`2bGyd`Ur+^d%`I zx6!Akmr&5|{VdrB48uvn9=nqli4W6Rn^Nc&$S-4U5|TlqM+`FW2&9Ms^;}<(Il;OC&ErRPxcIL-BsPT(V1`?E@HGlMom!z-vO)p%bI67thP#* z_r-aF8Y%4PYBWX_)I|K%>A_Bk2E!#+PMr%_3g8I`m^>cbu5tRf3n%KZGtVrIaR!qt z2+fk-UK%MQKgGR83tnZ_MY!Y%Pj=t&^}SOr;W0d7+GRMnZSi;}^lhwjZD zP*IGnpTZ(zH&@rSUF0RQjSKc>OT+If>m(mYAp5w0LQ;*sAuPtUW`7h}KylC#Xn*c$ z>yCh+peX>nJB1qb6*X#TY}Dm7;+5d#<&|*1wZI!6rauEO_^lFW9ysGm zvqybc7CU}x^sHWt*m7$mViV_c&}SDx`{#2)4M^^^vgEspDE5Wx6m~rwthsEqG#4G| z&;6>x&Mntp5Iep!vNiQDDQv-|BVP~3PMvN^%Fd2Zcq8VoC=<{8TqQkSn52P_T_lj!(b2u_@tYZO z^=}SAEf_A1>)0J_<7&RsS*RmMp4VgZ<#>mF^$WFJpQW><++xZ!)K3peu9aJ$h0I`5 z7GC`y7K^kMVMEWD$m@x0Lfyt}^RxF!)jUk1%J{|46um))8?=hrKVbpnh)^g39?7{f z{gr7%A5xMx%oY_PIzk$Apyv(rJP|T1uTpdPZQ)l$>0pC^AZNH{MeLV^>x#Sy2S%cB z(8pe^@ZcFY60f%I8TU=gT%E7|dmj0?l>=rSI48Bh4okuB8w?G*;CHf7b6?TFPUlf1 zR97o(APBj4t5 zH^F{Hyf$7Ay@x9n0Y63|q~{Ga-r`!+K(qdP0kQn1TlCI~SVZ*2{JiTgve-rI9BMS* z=;AReG1^;NFE04&O@>T{EL_(*Z+?x>FYI4b*?vz?H#{C3)bMM=zQ0N-ZA^NI3OB^2 z%Kud*+>3hcE`Gle*!=_@@zm^P@iRo~8yjbIW?nWr4Y8vSO@7DAt-R>D-SrwvY5{g) zY{a#P&@t-5GWvb)b-{AvR<%*R#{~0ma44tSiq?sK;cK(41>8JG_4NMq9q{@EWWiR@ zyo8A~TBy%X*3%P^%mg?U!jPb+IJeAgqCOLQ^2BfBnJMnB<;g-#hIB0wh1v8sunK3neNgqOS}H95LX*ku@xOU4iI9> zis)VkV(JuUGa4%jV$+VUma;6OdM!vUVcMWUrXrd1Edo8S5BN(RpqQaUP?Dp%}j!+lx4UpD(e}JGZtL`10`XWWc=i>>JG5n%j6nK~5E-crTs=qQOlr zRp|J-^7!L&v64RSaVsDnUHXE~wHs-E+03pPtC2*~o^dkJOD?UNLgGPho+f8hcIQW7 zn0E)7lIRu264W5z|1k)~a`8?VkP*LzN( zep^*Wl(^Qo)XA;UR)G#5lH=6r`v_h}Q1l`vh!3YHzaZ}!V7*sf-a=Mbqsx7vC|Kua zqz34x{OT=6o%eKVGT-BjV$$8cqfs}>3cc-Ug*<-cyR+++ucKPiiV4K5{x~vbo`uro zdNl%KKP*O5xMFy|Azj9e^zsVTb@(%08i*}NTj+CBGh`itVNj;c1kk%q+q(uG7|MKW8;$$rYNkp41j8IKXe~7vBZMa66)Hq^-RBs&+1TvgyJqNT_^5 zKiufI-FF@4O{*CB5Dz^>Nq09k=_}-=uU638bF8OJ2nwpXGj9m?FAk@5sP zqSIf}m}{$Mb$8ksv+IUT72^9*8`!{~U?1Qs0()uq`z61np(?yngWl5&7&)?_RiUd)h4=)Dq zi!lxRmjJ_N4<2M8`)wJv`5jC3li27*SBxY_DM$d??q4?=E^6uy97WiP#)Bc|lqW`# z%L{3*Ha?Y~y?|(ncoSq)gAw$ITp;xL(RJi0`4D;_Nf??y@fqp;vl&0e?DUV{MhmiumV`@z)m8Z_tBK z#%SNKt8ufM7^1?8+ByMPzE*-L82&$=S&H!4SVa+G!%ZX(o`Jl-zd)-U0V5CxqLCI2 zrHqIYXlW&XEHNWPmhQKwUZ0tf6&S_v8QJg1bW>|}>rItj^o-saFEOjtWhwc@H%DM` zr|lDrQ)gytbM~}%A?w$|vX?F)v^U}LEmePdu&rc+!6Hz)`E>wTdjDe7eXV-=m*(r} zds{g_g@&QG;@VFrhdARwM-vF#*`TcFA6H!YvLU|D9aQsYo#bd`^_`x3T6$;hAd;jf zdsiN~)rmzN7D^j0c#UW+`$xMt79E3dJ*s>$3kh*z%c$SbO4+PTdD&f0BW$KJ4exly z^oj@K3`LbN15B8V6?Mpb?Z;bZ~H%%530#FyfWCJD8;t$hV5lG8_pYnVt)Y>*M7BB3qXgpHX5-1`o+|NNyP>AJ-)p?$Ba zko^tolETR6!%h?D?O7ymuLKO4yLcL#TXA%%X_ZQfb7L#&x~PzyyKWErW`hPpppmWB zI&(CdKX}JL7KQjj+f;0UAxDOCH1qalXef-(LGMb7l4M(#s{$Xz3;=q{{Yk{(-CSz{ z;xHrbFkKr5SXMC}EsMXVohrNO_{hI0<1@k(o_%l80}0wN!WUh8>3+nd?}Mh(odXUC z{hIxw5Im?!>9{`D(+;iN^SC%BWzEz|{7=YygV0z*qise0Zzhfh*$m{MZ1at^iP zVf!SdWn)MOswW^!EMWz z=XT{j#82$48woF%`Pjm8RRI*mVKM%nd$(p9VIluYg-}78YJmM z&H-VRCfu3=R2gO~_v2x>-y)cfUKgrU7zYhvUn}-a8&?K{zQKe)X4_{~iMC$j)4R3R zH*1<0{>;W@rQZNkB^KM_GVeIQ(>(-0SpYsJRS6(4ktd?G120{QvAes$K^qo4!k;fX zidd!bsP1$~QE9_qm-{gQ1cC{c3Wj`{wUOIfJQ*nSB6Dr*KR3%|djlsA`c~s<>w|V$ z4$Cl(aTI3P$EC0Fpka5QR8i?wkSr}tOTxsQI`KU2SvsEc*b$L>q}qAw_sf;%CK7}o zOD)$&Qc7xh+b1LTB8Bm7{%Ba-;!J|)d9@+R1GLF;nTtdy_z;pL_mM_3S!I!1r=AnN zWmcq*AcI5LhzWMx0pAh;ICi-GwUV+6XmWWR&#=_1eDg3`;e;<`3D0?)*xgBb~FZiCDK(R&>6bvni7ActDbptV-d6rvh2A)gT%gP9D`pkPP%`v67# z*g5CEL0o_}i&j4(Yi^1|86$Bcj?sLzA<4%t0Y^&kLHKz>NG=9M zHRF&@O$rU9y|`90p0IKYb=lpy2)?VM7jwPehmd5>nv+Z4q=>(0lYBeTWRHgMO$(EZ zhM>p%J;GekyClOg9Zk%4aON^M_H;62^rRy7oJJVu-l-O_b~yI)ONP=WbAuVXR!SS` zU@dteLwZTnjKltnBoZ;XADdLDHJys?u2r8+n*G{yo)C!FJf;&-5KPiGOgBC(D5~oi3w4|wv|YhsHGzLuuO6- zOQ9)&LYpu^R5Uq(MUpg9wY8W%XFn+@Q>EnkT?Uj~;-62jGs^^2`-wy4%E(h9_3W%OV* zGsH2I3@Ho3Nb$~WGocWa7YQT_SyD37GfhhuDl2a-3F$);uMVnRC9ZaqZCR?UyL}s2SAdwnt^jxay=ep)?V-3{-W*@$WvK78cpf$$#0hXR^M&t zZE484$^|Oqw0r#D3aOVn(54sF+I^ynV0cSv%zYtT$Yak)n)#QX%#?~ka=NC{1l|)S$QIgiI2?WKt0@|P1|wt{t&I8 zmlyJC&JC>8M6`hj1=BO;u4Am@I)I!WKrY=rBM>6j^`a9Nh`fb=+l9YAeE7FNmVf%! zcjA=apZ2Fw7Bmv(jjP&#p*m6>85!YyRd%iPm&Y>$`3uJYqS631T)jO)Ab>3)_z52Z z*bfpw&ryiZSMS9qkPznPqZPd4yIl&0i_e}DRH;WI?mkn(Nk_afShDN#x_PHXKqxR3Kv-*vhR6t^Cp@y>{lxLZ|7Ni z6+88+wya6~Xs85(f}i#pJ>6lQKYI)yfg9+}OAozT$$O(Qgz6RVKlVcia_>$u z*BFX7CLG{FRZ+&Cb8MFq`OFYE+jwy$kwitoI3xY#p>X>wn zc~4OcvV3NAbTqOtuLE+Iwpq2e7>Vq^eDL7G+lq0sL=w@g5PHjP1Bk}3wE@l8ovm}9 znT`P@W^4v&bK@mPtkRO-mGve;LeLixM@%6Ad}dC=ofq`vSAYpikJAubpW>9^&5y%& z*d!38D2ic;JH1=3{Fl8mYE5HJGcouO@$&q*Y_dF>29b0;8~Yq6aJ zp*ieMI(Knit1Zi5)F~l^B^to`Gr623b540vl%9jbvFQ94C-641xzOTJfT7dHo5S50 z62|k1KwN9JH0|U34GJ>VKgk;RVvP(S{-EoC2ssqiT(biz!bIep>Bn#Gp9TU3ef=Cx zxBcB`M-mRRg74n(@7OQ&$C=v!0rP=6fzI61zmrblfq)b%mHb+*Ch~GQi6!+dSSKeZ zU`l|IKeoy^)P#bj03TfNx(jQ4{SDHR=Cy1t>Rd=?2UN~U3$pZ05_A}5o7Ze7iT!{9Z%9zw+s z5D$2WG_<6KfYdN;XC322%H=d4V{=Xt3D|9^*q6n!4CC>{YD{heJfZC8*Yn?-%sW<) zQ3Iq4gdEV|P(dh_1RIf$OhedO@-jGXSiY;sXZP^F%FZTqAYq4Cw*pehaCPe$j&e6G zvqJij5-c|Fz2f02rjf4*#`!J~!s8a|4JG0r809h+)PVqOYnNrLh0s_OX z1j(!2H|q!!nwC{cCB&I0M9gX-sdTUwl87rC*UqjS4>CFSAfpG!i>}Mo5MgcY(0p{- z14Qu3hTR866#AWbLjQo0+@&BmI8LynYB7bg6>)SNCp1l=k{7II zo#QG-es;Ea_;2nySG?II<_ zNStn^^XShD%Y19`(IVbw53GvL9&5@uzUnJTWPFM>LV(nq6B@-svR1fE_I=|Vd)ey|mahQohzx_EK^f?YJnp$u5(Xpmkc z<+LoXi)lLN0!KoZbd&1K$JD$S4FF+TzV_m}f(!vNR*;bapa5OHj}pB#vN0`}leK%_jSf{+QBElL*lxdR+k zjw@D+TuPk z+kLMRA<-6Wv(_oIHXi4flUpYzG?4n$zh2>!ji<&k2xWDKSFVPX+G83XVtpZczXM8*m-LV(;qi)1_~A=Lpw<`(c%1c(qLHX!a{`S3XoWZ0qm zZ6a8Coy@u4J|&)h@WAVxxfPI#i4ld(rer5SSL+hS6dDyQk8l@y14E_sb|=))#Tw=0 zlv(VDy>^{QDVCvA28qClqd4Os>~y2_``kmh9Cl~n$Ocp*a57m%q(aMI95}w2*MJ%_ z24rLac{{&-eB5=p?0TVqgkZ>8lc`AW^0JqC>vcQ_yxMkz>Vw00_-#h~*DCC8J3k%M zqkTJHzkc=KYSK+psMkwi%2_Wj&NZo41k0T22au!k1W~fE|g>Vr`27>|w-_S>aVhSK2KN z98CK60R@?IQqm*NV+_a-4ah+3z|3DG!QYR&#iENH^-|bisX5m)n+ppdA|F6RUQhIE zAHIQx5~m2_W=x<;cwwPb_Br`sY}vw{9L2?u2b$Wx%T2xIRqj=sue zZAg|2UqDKzwVm4FX)Ml@oJfkpx;k)DF`815OX+f2R%=gpoS-}sIBtCOn%KG33%k9mJoK>Ad$2a}K|!Q*Z4=~cUFk=hmo^Vu_N)0zVjIX&zZ zpG=^mAST%E$+i@GHWM}!_%u)`NGq>UD#!1vua!G zL|?v)vf$@V3s_OoX^~RW@$47-Nzj~=PSEssx>9A&Itepe@M@uoBZ=CboTlR>761gc zUdqPgVBy0?WPFPC0|RoU9xOZ4iRPH`PaeZ2tN4!fn+X45@BBjA$hSD&t6g-d-rFV^ zP&39h-nK|h;TkI;5J)0s zV(&lhl7Z!S&z}7eggO9GaTJ6J6ctQXFdC4ACHT{>^Z;-06Q}d}%QHAX+E|?X-FLTa z9Ubj&2E=@B3Zt+o%yhpoHFX2zc?1`E*)HLREX88H3@Rj=QWeoD#xvr)J?^|)}b5-aO}NH(EO8|dtVkUm|iI+&2OI@yqXaMw!; z65>gzvgiyu#Y{S#UYwl`&w};dt2FZgSsw0(12hGn#1ZP~Nl1rc%+Unij*Nmd518^dhk^n%)76to!x?DvKFez#aEQf+T7Qbfo7PHuS=64-s@s zMg|!JKNf4N__)`{t9fI9)u*RnwHS=uA+!cXV95QdpV35F$FAA#(MrXHN%+SNNwM z9~maw-mbyH(6ixoWhJ<>OHwhq6>r*g}j{gkW72Wdq;nNXxv6UB7r9=uoA& z27K(ri>6k>iT2i8!zpuE8_JH4*DUl(?pe4iV4L=#wUb_W^Du5erpC;$pGMcp#uie7@DV zu-jIlqfd7uA2uK_KVFf})_0j2$vxlM`Q=~5V!7o1-i$%kk{N~iP57KGKkqX7gKC&$ z=+y9L-*S4qWsGMNH4k{DY_ZimAyE8=pWy(aU@ zNC&m)!wJal`vIio;|0XhUU4Iq_KVMd-F#a7`@@G1OC|rcmC$sjd1)zoGYbm*y1&TT z3>soz(=)ZW3L1ahm(U|%+$6xKN?5=+O5g<+O2v}VXf%}qJn$n0oVmOK$DmIU{r*QY_L|(? zK0VArn>oaQv>bboclID%Oou>#b?etVcQ%Vf>_uIAazDEgy4;C5i+J2G?O3d}65@Pq zs|M?9(G*uTn|?`BQmh=!Tf|rQtthN|5Hh}#_KNGNMp#RtL(`O?%k2`zfSr9;foI7n`vXGw2!-^nyalr8TYv)}3g_0fL9Z5< z1e^vk789^h9G^JTQI7|nQj84hIk0#H zoQdFb``iwvgXn({_5KX$*-%>|MHuO`4-e1VTaQKhTiPkpnIq*vEW~+qSS+B?A;8+) zq=fudEXJ|xCthu=Yx*yzCVpqdsAJ4At5`#Vst7&_2H(ZWm(g?~AKqR{L^D3!IC(0d@+kIZ2 z>{ArCMy47D2I**MHfUW7`<+;F1(BP_ZXbXHZGM;>^TYO5vNuWqu^(NLz6*ct-T%uf zR#TnH)Ld6b|4w!F_4Q5Uq^=I0o9gRN9!@|Y%py;@9l{3$SSyjp$~qA8qP!f5M9kw$ z=9{?4Yuyu2RS$y)smgNVICL&@Tn!$aEvKIzAkr^~3Ji~Y4IadSj6Rk|Tv#m#B*@a( zYT^gdvnK)JRRV760GT3n>C)dm`wX5lDk_q#xdmFE&hxSocYA5!At?m$Ndjp$M{<6# z1&Y?+4|rhbEZ0bKg5(Pj8)&st>0xIhABK-KAYU8|$k*=&kVX@+dSvA^Ic;n>0nnIE zH8kT@^QVUo5b8bfct8hlq63LcO_`TKguEy(MX&`B1;o%QuHrp7YejchxxJnuXK)lX zZX;)WWj{bJ%-b0aGu^LQel)tqkGLeb(HFyuX$5ZO)m1Ek0!$VbfPw@TgSc_5jvp}j zymwLN)g+;W*j!8k_W}+=hHnK7cwX|+EkscRk*+!YPQZi5O?JV>SN_?FZh}gyeLx=( z1Yy<@4zac^xdQ=tPa32i2szc*2%e(pl<9OmUN)X+XarW8O^uDG;OUS7!r&m*P9v<% z;^Us4h?x;mS~epgQ`ct8x4NpW;;M91G(7q-M3k#&zJ498E{?DH{{SKOg2(~_%#w@LV91)_S z1#mzWO@9~R2lo3#MG6W)5r~+e;GuBnzeC#qbsst*ZATT5KQ4Z;{a*pn&~&o?lQXA3 z{U3j+M&?USH^9>wlc^540c;@1LN9Xiuz8RU=0Q+`P(F$qouM9cc6@w_5(0pn>%6H0 zV%Y0r3%PV@N|)Z8?M*;%Z@$hQ=t1(`Z?K7Kh^1x}B*d$UPCusWf}YmWq6CQi5DW&# z78a7U;}4txBwo_X=Lwmdj-%5-i3c=qoQ%rR>uquNL0l920URtglq5yed_F-4Mk|gB zJ;=bY9drnV<7fjiWZ69!kZ%Ye4JYgW+;D>R z>eOp#?kXV=@J8}b5+<%Ockjb)QVixHK6ndZpq9W$kQ6K2K(H^?j1(HeKH0)7GpJh` zotKq9II?{y^-b2o^udRPmM-i$=XY;%lWI(N`w+W76V3HcD1f36n{dw-#VJWo1ASy`yVkX1Mku<2tPp^N%lp>tfk_bgy zG^fq&hA7H~2My8Q#EKcY)#a6d2U*O3dJIEyE=bY{dRR-??<*y8ai0C@Y%ht2ibxp) za%Q3Mo$=nK{Zf+jZ@%u)ubTe}kY-X2?b?ucRYrg?^0D^?94rSNG?Da$8WcH4zE9H9q1bXK#ckfL?376Rme}!jFWN@Q;w8k-Mk4R zfw0&s)DOFTH{jsiwxGyy3YzPpFwjBsfS94(Cp=}FCP-c*C$0#ZxTm#+k=LB-wK{jl zBa6fA%!tD|LYv2m(`|*HNMLKP$Lk5{b_X6p0)lj`mOUWv&&<&GFO>ku*sTISdTKuv zkDmII0cj~`K-xOB6rBJ$fCy_Q7W0j_u5WCtKfe8Jdtqtk(DKcA_tYH~5Qaz>lMFSo z>QaTIkdEx7`9v_fN&w_J!C}`Y9}Eh!`p?0B_QO@)hYS<$AMOHKnGih(LM+>Jb$KmSK)_h*?6AkJSmng8}mB+yXLY9NXXDpEnxs?Y}!? z7wd0%fK+}e9*xy{jku5lr6C6hyDC2gVYLuyb$@Xj8w3RzztVlB^)c}QgdF|SI`!o6 zl~EU7QOZHVRjzv8p55*(o~eJNAw>Y0>9?zrF}v5V%Rx|BLP?%;J4L~YV{Ac0AhRZe zhF}Vn1g`-RbRd;S6w(>N8^Ocqn-S*wj%~h@;C5p59P@L~8gz4Tp)1fN;jyyl3DVJB z1jOmrf~<$kbYd0r^wsmNAoIpH%{g%XtakT2Kn$gZShWV+_G)ZaFE4&oUt7^YCBw?v zimH0z1ORD)&%srh)j>1`Awi>|NQjALD33qVOWRhgz}1$MHN4E(lPxh3zD`^NT5a z5|jiWaif~x073zepbL`%wUf9g(u&}j^e{R(xH-2l7hYs|h-lsbsk_MYHc15}8($4+ zK^8V-Jv^5Orrz!Em!u%nYElqnl~S^3sHxZEQBhGt_4BHV3-zq1-dM{3VXMBOq8t@O zUDsY7FhF9EhWOS|Ko*veke!{Q)(4iQ`=-2}_6~hNuQmojcm89IwU~T_he=CDOxmYR z#kYCwI^EFjh)vuH0TyH*!8sRNhvLZ%r@{sr1enba$O^M;2%uxNUlM3S=Oh{_S_J{U z8dzt^9HsD*v|*!229ky(*3`W&8w6Nb)*w~!(^*?D8k2e>So46CLlP*j zS42g#SG1-VL!p&Lzv$pnDYVpL`Md0ohXBi2ET8vkJG>JRVoeN{Ga&Ci4nZ3ZH*6yz49MC*>g~5)Og{5y^&JrXnF$zfME!3=y{a6Ee@c-PmR|EPE-=!n3#V znujz!8OWq?pEu&NV%CmkB^lc0@=Mrxg(DGU1^28(&Vf#&9HiwquFVBG2o~R?nPG>5 zgV@M?&LN^8B|@PYJEk9_~T-WkW$iQrl3; zzFt>ZQmRtEfMl1s(`@cs8v;O{5+8%U@!f@gF60n-`^2){ZYp*ZJ=gh8C(S8UZ$BZt zG8bkc9cKcf5`tKS>5R8 ztjh$!*ki{4i4(YcW!`DCDI84`92O;#5u0t&7L>3pHxo$uJ>hVA&Nb%^$K&V;mvS1&fc10i2F zAn&zi#p+xcy|%ff=d=Z~Qu>q8g4sx2-G%Z5#Ef*%T3Z7^wvQpaiuDcpHny39ENO`R z=r}NSY36Ubc{$p9{iMSDq(lv`fChMLGqtglg8|ajesybpXmv2QYCc6lSS5r}5u)Sd zDj*3d$YUX05d#+bTc7b`){WNG6lw`FkNvpJuiAyXwq$jM-X~M|U~UBgj#bpgw#+OvXcr#8V&ybVEY~bYzyg-pjQY>%-@^{i(#4zwTvJ z_YoX*HO&p5_=~DrTjdCdnT1yb$hG<2Rghd7VmbQO*sdS5rn&5DAJ8?c zT{Fn)$UClMii_4qHqgFraF`ia>0Q4XyTGMj(9M<5N@L-MxGJ!2`60pZ<~7 z@-G{!MVl2>`A{EF5)y|X$;pF8Ks3Zzu>NuV=8YT6$sp*63qmcBk;xG>?SULZ0Yres;?GzWAjnNS2T_RFFRtAsapw5ETzK##%bMeh68J=0lC1h+Vpg zYieDC@$l%;&=3;{U-tmR0afA;)89{jf9DPWac6mX`3_+{P!0}wr>-F12YBd2J`6G~`NRcp(0kQpuy)$@iBfsMKUiu%jfi7{p zY19w~S2dEm#yAW}n(9z2P>O6-(ArZhszWZL1!tjC=8%Rki!sr_U|-}NmW2ip=r%eC zQc^lFjzMV1L4o9uKy;~z6Ox5sdg`I?`+hSc$#%Rc&B1GHOk@)~BnN%+ec#`Ezwg8R zA}o2FI0}as#e~Ui zn2{d~N|ZJeqMx2rlOKF^S^yao5GcqZ2xp+JX{10 zpEC{@7>5O3(ah=q9EgU`?$Cox1of9Yc=q;o_jbwBtgmlvJ%9fC*|R6~y!w3n$XP5o ztg#|GkZ5H%<03|_$F{dgJ;NvHp^!H0$> zUFgz-TFderyIh*ha+y`YO(#{&P(_5429l9rN9PQN8Iie|%LeP7vDXtzKIy9>QWMcZ zw6PAvaax{@oQF&{SIl5&rO_xBv#I5oxsqY&xZ-R1zUQM^7!+DmV|CkIg;eC20&;DX z&HDiq1ohP=281=_#{K&@9{ppBo`-`)7TJ*G&eq$nzy9Oz#kRH2{(1*Mh-O+c`8eWX zk9pwd1wj#F0V;q60^*}IxiQ%KcaNG_zNtxabaoZe!FJs@>_)jjWmJ|5pnQI*YRBW; z_MXP6Rw9ukgPu;$VE~a+O0d#%Ce7|-HdRiiXG%gx2oI{ypdO?rnG6P2c!>ydeRH$R zGx>_d+fRsxrsn%bLL2y))^{>oG9}KR zpV)aB;t&DBI4~0Xun=5CyP|{C(JIR8GdA%}k>TCH;} zSgjNN!JDTYkh^_C7MYMg{Om0xWUyPvXT2|X=v}n;VE6Iky$FPT4|DNkKrSv0CZB|1 zCm|x}z8^KsYgw|?M9j3PvHC?8@^n2%wT-3p+;R$tAmXYh_SA}9QXGl}b(>bnhf@_* ztX6G|AL42)(UTD0B+G$a>R3`p_1ZLk8f8~Hg$Dav+LYii+5sc;^OB#}NI?`4)_|vd zd`1)JA*)u-F{tVr=+|NbJC^!=uLC z^@?d}GRa7#B8!#?;Ls|_W+w?T?D{rAQX;33g1smfdAMpSBQDP(x`f4KA{p)~WLe>o zQ2YR-BaYkb8DuR^iOFAh`O<7E1wNL(q`w$@wUjUiOVNBy*Ejk@y%_8Lcm&9aF0ti0O3QetXP$<7LgO5N+A>| z^>le==K4x$>av3nMxCrUI)fVmk$KOt2$0PIK#pnj=np^8Gx8uqge;Oz`#B^eEVI_b z2Mr7YWc3;A1?CY4^LWojchm>m_`#r`|KU!$qHCV#%38;DT}_tZNMO{1a*L`jG(;+` zdc#($oTrNjYDfi3h{$Q@8Y(-$2M&ArEBtmm!!dGbgp|`{JaW0Ge9y43QYe(v$zM7M z8s(E*?w#{s$pzOJ3bM%`S4M!G3I&M(Aq7E|<@X6$kIs76djRD1PscAti#UTc>wRg9 zgPTAOqa^lzxmdbxI))~B-Zw;uKz{ns45$3qsa~iuAxpZ?)IkLd@dWfjw(Mkrjkw4P`CHVh8z% zy$2w;809#=?zSAm?Z~o=`QD0Um_&{wdmjDQ-jywa#3O3#*;3H)cuIaG9vBfe9jSnf zEPYgSfFld9GDV+L5RAX`AH&2J*g&2`K3_;D6N!6TIB})$cnQiZy%_?s`Ds{ZjQ~06 z3bL=pB0|0j2w@Qs3Iaw*K%T^67Y7z`_N60Au@0x)BV!&rR6b(g1&CE4o9=34Hw@eG zT*>Wd8fq;~*1LLFHZ5HNFme~?!In`*9>ev*brf5qB%H;IwnzqETohMv;mq-oV>Svb z7%NDRLzvv{t1E?48Sz-POmg~nwiM9O788m@NVDns1c>r|FzF*eKBR)&9XQEaym|Ac zAY?UE5#nPt5Rfxx`#W>ShMdTuQ6__c#DcqpvG-CCdfO}5%<(tfG7P_kT1z8f=ocR@ zkp&?oA$ls^ZbeeMrm8loCD;cj$@21399BU}_+VGG5T`}mm0L#SXrXXbtnkEjkhR-u zL~9mb zSqAH-W^2kkyYVrmMkxFQ># z<+`oJBpzZ!Rcqxm%gBs~?L|!1l&GqRjRNN;=FO|PVTkoPOXbpBdbyV2<6*cKTuZD? z|7OB#D%?01R-I_oJg4RJ^>l8nAM0%15g`8;Am=U}VM72&s39yOzyk{M@QX8Jhdkp$ z5)vCOu!e4p2=%xWXvk6P4>Wp1T115=(_7QsmL*NsOkZNf0FG&reQHBvmz8#QU6cu*$@YTEt1$3SX6~d}-#9Q(8mUBwowLbF-=JG>Hts zkxDHiims?O>Jy23p3H~@m!z7$<2XKGk4J!w3yYJ&SZJl$ZXB7 zItB*7(1$b~HL23y-xmKA%dr~`PnIQRe&G4OdXR7by!c=C&OWq_^N!5|@8x;!P4Y`Z22-N%^W5`tcb3j@AN`)+ z^K$3$G~O-)vVsNq;ie*^h0a#in?wkThC}}T@jpFpm>!21=y3Mw+L~3byo6p>j5h;b9@?IcJN1fdPaxfrXKw0BWOPH zYdQyKMxl+wGZib@p3oFtT2jSx7JcNp;~J9P_-2qDJ8(+yiBXyzDW=xrxJ$4)oSh~Y zZ7!-a{QwBfFaZ;Bd~mR58auP*XK);3e*WsrOa><^&I}%( zo|*Y#9w?cIrq3w8pYzt)TY~_~;2=Jd;k~n&A$%d{Zeb*tlaS*$3zy6Es*MIc->z|EhzxwI{MhO4@M`r8Rs~Gx44&i^G{)+%e z_Tt6y@$rlQ%4RZ|@$pxooE;y}jAJF6iYHRpM0|2QlT1!_B=+q)n8{?b$z(R09mVs7 zz*PaCBpK!@?mk{gC6ntFr7|E6Kwf@DQT83QX&;B*?t}OaXHFP*yBog?PpbiXOkfh*PYN`@4?Ao2eDk+{y#k(Lt#3u@M z(Q}0oa5~)A6=Xds{TO^gl@uV-(L@6TNtIDfYMOC#foG#3~ zeARxru7At=nBsDstJ2pMIZ3sB&NoXC5Y`8t#nfZd(k{+ujoo~Ba~*mpHc+Voa>3(4 zN4*S4As{XIBAE~0f1jqal5Uu~b`6somv3CVeEAxRQc+%66OP&q{E%P5XZ7{<;bw_y zX|sx@G$g})!^5~iWq3H9#&mc9^IjCB10YTZdIvbi9lgD9fA_Zc(xHurnzhNQ|*&_jQe{!%!fc3W9P>TKe66x5bW5uv= z%Zs5@0bw7c+>2EN5NQ2C0F6muyJ*+gq1M)Wt@rNz79sQdx#~BdfYI+a3`~3msM?@MPZ>tEKrx3*^c>Cpc5eJoqey5V-J9k{ z6Ev)3=tKB~Ci?bbDlHsEGI5cS2*yaKgFq*Z^&C4f<;v>n{Oeu2n(j6U?QGgf+6D>) z0(F5pQccY#B?-v#(tR-;(pUzh0Fa7`smiJI6_t?EB=JfdRG8w&>&D}8`Os-B#@bPiD`X7?i6)K0ufJ!*5D^3t(~!v~SDMm3z;QTD-VoN#)&;f&5CPg8+Q}In$AhT4 zxB#xokmJ1Vq(!T~&3j*Q} z0Rx0!8V1Evd=SexzdVWWQchBlX3NH_^gk7g&!MAe>M~x3MTpE@MGiEVew=|`aVJr1V+y=L{2mu~YA%wEO;R;Q766G<7sZ(yruzpUI9^`Y(&f& z{ze)!U2`a;q0>Tv74kdlPKAopLn8HuG;7Qo?3*sX%NpfpD7`uvLCD$m(SoT8jmu#C zd@1>w5;Rfxl90-v+O)*+i7U{UCf8X55Hl>$tde)Ufm-) z&djbe(Tyfp`On=|)MRtph1VV^*Yt(hqJVBz0i&t&`1ltnZ+%Cm2P0J0>7Poqrw+zS%favP_8dUN=Gp8qFgGVy~(U}en`;GNgoDR38ptw3c zn%66kWLt%Jpam&%)6-RnYn7NdjidvY@I>LT3nQf31>3&;4hZOS9pZ=EJFw1&F4z z0SR#v%Q3gtHtANiP3l$U3}6RFtjazcAT)$B66vG?l?fcx{G!Rxjw0jH*lV*!%a6h%Wi^2|tH6bTUiB;AIGWuBN@dsEO{O;XIp*#9>-AYeWsl<>5e zD-PE~dLK+jKn@U^4XnDFG9b?wATPl!2~riy$<=lF!z&zcT@xNS`x%hQW)$s z-J^Ij8-B?Besf6r?ZxOK-0q8u3!qAC&E3jN4*`&cIXHRFP!wZ9YH?xFRMq+OUI!o{ z21HTq{)TjNHcFo|(4EGHQ`gvEwPk#K85H-{xIE=369>ZCrkmzTa& z>hCwRyV!=L&$0ZS+1Z^%Ausdc_xsJv{ssm*Rx}T1l`#15B82!hfd+J$kPocjH~|K} zi|7T3=E7G~Sq*>vtI8_NHWCS~)oR6q{i>~6j)M^&ub}bELdn~r8?Yd8Cn%zq%Qu~p z;`D;w;;b?nXG)Ne7SX{XtL^gL&&0)9=&X;^<^O+jPSHbnkeDD`ho7qTABx_Es<{HI;gTLn4vbAT?2KO(eL4c9#c$ft8>@E_%2sf(G>1MRpO! zc7!EIHfa->UmY$^TMz$U%hf~Sq>HO(BYrGI46P`5U?TWno}IKQ#Dy1PK=$t4qM_1R z;wKUb)MU^iENEuFQ}mqA1Y?&C!UqKe(YTPibbg#7a`L$JEeP44RmjbocYxsdx7h8Y z70Qn)Dk|17`z9VsrdHQ9=+$Mw1Xu~M6V~d4WF`m~0viYiQBMQ-SzukXS~j%EEHZOA zzTYl4EpBWbZinCDcRNsixX3$F;QmF?Y||hP_gcw*TokrzNqit4nM40gp@%#JlG>Ki z>GNL+MUvQQq!vWrBWsG6`c{MxiH@UR768dlK;nsq!QlLSg&L0t2Qtd^l{I=i@>O4k zR)ZRggcYG+IZ6ZGv_dbmND9l=pJ02mCql@_95XkEBmK>6xCs|-`rvl!+`7GT=;(X* zRJ6#rL?)Q&>@k`-8U_jT0X;dw#=vyPiu5TYF(BEdLY}cSlJUCq7DYm0Lws&*L_ntY zu^?F+OvLb`07%{ff|E@ENO0a#X?Zw5Y5^=P7E4)!)!L8{?1YGf00h(!sn}yea|{z= zLV!ppgzgZq;ed-_zzSe>``x>y!Y%Qz3kD)khXpGY^mM{o((tjUX$e0H#>p}=f4oVY ztaWiNSby``A(w`VK1uKE>iF25C*PN+jZ&iX~;O;wY&)tC-J#ta7jsBGd0OGA@b0e+qsn;d}Qx0IVr~HM}-LeXaSHs1tiYJ z**MEODG;Ct;X)vRp*S!E1&7dPOLU1G*wANwAD=15P>7Pa02wryJwbdd);6P5Dr?s_ z5_EaQ_h?jJVy_WaO2%Fe24^LimQ5zpqzTQ5$rKcF{~Arkpb;8V&=|DM03me6Up?Kp z2MzG8@Q#LLYQK%`!Z+$-s)o!UqyR{s0^%faARbPN2NR+5M-mVK8Wf+*caNt6rM>UlYPOiCb5h9PRFhqp*A+|b~-wya<`X=8%we#ua1fyR>6Yg zAs`&mfkiSN5hj#H2gB@RHQt7VE(Zyn#6$)UhD&wtTGPWb0+y@ETd?|c>d-v{l1wir+kT{Mx47#0yZzZrHBI58fj9(%|a-|%( zc7k%C$#I>Cp%9+3p%8J9xS(L*U6P2&-^1P_8?MxB#+|ru=+xI#$Xl*`6DRA50Lb44 z$BjkNXc09M)K<)9tB9D7w#l}(Nh7*g>pt8x=KK84n}oT6{{3CH?vnZj;dki;K=KZd zYnQK8aRMG8R@>TojuRt~P>BI*o_} zkJ3>j00N$0<9P`MLmIm2w1FT1Af(f4>2$ic9ieD%?|p^cSJ69(d8lyx#N?!6CE&cxd4!o!F4kI<;%@y zm!T1{6De|Xz8#1TH~A4gNG9~M16 zN6ZIfjwNNX=GmKzgpa>Ik9lRu<`uI;gMjegdSxrYpS5pjkXM@DLu0cI1;IH^f8I1X{vHO$+i8 zB?aV98EM{y4DX*y`K|A(ORm06*M%ItS9kLPy`zBq$Mr$+FT1u2fb0Xv_Rh{u|M(dM zWNbUNnp|B?^*>~R53Vh>3QDGo=a7$Qt6eTopnDk!nOj*61U#Ou~qVO|Mmn%6tg(iTH1@PZ?C0BUDM@)vlX+jnqFo3=Iu~X*4BN07^e@0wheN2Ap za(RCi2th!?MK(Ov3IM?^DOyWqt$b*xhwe>bLIB8&vF(air8;!*kV>VJ0iCjP@32ZX ztQs!&mV3SBaCw`(s92j#ao{=tf}6{xpJe2ipQc&mr)hHQJJZuA#xa@C4_W%x4`QM? z@o0nxlCEBTHv#d`Gdw>ioDZ@eAl*=AMmZ+LnRZesgreJSg;6)Q1FT@*cm_-eTjX&~ zOu)EJ&2!*inLiE4lF5L~lUiN`|7suwJOCnrwlRl6qk9hY03xogqE=mRujYBO%Z2!O zu9!8w2F8~$cx|DpDZhzg*$6Tk8 zkJFwNUIgUF;b8=1v?75Uwj%y(qiVTgXpC%Sffy-bZW>&&+l)=d{(ch_h{u~ycL*P;CZ(0}hc4enJW{D0dl>>U8Nk2# zu7lm92?)`9qJV%b;7PVwSO`MQDKsDxUCCer0%At<67X~dCaVAt9U33_u`4;*sx$Oz z2Hto51|XR5d^$D<_zZaA7k>?eG(YCSpxldgk^ktl=h+nTz#ta+3jh)XK-3A`z~%R! zu?0uxgTHl?Ju5&60b~Xfq7Du!XwK9@C?t0r+)A)ewLrzKCf7?hafxyB%nOpo`qYR4 zczB|Ff~np|GzNTwCqA6|BYtLk;ewd>Cp(9AP8uL2=bZ#3P<%{Zwf-493bui+GzxMHj1XZ3`8< zJ75>KV^*9%2OI1KDXj-S9Crl7E)7C2YiXy-WD0_XmI{c3G7W~hn+n4wfZAvX7WEoKgsZ^Xv0IcetFLG41f9c==%~tfF*5rF^#?mRR;8Sr8Bj zNad$001$h3GH8qxF@IMv80Osmp&%@=EJ3T|NFaRfC#nT^oTU3QF*TV55kRK?_?J6Pf5y$LuUx(|a%JT5mCI;OPZKq| zr|Ay)^C`|3%bEp=@#x-|K&?Vf# z708Fht!eA-wDKK0PjZo`3NBG_!uINH1#$#ydT(@hCRiUi;Cr(XKW&{JwukRH4Sc*k zf3>FyF4+m)B|S)gV8I&Xoa5Z?UYz@j^hPtC>4)|6mM$C?EY&a%W~idI9X| zM+?#mR<=Y%a~=wg{^6TlQ@B=f`pYk=e(<eBeiQ(dUD12E{FL7g=ZJ=@ z-2T1$4;9yNqkJG6#A9>30zgoLSG*u6v!((8VjC-aV70khc4QunX7sLxBi1;$anIDq z2&j;~XY=y%YA)5BJbAY0Fp|ChM92O6|AzWlJ8$2PGs4$Qnp&ru^#%qcO!au*1Y{K; zsMa-JB85wFRU6Hkl{cjZ1qF>pIIT1S4#sTCvem#N`-Jht31c?3hKC~+_Q=h>2yd2D zYK*z~U6mJ&m6}Sp%sx&HgF2pV%*7Mf@Pw#8!8hlkb5JOh2H{YE?Cizb3;hNt_t8j& z=(z|GUwY=QT?YzcZGor`sH@SS8((j0JmSY$T=!Q_tHPt>Vgqy@zmGH?U2SkgjP+=6 zoifxna3nqO%gxX*jZb=gu=A*UQVVAG= zd8aR6xrPLe?HABUP61qjk$(bQlr21IDX1Ad&bNk7rKKhzW;EIucmbdsLwYut^p zy8Qm?Tzb;fdgG=pUi|j&|66{)s%vk?h6N=2fAH~%+91vjIY?JmqscVb1*?RvuD*`G zuD-$f$q*8gDKy#F*EcvBnw&Isz*VTDqr)ULQ6dzgGg3LD1d+mngqPecC~sSh@>>%(gk7LA#25D{EMzv4zH_;v9 zR+XirI^6q`6@9T*HRnB;k#R77;uMvzwQqw0vIqux7|is|5o~J#f!nRFuC5Ah{mH?u zu0aqu%p)vj*fe86Y6_dcDbPk;p67kMX6-AadfW%{eTyIY3IK z-S1u?IaKoEg^kD4>XkemyvpP8*i4e-y+X3kjgB^w9BRJ=YN)CzufL}r_!8;8DCDR^ zPB0}&mQl;B7$6#Mkx(lFVJE|eM8uO9Pf^u`>&zaZYt`dcU33GyX)0~LX(b-9nWI$U z)bllc6*J_N z%ufn=q0me)7!C&lVarpYkjED@(k$Y%v@+KiN%B3a9F@v|QaC1B6SOjgK=ovOfFq`1oUx1B(gJ{#2o3o;Dn=5E!C>X&mOGZ${U!T}wF!%1R^nc@_4l9>>gvj{ zVwXy#+Rk(L)7irjt0c~$fStjVvjKNbp>iFgt+y~B5=mv{%61JBTr&mx^Y}&8e`)F- zp9#M)0SO3b*#u-AKw2C(sxGwFlTzhmV&d!9uM^=9kroI-Aer-RlqV6KcwDriP-hyqvnZx^Jv!ST#jC^X9#jwgg^oREP_bUi?^S@8U@5g z0dk}CLD|??LTBfgC&BZe?29s+y9d{q7*Q4&9FQN4u4|9M5_8H$ymd4nbe}khB+@I6 zE=iZ*>cZzMr{&O^;~?FWH=;nIW7+m?@TLu$fUE;Z+t5(nrPg|>QX85_7RY=eY$2^^ z_Ty3j*a!zLx}etMSulWM5KIAELy_!txx9Q{cYk$tb#3)mE)_#9P%G%olEyMD3@`i$ z@&?4kVVDIvxZ!mQf)Er6^m>k3O$-Puih%*5P%ZYVMn}yImO?NvFp!mEFqjFIi$#B) zaSZy2tH|#QHVB8(ASX4N5}z|BV28VX?w)MAY}be%m=7cUK%{6^Q4&W;6NN=ogV5ST z5&`7ksVN;z>D}z>OdAO$;?DjPCk)}tPq03 zFpOTsDg*;!bAS!P<@TS6jt$v^kB%ZP#Yb+mco*rBYzhw)GvP)WM&Q*Jwa~hJ4|g_g zlEe)2_^u|H5~M*^H03?G%4vo9h%dg~1mxETNQhj7jSThmNtwxPkxcfKt=B6jJ3@;~ zmSE5l3zM8oQdJT{F0# zWwZ(-EK;0#JBgfW2M*n0k%eNq$sAa|G+a(rAlC9zV-HhO-_hlZSpxCAs_QIw@m#a4 z(JV)XoeqPM=1jIYq~c*)4za!G`Fu{YY;QkpKNQc8q_a-`5(xL={k%WV^LdVAhSbL* z<)1t3i9LqDORIO*fhF<77LF6IedUrF}A8kH2P4EM8e^GI3LL;$D?Mo zh}%Ij`FyTuj+@nFu9U-NEin-rA0K%;efl(RL-L#-3r(50%&U;AzEsmqJ;O_q2o41F zr(hT{g?x_?QZ$UbM$hNrQPTB{Dyd|V7!L75GWQr8e+e;aJXUxEdwIJ^C4C0?=$H%! z>qAh2KGMg6-H-MCyJTNGDc%Qg=tDi*LK&%-7JDcjbrFFSYd5QEe~XSXd24s@&-2&! z(D8b+e4MHCak8nDegw$jQxN2%hJc)nW4Ajtyel#SQiuzJJChgGj0tB+Rm^FnOeUu! z0g&`i-w*`XcY17Od`c5(=|Yi|nm%RZ5^xRO} zGT;1q0(k-tp9mXfF#*{c{(>TEFC;K`{}2>x9U{T!~S@_OUHqciiDA- z`3>DCkLF?>MnGu2Tt6Gq(!l@Oh498HQou=kO~Dj$xc2EgTUTkzwPELM=OS?t+U0UQ{A4yvoG|j^|ZHBl~xm zxZr)(P>}RYM;QRQg2n=qtF|6YsQi9QL1uxA>=Ly_*{%Z-2o49xrojNYDf)2g?t34; zfAQzv0h7LK%J+^}B%C}y-n5_ac=OuT!8t(PM;_$RD#&QHngnTZ37L$LDdyt>LL%gH zY>wgB$_!fVq^>8E$wJI6gxvrLQbK}ZSzthFgvxP4V?*$Yj|~m=c^nQ0Tf=rxV`dha5)^PKSD)b9y`~{+7c7!94*3LOcip^1cNK86X6J;KmdG?iisZ zUlymQ%-+6TZ-Jzd!fNK^CC+Z$!U_Ga%vXUJI!V%>_cXDwXMh1)g_$n5u27R@>UDWePRM;Vf;v zc=2L;dmD~5;Nsm%WsC^O>hvn70v!zQCj?PJm;jJ|aOwYi!XO|WMjrpkI>r4=+@6B!yW=iskEs@k}(;sRRQ}sCemp+Qhd47(qgy6e^Pf9 z+=yEwNT~2+1y*2?jzoe#!Sf=dUI@tG;Ju!nzauZXm-d>X)$CifYBk4kn?T3L#@gE2 z{JfT9hMray`*=y^Pb^GNv#LjxH2S9{hEX`~8P-AiaYrFh5DJK|tqzE1(U-T~|8L0`VtgB;&`OY~FCGkKe5j#5016yy*B zVyB^p^oYm7Xy_J1H3Fub$%UU*R#qw#f+EKXEgNe)BwAXEU{n+yYl8>`8xG4ko}6N> zP;|S!(~DzI2bY(ZQ%`u&9m#KOY^<-pw2j(Ei-O?RI%zLrXX_(ga0!*c)z#I7zI1wF zaXJl_MMS@^XmDhiIQtA!tV@?pBOv8EAXGt8{-ve19)Epx7Y@U17wUAFQ_-e-<{%hT zrmmZW5RA|M(n}G!+yq8@V&(H*;9feq8_8AoS9q$)(Jk2iyE+H~B$*6z zxl##7F({%J97)FgbY%uR)6?Eaq}Z~(-GX6nu@}AJu)>R_d0cN&S#TveURpy{m=`5c zhzkHnr82O*Jn*+xNeE}==ht>x?6x_Z4FK^1AXsrH=~%|=t$e=n@fT?}{zc{UX}1t( zL@Y%zj8<|nn&5f^^`i?F#Qkx(OaUQvKu{3>ECABh7<3)*`L0~RPGr;E4@h);YTPV} zIem&K2r%-RHP!d#jm!Ju1|7~z=k)&OOrs~USvhv^D0Q+4jw3)0Cm?sq<>Z##UX8_E zT&cE+DOO1nz=H_hO8L&6I{--7>khxPTQYmhklDB(Cg#^SHEmu~*f_&7ytMJ6WqV_L zV_pQ?j)1JJ3=Rw|wDNGRLprt7(rufYGcqj0h!UB5gl;wx^d&`uc%h+-Xmw%j_*=ou|bCR9szO)mw7=vssM=WW;Sb^we`)-O-+b| zU7TwI+eIo9UKU`f+VINz(lCE*qDfaItc_!T2{GxCG*3e!CVg>idJtk@A;CLOms)mq z?Aoe_NHqFwOF^#E_!&GPa9;IQ`XF)h zqq&0h^|p zLpRN123&q-3;@x{PAV-YNi6H&6bU=AGz~j;IY-~(;_6?QF+f3_=W|t?ZSG5h0^)I~ z3COW9%K{l;93EaIomtoj%mW{)RKfv`8kP<{P7W2MtKVuhDH8>;#>8hI+`FE-K1mcL zKw3jSbk3OJ7P3W^Z{@nE16Gwm? z!ew4C2ctG)e0)R>NAh{EH=obMj43^z5!^D)TFkkV#)zR83e^I6#gb>`3^p$2uzns7 z$7DKblnm=t!ZPk-`WJiW``grc#qs~4k*Mr$Y7!LP5)*}@g+*m`8Wy(NQ5WnGuSgp- zw6)U^tzI2WaYD7k*U6ABD?}x?`ldua*S{`?H&H&EbDrls->=Jc528cUP^qhq5*&D@J;B%WW*Yh( z(m>9!Ld7+S6I?ji3y8>NGIM`^>=B1o8lXuh!FMRJD1)4qG6**5;lZv^aMQOCWS|+(^b~-l{#I$#be6EMBFx{2hbC5n1pu1Zs#T^1&=2xvSZ`886FK} zlK3lbwf>F95d-*T0~TO#8;i#+VhEViqex>i8I3X-Qu?={fv6Cp8Amn^UoF5beWJPG zkj0{W7pHl1w>iupHy@lXtYS$PZFxHdHk^2k0D&auF)5hiGuhhGdlkKySd}F;>1VH9 znIp<;yR4jD6vbT(5H`LJ^$-FwV8$7C9MJ6##RKZeAt;q- z8*wNU&m?gNv40YaCTjw+2!qLN)(nLNsJhG=4c1rCvuiAH3mrQXukP1`;&EwMaf|`- zhVw+h(@<69z|%-27G@9>oPaJoGpcwFw?H5i)PvwP3UruoMayJ*69Jh$K8q??D%D?A zD8x%@yrfuNc>B0S$7J0|)@vJVrGHTdWb-xYm_i@~A!@0t20H5CskaE7?J){SAocoA z%Rs#hP=T;=`c7ehRIagO;ds3uwA-=V67lrmw-!M^Icc3lDQjrCc_G@4AGXS@(8_ZI z(P+Y~F|&rHKV*qUV?+bZGHUd2JH#edaI#U1M@LAUH+Q?9_uX_{dGKo|%OE7g{v=SG z9R;T)Ks=s|M?tMQW(yz%@`@L(fY)PU%e*_8mD_utzW(8d8!2L8d|D8WD-pu_dc6wJ zGaz1F2IPAH(&KQb)oOJ1>+I}gMt|^g@cAk#^m;w5?CJG&)pb5p`2lvI2-ESr4oG6t zi#ndGN8=6j-w<(-k>l8i7QEY~iA7G{0DN#(EB;;h0AUy5BRoXvIj~?ePjWoZkw`p^ zFHSbJ4=730B-cTJI2>2@&xga|ba-4EYcC3%x^mE_IWA;*6pDb5NG7m!R4CZ?Ii(b~ zm%jHKBIGbF^PYWbOs~C?U*u)Wy!nigSE|mdS(l8QlmXdvfZRb7=mm-yDHffJ^pcOG zOha+s;{0X!1-*Rg$i5>_W&v?B&=8J93=t`6Ya@6?B1&Z~eC}gG=c`(7w-jzsG^nFx ztWVw|Z`rz4)*_R4baeE|aZFL(N0W^5u?SUIxt98RpW5NLe!VTYx;ip4;;vXSvT!L~ zN~O_YG#Y}PQ|<{|$)$xXkHVBeYoJ6lV5$N@0&!e`3t*{*kE$CV?8Xd2c2b8gNpb!X zDp}{{tIwY~v;F<=9Qhu;49KPffl+|6C@cT zS$IlDwvDAmw#8QG)G^r7=slRWrEKtk3mEaM18S)^FKl=eb>?JH_<6Cmdl`^T2}tuh@9bGXcUz}(cGfvFI5^`( z8jy!ihT%76xc3B!y8{|{1{}=}3O>(GC62a@MPL-0IOmN93&yo<>DFeGzEsh<^DZ** z%tuZVt|n<-TP?@w9X&nQKj`!Y0gzMK@vI>`0#8F$smvv^U^5c9 zI^iWKGI5h9kzC7AV`8eRs%mCig@2I5s^5Jb&yAEw^M1U66z|tXD%LNrcbxiVxy0Ih zfT#sQ&^}loliNpgcxGzq;>_?c*><{pKA(H#NN*GRKZjSB{QltTsW1}K*cgWYz5Pqs zFaZI%0m~diIL)@TZRv;-iY)Z8g~ZThOJV7CH`T>F)w;S;sR(5UcAKMQQ2+uWm6HPh zB&Fo|3IwD_UEw!i4jCUY7z{z9QfYuE)L6mblBFWpmdWFR3%%Yr%_auo`OU$2+!T*y zpyEP6pe=dhctQ7PeMkZhUzP|{zxwJ%61^qXY|m_yP69S-Wk5Cpgevuk>qyAI)CstY zCDo2W?3sQ=Cm#L!3Ua3<*_lyFf*|Oz@7m{T_o(4!#d!yOuoVmG%fFyvI z(@`!+jZ_oX`8C?ezlpl z|9JN)AVig|=41_W8CM;=kHu8PFVeAd-rsjD_b~U+CD-5pJmR_>t$oT=YFsUroKZ4(QGLLvN0e+0*TlGfGk|0{1HnE zH-6z99^NCcjgXl7!c1@P;v8Aviejv%xwp0H=m1$ni=xFb2))QkjCK{__ToIc+=~5H zD~Fm57sEDNQ;?I%Wio4nSg{W+*G5E|C7HDPjK^wnIb*}n!R2k+wrMI?(?CR6XBX|9 z-EP&vE%{3kAS{D)`ujR|wYX}P$_OCRf|TImn2R5SiyjBo?Sqmf8M@jOBs-jHwqI8Azt;f zJ5J~EW^Do~NL=09j6Uf%EhGaZ-1xZ@3a&$z7;{bk%iB{585in2)M`_;t`Z=K&qq*lrAMp> zmk%y4ZyO3-40q*h6DTU1bomX+A^_yH<~^TA8JFElG?Wxnpzv1oOA6W01(subfHP5Y8rHh zaBwRmT$yQAsah8+>{wyhlQ#z;p{N#v=7W$x4qDp|wA#9C^DERbT1EGsCR-P+^QMfv ze@crcJZ=6l7qlA#KJq5<>tX}Gc3&M|C$zbRwvLxx`s%9}U;OcpPA)&LIeGFVJZqL8 zKYmeU;jQLp#y;vS@%(eW$k%oKb1XNguE(^6blTNTdRvJ)a- zlrzYt1LVyA*gM;psM0HrH{DH})+SA*Y0~sVLpNy!)Fo)ZQ8E;(R?vkEY7_#~9jHz) zKu17jr=v3vooNY~zyPU>BDfM3beIOvc}Iqrj1@FeLWnPM66~6OX|nYLvHj3Z&pFTY z+?N6AYHh32InSMY?_6e(-Q3?j=R7a}v#_wRaXL8i5g>Bwk!zu%V)OLKkb?+${Ii^j zg@!>mDw5IBQJrPpk~W&A z*QeQ+=I58}znucJU%GU%H~Zx6=;UO`0}q9&>k1FT@(xveb(DJ$mG=;-xh#dHUR8J{ z=|K{4B>fh!0TCAU^p3!pL)Z{rcL*U|2mElv(a1*!ff#(7$BPCw4vhqZBUlp}2Md9p z>8j}w2UF$Q)946R z94x#}Y+R@9W2}(g_%UoqNFFw6^jwSxrQQ0I{zF zC^#T`Ivv&HQh5mAAj`pu3wnE6Z*ixm#846nX#^l@x6yi3EV(63lQ{Pg*R9Lb4~nnY zs@tRoNjN}qb91qXz(NItS_`fP*JhW?wUO5<6UED@u32zeF=Go|3zmKA0|%ah8pzpOuHxS%?LIi~}J3HN|&u{*`GWJkyb4NC~G-bYajHbli;?qEnWA9F0zu{i$Tn|uZQQl% z@vg@oJpLd*|4}|rR`m!=25P1?K@OUj9EqH{hkQd0x5MFsCRH~O{>tYqzFf?b^vIEL zhgNGe&dq6!CQ~{dwAi0zG_?UBnCt5~Ae4{Tm!5wCfB+&>2uQD8uiIxZ*MvMWAgwAo zTDcEFK3bp3{^RF-a8TW~t59s9?X3mm^Cu_1_k%w_`EC-B7Xb1aEJLvfe5D@?D=(Lk zW3=s5vL^8cE-hz)6Sp%pHFFXRNk=0S6GqdR(HOxQim*ZUp~VR&5Mr6_qk8HN8@0^O zOCE%USZP@H5MBU?xume)<9XPxVHI?ot-RYxMnq~)m3_N$a*FZp1MxU_<&SSEAiRv{ zlO!PjIY3?kD1MapvNy{pSNN`-<%CvhXT3KvwjnZR(rP2xaYH!LVKRr)!F?EwTJRto zkTgg^EJ%magXme&DgY#<!X=V@H>!B>E6RpcFYa&+|u%l`c9 zk#tt{ZZQeSazHXxeek~tCjP*TjLG82nQ&w*J>4_|?!%~^OE+oLwX~TGW*tUVdh{Sm z^Ljj&Jcyq20ZrH3?+JN4p8lZlAR?sVskuTJ>#3Z3$YOCy=TWB!u-LTtR%Dsj21Vsocs_d0MejYk6SrjhOFmm>T`zCotjajYqvRd76f>)|zl`*_hT{%#x;o@ooq(Mkax!I!b^K`=al9qZatsS?6 z=MRFlcXbVSb@g?1;jXW5_`-$2)eFOegMq%&-e~l6Utlm=Qxo-~-Mo3H!)S~&pP5)R zn1A=)dp}vcAI1s2+4jY|KfXP7|1XO=``_n*1B*_tvj8hxAH{-R#6or6EGIrWVQK64 zT)QShtXpbzUMC|1c3|D^b0Vfvb?LGW-E+${Nt4o}i3y0Cn{6fYi=7|$e(~NfUHcT* zb9dW(H*7Y(pt}W(RM%RFDI}{JTQ%-0D`VA_m9WLQd||b;!$URO(`Uh~_+j|IMx)uT z*}Hdd%kdkfzbGy3JN=uB_b$%e9FC%P#N3>B?oSsldIz5!IQjicy}eAhacYWXAMb@C%A^;#?Y)c`D);^hm~Wfi$3Ac+SE-3)Fg-qYP~ zCN0P*C=;!$sj11|)YOBGZ<5u@hgzY$CZD6x_wd_(zkk-x%tty23__pJZG)yTrxTr) z8~-q%3;#g8Y59#TltP8IX( zy_%`>3agamP0kOvmdWuh*W!({q-aCp0m2dv7mJD5T~aA&)iRND3OIx=CyI31il8Am zWlh-7Y9&(%9~|C&SRsjUSiYcAXe*#&!EWhyaMWfAH$OJ89`^EK^ZA7zvlSI}!^X8k zZ8pZa8~@kGFxf7g}l(kVFJTwj5}5tf0i3 zzY~c&Hw8tEBl*VTwKE( zHj*XOepqC9!_7Spy~vHl3MIXtzf!G(D?;|?55mx;(1E;1QuZey0f{MM8w_k>Ey_$? zqk(K(vwhpKW9?uA1MRAGTS1K?CszSP4Dp~|cq8^m=RWCZH(SosZtImD(o13` zw0s0l1>9GG(-J|Tf3}C!PN$|a-#-*Oyov!4d4-fT$wcbLN&=E_fKdL?&6=%SnV$PG zj3I*z#2;rA-iSPcr4Z~XOqn?*50sx{97D-BF~hkTSg|69RDr-MV!Jq|WT?~pH%fk+H?&Xuj3n3DUvRJMGKB|dDMrPu81Hs36yt?BBn?bbo2-UbL8Id)Gs?B(Id8Q*the^2%kXezo?S-%bLOIDmZX zoi+ddto8T_him^kvmG;DdM+fb0DHw>@TEVw=H0KqVSv1D`#%EYE8lqcJ8Qo7&vvdv z$x$5!8X3xVVKDgrKlWLN4dftMl2j8350O5Y>^SAwNc8VPzt`)&x}?C_W^JJsSI|2dM*{d64(r)v+ZI zErKmk+~z@YUeJTgr78N4nR?)}4!SAJQthSCOrf|!kW&rP1_JYSf~35NKgf4YK-?PO z)1Fk25M|#}q4 z#s*j0?43~T%B)5P4Lk*yyOz}toDsy~KuhI=E0I=czDJ?>j3931L(vqtN6JTK3pWRe zGfQ5)^wfUZ97>e})F+Z$Slq;VL{4tjHk&AL{K^u!zZGR+?pm&LSo4G+u`m!H*HfJ{ z%X6n`EX5ZHV)HoIV#o_`zAN-a-3DKnGWn*K{Y17nm&?Q!Ja55RvE9-8HDVtqre7|e zWpo)kL6Q5lP2c!2;jG1yM`s2eJNXegaNBYcuAC6WBNYq3`WBTjSGHFaipvC9a$?C5 zDRo7U?VSb@Ta@G}Ri6z93QdX{1gx=uuhlbU2^gA|>I#v1MJx6M`(>7h(aW znqgb3*EE*mO9TN7P|&D&8&0SO!U;iU-q-UfLCOy9eKZ`3k$gFteNE-kt7ilWHBNd$ z5Q*;S{ab>pJ2$6LT+d=bkI@b)WKVd1-c#meb82RtT7sK-B^62!QKIWH{S zNgF;TvLnd&QiJrb2tw$#yul#zPpUx_9}}c!Yl2;bGNRQ!)gboHTu%rh9;&tw zR~n=#?K&fsS{@K2QbtS$T@LzQp}0;E%ZA51NnSEqUm}Q?u*%+={leB9YEBH(vTl4t zkXfiyXWYkhdxBttR!O%)nV=uC;wl1_tX;=8I+cqnrae&XzEUy48dohWVgv&w@P(SU zVmA*2&QSF|nn*?X$ky!0P@_k=4NF zLb6X-#Swx5IzolwBDiF29Up;3>s--pC%;ftJ&bv~VMOw&;G4$Y-Aqzz-&U&TyCOW* z{CH;{S|Y%(KG@aorQSYpk>%Ku(^#cRr!&_XI8Cq~Q=%=js^%##*`~4G$UT>IE{E1M|@3Xb=W@ZYk zCb1NMA{4y#?ZhZl^g9I=zaO#Pi~dglYc;}BC=?2XLZMJ76pEjN{{T>*&qEsdfiVC8 N002ovPDHLkV1hN*1%Utn diff --git a/docs/Stack/Min-Stack.md b/docs/Stack/Min-Stack.md deleted file mode 100644 index 7c367a19d..000000000 --- a/docs/Stack/Min-Stack.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: min-stack -title: Min Stack -sidebar_label: Min Stack -description: "A MinStack is a data structure that supports standard stack operations while efficiently retrieving the minimum element in constant time." -tags: [dsa, algorithms, stack] ---- - -### Definition: -A MinStack is a specialized stack data structure that supports standard stack operations (push, pop, top) while also providing the ability to retrieve the minimum element in constant time O(1). It achieves this by maintaining an additional mechanism that tracks the minimum value, ensuring efficient access to both the stack's top element and the minimum element at any point. - -### Problem Statement: -Design a Data Structure MinStack that supports all the stack operations like push(), pop(), isEmpty(), isFull() and an additional operation getmin() which should return minimum element from the MinStack. All these operations of MinStack must have a time complexity of O(1) - -### Algorithm Steps: - - 1. Use a dynamic stack to hold elements, allowing it to grow as needed. - 2. Track the minimum element in constant time by adjusting how elements are stored when a new minimum is encountered. - 3. When adding a new element, check if it is less than the current minimum; if so, store a modified value in the stack to represent the new minimum. - 4. When removing an element, determine if it is the current minimum; if so, recalculate the minimum based on the modified values stored in the stack. - -### Steps Involved: -**1. MinStack Structure:** - - Variables: - - `stack mainStack`: Holds stack elements. - - `int minElement`: Tracks the minimum value. - -**2. Functions:** - - - `isEmpty():` Checks if the stack is empty. - - `isFull():` Always returns false. - - `getmin():` Prints the minimum element. - - `peek():` Shows the top element or the minimum if the top is less. - - `pop():` Removes the top element and updates minElement. - - `push(int val):` Adds an element, updating minElement if necessary. - -**3. Main Function:** - - - Demonstrates the stack by pushing values, printing the minimum, popping elements, and checking the top. - -### Time Complexity: -- The time complexity of the `MinStack` implementation is as follows: `push()`, `pop()`, and `getmin()` operations all run in `O(1)` time, as they perform a constant number of operations regardless of the stack size. The `peek()` operation also executes in `O(1)` time since it only accesses the top element of the stack. The `isEmpty()` and `isFull()` functions similarly operate in `O(1)` time by checking the state of the stack. Overall, all operations in this stack implementation are efficient, with a consistent time complexity of `O(1)` for each operation. - -### Space Complexity: -- The space complexity of the MinStack implementation is `O(n)`, where `n` is the number of elements stored in the stack. This is due to the need to store each element in the underlying stack data structure, while only a few additional variables (like minElement) are used, which do not contribute significantly to the space usage. - -### Sample Input: - push(9) - push(15) - getmin() - push(1) - getmin() - pop() - getmin() - push(4) - getmin() - pop() - peek() - -### Sample Output: - Element Pushed: 9 - Element Pushed: 15 - Minimum Element in the stack is: 9 - Element Pushed: 1 - Minimum Element in the stack is: 1 - Element popped: 1 - Minimum Element in the stack is: 9 - Element Pushed: 4 - Minimum Element in the stack is: 4 - Element popped: 4 - Top Most Element is: 15 - -### Explanation of Sample: - -- Elements 9, 15, and 1 are pushed, updating the stack and the minimum value accordingly. -- After pushing, the minimum values (9 and then 1) are printed. -- The top element (1) is popped, and the new minimum (9) is displayed; then 4 is pushed and becomes the new minimum. -- Finally, the top element (15) is displayed after popping 4. - -### C++ Implementation: - -```cpp - -#include -using namespace std; - -struct MinStack { - stack mainStack; - int minElement; - - // Check if the stack is empty - bool isEmpty() { - return mainStack.empty(); - } - - // Check if the stack is full (always false for dynamic stack) - bool isFull() { - // Since std::stack can grow dynamically, we'll return false - return false; - } - - void getmin() { - if (isEmpty()) - cout << "Stack is empty\n"; - else - cout << "Minimum Element in the stack is: " << minElement << "\n"; - } - - void peek() { - if (isEmpty()) { - cout << "Stack is empty "; - return; - } - - int topElement = mainStack.top(); // Top element. - cout << "Top Most Element is: "; - - // If topElement < minElement, minElement stores - // the actual top element value. - (topElement < minElement) ? cout << minElement : cout << topElement; - } - - // Remove the top element from MinStack - void pop() { - if (isEmpty()) { - cout << "Stack is empty\n"; - return; - } - - cout << "Element popped: "; - int topElement = mainStack.top(); - mainStack.pop(); - - // Minimum will change if the minimum element - // is being removed. - if (topElement < minElement) { - cout << minElement << "\n"; - minElement = 2 * minElement - topElement; - } else { - cout << topElement << "\n"; - } - } - - // Inserts an element into MinStack - void push(int val) { - // Insert new number into the stack - if (isEmpty()) { - minElement = val; - mainStack.push(val); - cout << "Element Pushed: " << val << "\n"; - return; - } - - // If new number is less than minElement - else if (val < minElement) { - mainStack.push(2 * val - minElement); - minElement = val; - } else { - mainStack.push(val); - } - - cout << "Element Pushed: " << val << "\n"; - } -}; - -int main() { - MinStack s; - - // Function calls - s.push(9); - s.push(15); - s.getmin(); - s.push(1); - s.getmin(); - s.pop(); - s.getmin(); - s.push(4); - s.getmin(); - s.pop(); - s.peek(); - - return 0; -} - - -``` diff --git a/docs/Stack/MonotonicStack.md b/docs/Stack/MonotonicStack.md deleted file mode 100644 index 140a2efe1..000000000 --- a/docs/Stack/MonotonicStack.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: monotonic-stack -title: Monotonic Stack -sidebar_label: Monotonic Stack -sidebar_position: 4 -description: 'Monotonic Stack is a data structure technique used to maintain elements in a particular order, typically increasing or decreasing, and is commonly used for solving problems involving range queries, such as finding the next greater element.' -tags: [dsa, algorithms, stack, monotonic-stack] ---- - -### Introduction - -A **Monotonic Stack** is a special type of stack that maintains its elements in a sorted order, either strictly increasing or strictly decreasing. It is a powerful tool used in many problems where you need to find the next or previous greater or smaller elements efficiently. - -Monotonic stacks are primarily used in problems related to range queries, like finding the next greater or smaller elements in a sequence, solving problems that involve temperatures, stock prices, or histogram areas. - -### How the Stack Works - -A monotonic stack operates under two variations: -1. **Monotonically Increasing Stack**: The stack maintains elements in increasing order, where the top of the stack has the smallest value. -2. **Monotonically Decreasing Stack**: The stack maintains elements in decreasing order, where the top of the stack has the largest value. - -The fundamental principle is to push elements onto the stack while ensuring the monotonic property is not violated. If the property is violated by a new element, elements are popped from the stack until the property is restored. This approach helps in reducing the time complexity of certain range query problems. - -### Algorithm - -To construct a monotonic stack: -1. Initialize an empty stack. -2. Iterate through each element in the input. -3. For each element, check if it violates the monotonic property of the stack. - - If it does, keep popping elements from the stack until the property is restored. - - Push the current element onto the stack. -4. Repeat this process until all elements have been processed. - -### Applications - -- **Next Greater Element**: Finding the next greater element for each element in an array can be efficiently solved using a monotonic stack. -- **Histogram Problems**: Finding the largest rectangle in a histogram or largest area under a histogram can be solved using a decreasing monotonic stack. -- **Stock Span Problem**: Calculating the stock span for a series of days is another application of the monotonic stack. -- **Temperature Problem**: Finding the number of days until a warmer temperature can be solved using a monotonic stack. - -### Pseudocode - -```text -Function monotonicStack(arr): - Initialize empty stack - For each element in arr: - While stack is not empty and element violates monotonic property: - Pop element from stack - Push current element to stack - Return stack -``` - -### Implementation in C++ - -```cpp -#include -#include -#include - -using namespace std; - -// Function to find the next greater element using a monotonic stack -vector nextGreaterElement(vector& nums) { - vector result(nums.size(), -1); // Initialize result with -1 - stack st; // Monotonic stack - - for (int i = 0; i < nums.size(); i++) { - // While stack is not empty and current element is greater than the stack's top - while (!st.empty() && nums[i] > nums[st.top()]) { - result[st.top()] = nums[i]; // Set the next greater element - st.pop(); // Pop the top - } - st.push(i); // Push the current index onto the stack - } - - return result; -} - -int main() { - vector nums = {2, 1, 2, 4, 3}; - vector result = nextGreaterElement(nums); - - // Output the result - for (int num : result) { - cout << num << " "; - } - cout << endl; - - return 0; -} -``` - -### Time Complexity -- Time Complexity: $O(n)$ -Each element is pushed and popped from the stack at most once, making the overall time complexity linear. -- Space Complexity: $O(n)$ -The stack requires space proportional to the number of elements in the input array. \ No newline at end of file diff --git a/docs/Stack/Next Greater Element (NGE).md b/docs/Stack/Next Greater Element (NGE).md deleted file mode 100644 index 668de6946..000000000 --- a/docs/Stack/Next Greater Element (NGE).md +++ /dev/null @@ -1,90 +0,0 @@ ---- -id: next-greater-element -title: Next Greater Element Algorithm -sidebar_label: Next Greater Element -sidebar_position: 2 -description: Documentation for the Next Greater Element algorithm using a stack-based approach in C++ -tags: [algorithm, stack, C++] ---- - -# Next Greater Element (NGE) Algorithm - -This documentation explains how to find the Next Greater Element (NGE) for each element in an array using a stack-based approach in C++. - -## Algorithm Overview -The Next Greater Element algorithm finds the next greater element for each element in an array. For an element, the NGE is the first greater element on its right in the array. - -### Key Points -- Uses a stack to keep track of elements for which the NGE is not yet found. -- Iterates over the array elements and prints NGE pairs. -- For elements without an NGE, outputs `-1`. - -## Code Implementation -Here is the C++ code for the NGE algorithm: - -```cpp -#include -using namespace std; - -void printNGE(int arr[], int n) { - stack s; - s.push(arr[0]); - - for (int i = 1; i < n; i++) { - while (!s.empty() && s.top() < arr[i]) { - cout << s.top() << " --> " << arr[i] << endl; - s.pop(); - } - s.push(arr[i]); - } - - while (!s.empty()) { - cout << s.top() << " --> " << -1 << endl; - s.pop(); - } -} - -int main() { - int arr[] = { 11, 13, 21, 3 }; - int n = sizeof(arr) / sizeof(arr[0]); - printNGE(arr, n); - return 0; -} -``` - -## Explanation -- **Stack**: Used to store elements without their NGE identified. -- **Logic**: - - For each element, check if it is the NGE for elements in the stack. - - If it is, pop the stack and print the pair. - - Otherwise, push the element to the stack. -- **Final Elements**: After iterating, elements left in the stack have no NGE, so they are paired with `-1`. - -## Output -For the input `{11, 13, 21, 3}`, the output will be: - -``` -11 --> 13 -13 --> 21 -21 --> -1 -3 --> -1 -``` - -## Complexity -- **Time Complexity**: O(n), where n is the number of elements in the array. -- **Space Complexity**: O(n) for the stack. - -## Diagrams and Visuals with Mermaid -To visualize the process, consider the following stack transitions: - -```mermaid -graph TD; - Start --> Push[Push 11]; - Push --> Compare[Compare with 13]; - Compare --> Pop[Pop 11 -> 13]; - Pop --> Push2[Push 13]; - Push2 --> Compare2[Compare with 21]; - Compare2 --> Pop2[Pop 13 -> 21]; - Pop2 --> End[Push remaining and end] -``` - diff --git a/docs/Stack/Problem-Practice.md b/docs/Stack/Problem-Practice.md deleted file mode 100644 index edf6dff9c..000000000 --- a/docs/Stack/Problem-Practice.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -id: Practice-Problems-on stack -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 2 -Description: Here are some practice problems for Stack data structure divided into topic-wise and difficulty wise. -tags: [DSA, algorithms, stack, dsa] ---- - -### Basic Stack Operations: - - - [Valid Parentheses](https://leetcode.com/problems/valid-parentheses/description/) - - [Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/description/) - - [Reverse a string using Stack](https://www.geeksforgeeks.org/problems/reverse-a-string-using-stack/1) - - [Backspace String Compare](https://leetcode.com/problems/backspace-string-compare/description) - - [Baseball Game](https://leetcode.com/problems/baseball-game/description/) - - [Reverse a string using Stack](https://www.geeksforgeeks.org/problems/reverse-each-word-in-a-given-string1001/1) - - ### Monotonic Stack: - - - [Next Greater Element I](https://leetcode.com/problems/next-greater-element-i/description/) - - [Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/description/) - - [Help Classmates](https://www.geeksforgeeks.org/problems/help-classmates--141631/1) - - [Daily Temperatures](https://leetcode.com/problems/daily-temperatures/description/) - - [Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/description/) - - [Largest Rectangle in Histogram](https://leetcode.com/problems/largest-rectangle-in-histogram/description/) - - ### Stack with Extra Operations: - - - [Min Stack](https://leetcode.com/problems/min-stack/description/) - - [Max Stack](https://www.naukri.com/code360/problems/max-stack_985280) - - [Online Stock Span](https://leetcode.com/problems/online-stock-span/description/) - - [Sum of Subarray Minimums](https://leetcode.com/problems/sum-of-subarray-minimums/description/) - - [Maximum Frequency Stack](https://leetcode.com/problems/maximum-frequency-stack/description/) - - ### Stack with Recursion or DFS: - - - [Simplify Path](https://leetcode.com/problems/simplify-path/description/) - - [Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/description/) - - [Decode String](https://leetcode.com/problems/decode-string/description/) - - [Expression Add Operators](https://leetcode.com/problems/expression-add-operators/description/) - - [Basic Calculator](https://leetcode.com/problems/basic-calculator/description/) - -### Infix/Prefix/Postfix Expressions: - - - [Evaluate Reverse Polish Notation](https://leetcode.com/problems/evaluate-reverse-polish-notation/description/) - - [Infix to Postfix Conversion](https://www.geeksforgeeks.org/problems/infix-to-postfix-1587115620/1) - -### Stack with Backtracking: - - - [Remove K Digits](https://leetcode.com/problems/remove-k-digits/description/) - - [132 Pattern](https://leetcode.com/problems/132-pattern/description/) - - [Asteroid Collision](https://leetcode.com/problems/asteroid-collision/description/) - - [Smallest Subsequence of Distinct Characters](https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/description/) - -### Stack in Tree Traversals: - - - [Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/description/) - - [Binary Tree Preorder Traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/description/) - - [Iterative Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/description/) - - [Binary Search Tree Iterator](https://leetcode.com/problems/binary-search-tree-iterator/description/) - - [Flatten Binary Tree to Linked List](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/description/) \ No newline at end of file diff --git a/docs/Stack/Reverse-Stack.md b/docs/Stack/Reverse-Stack.md deleted file mode 100644 index d4c52edf5..000000000 --- a/docs/Stack/Reverse-Stack.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -id: stack-reversal -title: Stack Reversal -sidebar_label: Stack Reversal -description: "Reversing a stack involves changing the order of elements so that the bottom becomes the top and vice versa." -tags: [dsa, algorithms, stack] ---- - -### Definition: -Reversing a stack means rearranging the elements in such a way that the last element added becomes the first element to be removed, effectively flipping the order of the stack. - -### Problem Statement: -Given a stack of integers, the task is to reverse the stack using recursion. The function should return the stack with the order of elements reversed, without using any additional data structures except for the recursion stack. - -### Algorithm Steps: - -1. **Base Case:** If the stack is empty, return from the function. -2. **Recursive Case:** - - Pop the top element from the stack. - - Call the function recursively to reverse the remaining stack. - - Insert the popped element at the bottom of the reversed stack. - -3. **Insertion at Bottom:** A helper function is required to insert an element at the bottom of the stack. - -### Steps Involved: -1. **Function `reverseStack`:** This function is responsible for reversing the stack recursively. - - *Step 1.1:* Check if the stack is empty; if it is, return. - *Step 1.2:* Pop the top element and store it. - *Step 1.3:* Recursively call `reverseStack` for the remaining stack. - -2. **Function `insertAtBottom`:** This function inserts an element at the bottom of the stack. - - *Step 2.1:* Check if the stack is empty; if it is, push the element. - *Step 2.2:* Pop the top element, call `insertAtBottom` recursively, and push the popped element back. - -3. **Main Function:** The main function initializes the stack, calls `reverseStack`, and displays the reversed stack. - -### Time Complexity: -- The time complexity of this solution is `O(n)`, where `n` is the number of elements in the stack. This is because each element is processed a constant number of times (popped and inserted). - -### Sample Input: -Stack: [1, 2, 3, 4, 5] - -### Sample Output: -Stack after reversal: [5, 4, 3, 2, 1] - -### Explanation of Sample: -- The stack is reversed so that the top element (5) becomes the bottom, and the bottom element (1) becomes the top. - -### C++ Implementation: -```cpp -#include -#include -using namespace std; - -// Function to insert an element at the bottom of the stack -void insertAtBottom(stack& s, int x) { - if (s.empty()) { - s.push(x); - } else { - int temp = s.top(); - s.pop(); - insertAtBottom(s, x); - s.push(temp); - } -} - -// Function to reverse the stack -void reverseStack(stack& s) { - if (!s.empty()) { - int x = s.top(); - s.pop(); - reverseStack(s); - insertAtBottom(s, x); - } -} - -int main() { - stack s; - s.push(1); - s.push(2); - s.push(3); - s.push(4); - s.push(5); - - reverseStack(s); - - cout << "Stack after reversal: "; - while (!s.empty()) { - cout << s.top() << " "; - s.pop(); - } - return 0; -} -``` -### Python Implementation: -```py -def insert_at_bottom(stack, x): - """Helper function to insert an element at the bottom of the stack.""" - if not stack: - stack.append(x) - else: - temp = stack.pop() - insert_at_bottom(stack, x) - stack.append(temp) - -def reverse_stack(stack): - """Function to reverse the stack using recursion.""" - if stack: - x = stack.pop() - reverse_stack(stack) - insert_at_bottom(stack, x) - -if __name__ == "__main__": - # Sample stack - stack = [1, 2, 3, 4, 5] - - reverse_stack(stack) - - print("Stack after reversal:", stack) - -``` diff --git a/docs/Stack/Stack-permutation.md b/docs/Stack/Stack-permutation.md deleted file mode 100644 index a04a99632..000000000 --- a/docs/Stack/Stack-permutation.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -id: stack-permutation -title: Stack Permutation -sidebar_label: Stack Permutation -description: "A stack permutation is a reordering of an input sequence that can be achieved using a single stack with push and pop operations." -tags: [dsa, algorithms, stack] ---- - -### Definition: -A stack permutation is a permutation of objects in the given input queue which is done by transferring elements from the input queue to the output queue with the help of a stack and the built-in push and pop functions. - -The rules are: -- Only dequeue from the input queue. -- Use inbuilt push, and pop functions in the single stack. -- Stack and input queue must be empty at the end. -- Only enqueue to the output queue. - -### Problem Statement: -Given two integer arrays, `input` and `output`, each containing unique elements and both of the same length `n`, determine if it is possible to achieve the output sequence using only stack operations on the input sequence. In other words, we start with the input array and can perform a series of stack operations: we may push elements from input onto a stack in their original order and pop them off the stack to match the output sequence. The task is to write a program that checks if the output sequence is a valid stack permutation of the input sequence. If it's possible to generate the output using these stack operations, print "Yes"; otherwise, print "No" - -### Algorithm Steps: - -1. Initialize an empty stack to hold elements temporarily. -2. Push each element from the input sequence onto the stack. -3. Whenever the stack's top matches the next element in the output sequence, pop it from the stack. -4. If all elements are matched and the stack is empty at the end, the output is a valid stack permutation; otherwise, it is not. - -### Steps Involved: -1. **Input Arrays:** The program receives `input` and `output` arrays, which are both of the same length and contain unique elements. - -2. **Function `isStackPermutation`:** This function checks if `output` is a valid stack permutation of `input`. - - *Step 2.1:* A `stack` is initialized to simulate stack operations, and it uses standard stack operations with C++'s inbuilt `push()` and `pop()` methods. - *Step 2.2:* The variable `j` tracks the current index of the `output` array. -3. **Iterate through `input`:** The loop processes each element in `input`: - - *Step 3.1:* Each element from `input` is pushed onto the stack. - *Step 3.2:* If the stack’s top matches the next element in `output`, it’s popped from the stack, and the index `j` is incremented to move to the next element in `output`. -4. **Result Check:** After processing all elements in input, the program checks if all elements in `output` have been matched. If `j` equals `n` (the length of output), the function returns `true`; otherwise, it returns `false`. - -5. **Main Function:** The `main` function tests the `isStackPermutation` function with sample arrays and outputs "Yes" if `output` is achievable from `input` using stack operations, and "No" otherwise. - - -### Time Complexity: -- The time complexity of this solution is `O(n)`, where `n` is the number of elements in the input (or output) array. This is because we iterate through each element in the input array once, pushing each onto the stack. Each element can only be popped from the stack once when it matches the next element in the output array, so the number of push and pop operations is limited to -`2n` (one push and one pop per element at most). Thus, the algorithm efficiently completes the check in linear time. - -### Sample Input: -int input[] = {1, 2, 3}; -int output[] = {2, 1, 3}; - -### Sample Output: -Yes, it is a stack permutation. - -### Explanation of Sample: - -- Push 1 and 2 from input onto the stack. The stack now contains {1, 2}. -- Pop 2 and 1 from the stack since they match the first two elements of output. The stack is now empty. -- Push 3 from input onto the stack, then pop 3 as it matches the next element in output. -- All elements in output have been matched, and the stack is empty, confirming that {2, 1, 3} is a valid stack permutation of {1, 2, 3}. - -### C++ Implementation: -```cpp -#include -#include -using namespace std; - -// Function to check if the given output is a stack permutation of input -bool isStackPermutation(int input[], int output[], int n) { - stack st; - int j = 0; - - for (int i = 0; i < n; i++) { - // Push the current element of the input array to the stack - st.push(input[i]); - - // Check if the top of the stack matches the output array - while (!st.empty() && st.top() == output[j]) { - st.pop(); - j++; - } - } - - // If j has reached n, then output is a valid permutation - return (j == n); -} - -int main() { - int input[] = {1, 2, 3}; - int output[] = {2, 1, 3}; - int n = sizeof(input) / sizeof(input[0]); - - if (isStackPermutation(input, output, n)) - cout << "Yes, it is a stack permutation" << endl; - else - cout << "No, it is not a stack permutation" << endl; - - return 0; -} - - -``` - -### Python Implementation: -```python -def is_stack_permutation(input, output): - stack = [] - j = 0 - n = len(input) - - for i in range(n): - # Push the current element of the input array to the stack - stack.append(input[i]) - - # Check if the top of the stack matches the output array - while stack and stack[-1] == output[j]: - stack.pop() - j += 1 - - # If j has reached n, then output is a valid permutation - return j == n - -if __name__ == "__main__": - input = [1, 2, 3] - output = [2, 1, 3] - - if is_stack_permutation(input, output): - print("Yes, it is a stack permutation") - else: - print("No, it is not a stack permutation") -``` - - diff --git a/docs/Stack/Stock-span.md b/docs/Stack/Stock-span.md deleted file mode 100644 index 519c9a992..000000000 --- a/docs/Stack/Stock-span.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: stock-span -title: Stock Span Problem -sidebar_label: Stock Span Problem -description: "The Stock Span Problem is a financial problem that calculates the span of stock's price on a given day." -tags: [dsa, algorithms, stack] ---- - -### Definition: -The Stock Span Problem is defined as follows: Given a list of daily stock prices, the span of the stock's price on a given day is defined as the maximum number of consecutive days (including the current day) for which the price of the stock was less than or equal to the price on the given day. - -### Problem Statement: -You are given an array of stock prices, where each element represents the stock price on a particular day. Your task is to compute an array of the same size, where each element at index `i` contains the span of the stock price on day `i`. - -The span of the stock price is defined as the number of consecutive days (including the current day) for which the stock price was less than or equal to the price on day `i`. - -### Algorithm Steps: - -1. Initialize an empty stack to hold indices of the days. -2. Traverse the array of stock prices from left to right. -3. For each day, while the stack is not empty and the price of the current day is greater than the price of the day at the index on the top of the stack, pop from the stack. -4. If the stack is empty, it means the current price is greater than all previous prices, so the span is the current index + 1. If the stack is not empty, the span is the difference between the current index and the index at the top of the stack. -5. Push the current index onto the stack. -6. Repeat the above steps for all stock prices. - -### Steps Involved: -1. **Input Array:** The program receives an array of stock prices. -2. **Function `calculateStockSpan`:** This function calculates the span for each day. - - *Step 2.1:* A `stack` is initialized to store indices of the stock prices. - - *Step 2.2:* An array `span[]` is initialized to store the span of each day. -3. **Iterate through `prices`:** For each price in the stock prices: - - *Step 3.1:* While the stack is not empty and the current price is greater than the price at the index of the stack's top, the top index is popped from the stack. - - *Step 3.2:* If the stack is empty, the span is the current index + 1; otherwise, it's the difference between the current index and the index at the top of the stack. - -4. **Push the current index:** After calculating the span for the current price, push the index onto the stack. -5. **Return the `span[]`:** After processing all prices, return the computed spans. - -### Time Complexity: -- The time complexity of this solution is `O(n)`, where `n` is the number of stock prices. Each price is pushed and popped from the stack at most once. - -### Sample Input: -```cpp -int prices[] = {100, 80, 60, 70, 60, 75, 85}; -int n = sizeof(prices) / sizeof(prices[0]); -``` -### Sample Output: -Span array: [1, 1, 1, 2, 1, 4, 6] - -### C++ Implementation: -```cpp -#include -#include -using namespace std; - -// Function to calculate stock span values -void calculateStockSpan(int prices[], int span[], int n) { - stack st; - st.push(0); // First day's price always has a span of 1 - span[0] = 1; - - for (int i = 1; i < n; i++) { - // Pop elements from the stack while the current price is greater - while (!st.empty() && prices[st.top()] <= prices[i]) { - st.pop(); - } - - // If the stack is empty, current price is greater than all previous prices - span[i] = st.empty() ? i + 1 : i - st.top(); - st.push(i); - } -} -int main() { - int prices[] = {100, 80, 60, 70, 60, 75, 85}; - int n = sizeof(prices) / sizeof(prices[0]); - int span[n]; - - calculateStockSpan(prices, span, n); - - cout << "Span array: "; - for (int i = 0; i < n; i++) { - cout << span[i] << " "; - } - cout << endl; - - return 0; -} -``` -### Python Implementation: -```python -def calculate_stock_span(prices): - n = len(prices) - span = [0] * n - stack = [] - - for i in range(n): - # Calculate span for the current price - while stack and prices[stack[-1]] <= prices[i]: - stack.pop() - - # If the stack is empty, current price is greater than all previous prices - span[i] = i + 1 if not stack else i - stack[-1] - - # Push the current index onto the stack - stack.append(i) - - return span - -if __name__ == "__main__": - prices = [100, 80, 60, 70, 60, 75, 85] - span = calculate_stock_span(prices) - - print("Span array:", span) -``` diff --git a/docs/Stack/String_Reversal.md b/docs/Stack/String_Reversal.md deleted file mode 100644 index 39f4da23d..000000000 --- a/docs/Stack/String_Reversal.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -id: string-reversal -title: String Reversal -sidebar_label: String Reversal -description: "This program reverses a given string by pushing its characters onto a stack and then popping them back into the string." -tags: [dsa, algorithms, stack] ---- - -## Problem Statement: -Write a program to reverse a string using stack data structure. - -## Defination -The program reverses a given string using the stack data structure. The program reads a string input from the user, pushes each character onto a stack, and then pops the characters from the stack to display the string in reverse order. - - -## Algorithm Steps: - -This C++ program uses a stack data structure to reverse a string, demonstrating fundamental stack operations like push and pop. The stack is implemented using a structure that holds an array for the items (characters of the string) and an integer top that tracks the position of the top element. Several helper functions manage the stack, including initialize to set up an empty stack, - -```isFull``` to check if the stack has reached its capacity, - -```isEmpty``` to check if the stack is empty, - -```push``` to add characters to the stack, and - -```pop``` to remove characters from it. - -The main logic of the program lies in the ```reverseString``` function. - -The function first pushes each character of the input string onto the stack. Since a stack operates on a Last-In-First-Out (LIFO) principle, when the characters are popped back off the stack and placed into the string, they are inserted in reverse order. Thus, the string is reversed by the end of the process. The program reads the string from the user, uses the stack to reverse it, and then prints the reversed string. - -## Time Complexity -The time complexity of the `reverseString` function is `O(n)`, where n is the length of the input string. This is because the function first iterates through each character in the string to push it onto the stack, taking O(n) time. Then, in a second loop, it pops each character from the stack and places it back into the string, also taking `O(n)` time. Since both loops run sequentially, the overall time complexity is `O(n) + O(n)` = `O(n)`. - -## Space Complexity -The space complexity of the `reverseString` function is `O(n)` due to the use of a stack to store each character of the input string. The stack requires `O(n)` additional space since it stores all characters temporarily until they are popped back into the string. While the input string itself takes `O(n)` space, it is not considered extra memory allocation by the function, as it is passed by reference. Thus, the dominant additional space usage is from the stack, resulting in an overall space complexity of `O(n)`. - - -## Sample Input: -Enter a string (max 100 characters): My Contribution - -## Sample Output: -Reversed string: noitubirtnoC yM - -## C++ Implementation: - -```cpp -#include -#include -#include - -void reverseString(std::string &str) { - std::stack stack; - for (char ch : str) { - stack.push(ch); - } - for (size_t i = 0; i < str.length(); i++) { - str[i] = stack.top(); - stack.pop(); - } -} - -int main() { - std::string str; - std::cout << "Enter a string (max 100 characters): "; - std::getline(std::cin, str); - reverseString(str); - std::cout << "Reversed string: " << str << std::endl; - return 0; -} -``` diff --git a/docs/Stack/Trapping Rain Water Problem.md b/docs/Stack/Trapping Rain Water Problem.md deleted file mode 100644 index 4fa914f23..000000000 --- a/docs/Stack/Trapping Rain Water Problem.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -id: trapping-rain-water -title: Trapping Rain Water -sidebar_label: Trapping Rain Water -sidebar_position: 1 -description: Documentation for the Trapping Rain Water algorithm to calculate water trapped between bars of varying heights. -tags: [algorithm, water-trapping, stack] ---- - -# Trapping Rain Water - -The **Trapping Rain Water** algorithm calculates the amount of water that can be trapped between bars of varying heights. - -## Problem Statement -Given an array of non-negative integers representing the heights of bars, calculate how much water can be trapped after raining. - -## Approach -1. Use a stack to keep track of the indices of the bars. -2. Iterate through each bar in the array. -3. For each bar, if it's taller than the one on the stack's top, calculate the trapped water. -4. Repeat until all bars are processed. - -### Code Implementation -Below is a C++ implementation of the Trapping Rain Water algorithm. - -```cpp -#include -#include -#include -using namespace std; - -int maxWater(vector& arr) { - stack st; - int res = 0; - for (int i = 0; i < arr.size(); i++) { - while (!st.empty() && arr[st.top()] < arr[i]) { - int pop_height = arr[st.top()]; - st.pop(); - if (st.empty()) break; - int distance = i - st.top() - 1; - int water = min(arr[st.top()], arr[i]) - pop_height; - res += distance * water; - } - st.push(i); - } - return res; -} -``` - -### Math Formulas -The formula for trapped water between two bars can be expressed as: - -$$ \text{Water} = \text{distance} \times (\min(\text{height}_{left}, \text{height}_{right}) - \text{height}_{current}) $$ - -### Diagrams -The following Mermaid diagram represents the steps for processing bars to trap water: - -```mermaid -graph TD; - A[Start] --> B[Initialize Stack]; - B --> C[Loop through each bar]; - C --> D{Is current bar taller than stack top?}; - D -->|Yes| E[Pop stack and calculate trapped water]; - D -->|No| F[Push index to stack]; - E --> C; - F --> C; - C --> G[End]; -``` - - diff --git a/docs/Stack/_category_.json b/docs/Stack/_category_.json deleted file mode 100644 index b994ad528..000000000 --- a/docs/Stack/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Stacks", - "position": 7, - "link": { - "type": "generated-index", - "description": "A stack is a linear data structure that follows the Last In First Out (LIFO) principle. It allows operations to be performed at one end, called the top of the stack, making it efficient for scenarios such as expression evaluation, backtracking algorithms, and function call management." - } -} diff --git a/docs/Stack/introduction-to-stack.md b/docs/Stack/introduction-to-stack.md deleted file mode 100644 index 75d19207d..000000000 --- a/docs/Stack/introduction-to-stack.md +++ /dev/null @@ -1,311 +0,0 @@ ---- -id: introduction-to-stack -title: Stack Data Structure -sidebar_label: Introduction to Stack -sidebar_position: 1 -description: 'A stack is a linear data structure that follows the Last In First Out (LIFO) principle. It allows operations to be performed at one end, called the top of the stack, making it efficient for scenarios such as expression evaluation, backtracking algorithms, and function call management.' -tags: [dsa, data-structures, Stack] ---- - -### Introduction to Stack - -A **stack** is a linear data structure that follows the Last In First Out (LIFO) principle. This means that the last element added to the stack will be the first one to be removed. Think of a stack of plates; you add plates to the top and also remove plates from the top. - -Stacks are widely used in various computing applications, including: - -- **Function Call Management**: Keeping track of active subroutines in programming languages. -- **Expression Evaluation**: Parsing expressions in compilers. -- **Backtracking Algorithms**: Navigating through potential paths in maze-solving or puzzle games. -- **Undo Mechanisms**: Implementing undo features in text editors and other applications. - -![alt text](Introduction_to_Stack.png) - -### Stack Operations - -A stack typically supports the following operations: - -1. **Push**: Add an element to the top of the stack. -2. **Pop**: Remove the element from the top of the stack. -3. **Peek (Top)**: Retrieve the element at the top of the stack without removing it. -4. **isEmpty**: Check if the stack is empty. -5. **isFull**: Check if the stack is full (applicable for stacks with a fixed size). -6. **Size**: Get the number of elements in the stack. - -### Pseudocode - -#### Basic Operations - -1. **Push**: - - ```text - function push(stack, element): - if isFull(stack): - return "Stack Overflow" - stack.top = stack.top + 1 - stack.elements[stack.top] = element - ``` - -2. **Pop**: - - ```text - function pop(stack): - if isEmpty(stack): - return "Stack Underflow" - element = stack.elements[stack.top] - stack.top = stack.top - 1 - return element - ``` - -3. **Peek (Top)**: - - ```text - function peek(stack): - if isEmpty(stack): - return "Stack is empty" - return stack.elements[stack.top] - ``` - -4. **isEmpty**: - - ```text - function isEmpty(stack): - return stack.top == -1 - ``` - -5. **isFull**: - - ```text - function isFull(stack): - return stack.top == stack.size - 1 - ``` - -6. **Size**: - - ```text - function size(stack): - return stack.top + 1 - ``` - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -class Stack: - def __init__(self, size): - self.size = size - self.elements = [None] * size - self.top = -1 - - def push(self, element): - if self.is_full(): - print("Stack Overflow") - return - self.top += 1 - self.elements[self.top] = element - - def pop(self): - if self.is_empty(): - print("Stack Underflow") - return None - element = self.elements[self.top] - self.top -= 1 - return element - - def peek(self): - if self.is_empty(): - print("Stack is empty") - return None - return self.elements[self.top] - - def is_empty(self): - return self.top == -1 - - def is_full(self): - return self.top == self.size - 1 - - def size_of_stack(self): - return self.top + 1 - -# Example usage -stack = Stack(5) -stack.push(10) -stack.push(20) -print(stack.pop()) # Output: 20 -print(stack.peek()) # Output: 10 -print(stack.is_empty()) # Output: False -print(stack.size_of_stack()) # Output: 1 -``` - -#### C++ Implementation - -```cpp -#include -using namespace std; - -class Stack { -private: - int *elements; - int top; - int size; - -public: - Stack(int size) { - this->size = size; - elements = new int[size]; - top = -1; - } - - void push(int element) { - if (is_full()) { - cout << "Stack Overflow" << endl; - return; - } - elements[++top] = element; - } - - int pop() { - if (is_empty()) { - cout << "Stack Underflow" << endl; - return -1; // Indicating underflow - } - return elements[top--]; - } - - int peek() { - if (is_empty()) { - cout << "Stack is empty" << endl; - return -1; // Indicating empty - } - return elements[top]; - } - - bool is_empty() { - return top == -1; - } - - bool is_full() { - return top == size - 1; - } - - int size_of_stack() { - return top + 1; - } - - ~Stack() { - delete[] elements; - } -}; - -// Example usage -int main() { - Stack stack(5); - stack.push(10); - stack.push(20); - cout << stack.pop() << endl; // Output: 20 - cout << stack.peek() << endl; // Output: 10 - cout << boolalpha << stack.is_empty() << endl; // Output: false - cout << stack.size_of_stack() << endl; // Output: 1 - return 0; -} -``` - -#### Java Implementation - -```java -public class Stack { - private int[] elements; - private int top; - private int size; - - public Stack(int size) { - this.size = size; - elements = new int[size]; - top = -1; - } - - public void push(int element) { - if (is_full()) { - System.out.println("Stack Overflow"); - return; - } - elements[++top] = element; - } - - public int pop() { - if (is_empty()) { - System.out.println("Stack Underflow"); - return -1; // Indicating underflow - } - return elements[top--]; - } - - public int peek() { - if (is_empty()) { - System.out.println("Stack is empty"); - return -1; // Indicating empty - } - return elements[top]; - } - - public boolean is_empty() { - return top == -1; - } - - public boolean is_full() { - return top == size - 1; - } - - public int size_of_stack() { - return top + 1; - } - - // Example usage - public static void main(String[] args) { - Stack stack = new Stack(5); - stack.push(10); - stack.push(20); - System.out.println(stack.pop()); // Output: 20 - System.out.println(stack.peek()); // Output: 10 - System.out.println(stack.is_empty()); // Output: false - System.out.println(stack.size_of_stack()); // Output: 1 - } -} -``` - -### Complexity - -- **Time Complexity**: - - - Push: $O(1)$ - - Pop: $O(1)$ - - Peek: $O(1)$ - - isEmpty: $O(1)$ - - isFull: $O(1)$ - - Size: $O(1)$ - -- **Space Complexity**: $O(n)$, where $n$ is the number of elements that can be stored in the stack. - -### Example - -Consider a stack with the following operations: - -1. Push 10 -2. Push 20 -3. Pop -4. Peek -5. Check if empty -6. Get size - -**Operations**: - -- **Push 10**: Stack becomes [10, _, _, _, _] -- **Push 20**: Stack becomes [10, 20, _, _, _] -- **Pop**: Removes 20, Stack becomes [10, _, _, _, _] -- **Peek**: Returns 10, Stack remains [10, _, _, _, _] -- **isEmpty**: Returns false -- **Size**: Returns 1 - -### Conclusion - -A stack is a fundamental data structure that is simple yet powerful, enabling efficient management of data with its LIFO behavior. It plays a critical role in various computing scenarios, such as managing function calls, parsing expressions, and implementing undo mechanisms. Understanding and implementing stacks is essential for solving a wide range of algorithmic problems and building efficient software systems. diff --git a/docs/Stack/stack.md b/docs/Stack/stack.md deleted file mode 100644 index 6a77f511a..000000000 --- a/docs/Stack/stack.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: monotonic-stack -title: Monotonic Stack -sidebar_label: Monotonic Stack -sidebar_position: 4 -description: 'Monotonic Stack is a data structure technique used to maintain elements in a particular order, typically increasing or decreasing, and is commonly used for solving problems involving range queries, such as finding the next greater element.' -tags: [dsa, algorithms, stack, monotonic-stack] ---- - -### Introduction - -A **Monotonic Stack** is a special type of stack that maintains its elements in a sorted order, either strictly increasing or strictly decreasing. It is a powerful tool used in many problems where you need to find the next or previous greater or smaller elements efficiently. - -Monotonic stacks are primarily used in problems related to range queries, like finding the next greater or smaller elements in a sequence, solving problems that involve temperatures, stock prices, or histogram areas. - -### How the Stack Works - -A monotonic stack operates under two variations: -1. **Monotonically Increasing Stack**: The stack maintains elements in increasing order, where the top of the stack has the smallest value. -2. **Monotonically Decreasing Stack**: The stack maintains elements in decreasing order, where the top of the stack has the largest value. - -The fundamental principle is to push elements onto the stack while ensuring the monotonic property is not violated. If the property is violated by a new element, elements are popped from the stack until the property is restored. This approach helps in reducing the time complexity of certain range query problems. - -### Algorithm - -To construct a monotonic stack: -1. Initialize an empty stack. -2. Iterate through each element in the input. -3. For each element, check if it violates the monotonic property of the stack. - - If it does, keep popping elements from the stack until the property is restored. - - Push the current element onto the stack. -4. Repeat this process until all elements have been processed. - -### Applications - -- **Next Greater Element**: Finding the next greater element for each element in an array can be efficiently solved using a monotonic stack. -- **Histogram Problems**: Finding the largest rectangle in a histogram or largest area under a histogram can be solved using a decreasing monotonic stack. -- **Stock Span Problem**: Calculating the stock span for a series of days is another application of the monotonic stack. -- **Temperature Problem**: Finding the number of days until a warmer temperature can be solved using a monotonic stack. - -### Pseudocode - -```text -Function monotonicStack(arr): - Initialize empty stack - For each element in arr: - While stack is not empty and element violates monotonic property: - Pop element from stack - Push current element to stack - Return stack -``` - -### Implementation in c++ - -```cpp -#include -#include -#include - -using namespace std; - -// Function to find the next greater element using a monotonic stack -vector nextGreaterElement(vector& nums) { - vector result(nums.size(), -1); // Initialize result with -1 - stack st; // Monotonic stack - - for (int i = 0; i < nums.size(); i++) { - // While stack is not empty and current element is greater than the stack's top - while (!st.empty() && nums[i] > nums[st.top()]) { - result[st.top()] = nums[i]; // Set the next greater element - st.pop(); // Pop the top - } - st.push(i); // Push the current index onto the stack - } - - return result; -} - -int main() { - vector nums = {2, 1, 2, 4, 3}; - vector result = nextGreaterElement(nums); - - // Output the result - for (int num : result) { - cout << num << " "; - } - cout << endl; - - return 0; -} -``` -### Implementation in Java - -```Java -import java.util.Stack; -import java.util.Arrays; - -public class NextGreaterElement { - - // Function to find the next greater element using a monotonic stack - public static int[] nextGreaterElement(int[] nums) { - int[] result = new int[nums.length]; // Initialize result array - Arrays.fill(result, -1); // Fill result with -1 - Stack stack = new Stack<>(); // Monotonic stack to store indices - - for (int i = 0; i < nums.length; i++) { - // While stack is not empty and current element is greater than stack's top element - while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) { - result[stack.pop()] = nums[i]; // Set the next greater element - } - stack.push(i); // Push current index onto the stack - } - - return result; - } - - public static void main(String[] args) { - int[] nums = {2, 1, 2, 4, 3}; - int[] result = nextGreaterElement(nums); - - // Output the result - for (int num : result) { - System.out.print(num + " "); - } - System.out.println(); - } -} -``` - -### Time Complexity -- Time Complexity: $O(n)$ -Each element is pushed and popped from the stack at most once, making the overall time complexity linear. -- Space Complexity: $O(n)$ -The stack requires space proportional to the number of elements in the input array. diff --git a/docs/Standard Template Library/STL-algorithms.md b/docs/Standard Template Library/STL-algorithms.md deleted file mode 100644 index 0c84816ac..000000000 --- a/docs/Standard Template Library/STL-algorithms.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: introduction-to-STL-algorithms -title: STL Algorithms -sidebar_label: STL Algorithms -sidebar_position: 7 -description: "STL provides a wide variety of tools that allow C++ developers to write code that is both efficient and reusable. It abstracts away many of the complexities of data structure management and algorithm implementation, making it an essential part of modern C++ programming." -tags: [STL, data-structures, libraries] ---- - -# Algorithms in C++ STL - -The **C++ Standard Template Library (STL)** provides a rich set of algorithms that work on containers. These algorithms are implemented as template functions and can perform a variety of tasks such as searching, sorting, manipulating, and more. The key advantage is that the same algorithm can work with different types of containers. - ---- - -## Categories of Algorithms - -Algorithms in STL can be broadly divided into the following categories: - -1. **Sorting Algorithms** -2. **Searching Algorithms** -3. **Modifying Algorithms** -4. **Non-Modifying Algorithms** -5. **Partitioning Algorithms** -6. **Set Operations** -7. **Min/Max Operations** -8. **Heap Operations** - ---- - -## 1. Sorting Algorithms - -Sorting algorithms rearrange elements in a container in a specific order. The most commonly used sorting algorithm in STL is `sort()`. - -### Common Functions: - -- **`sort()`**: Sorts a range of elements in ascending order by default. -- **`partial_sort()`**: Sorts the first N elements. -- **`stable_sort()`**: Sorts while preserving the relative order of equivalent elements. -- **`nth_element()`**: Reorders the elements so that the element at the Nth position is in the sorted order. - -### Example: - -```cpp -#include -#include -#include - -int main() { - std::vector v = {5, 2, 9, 1, 5, 6}; - - std::sort(v.begin(), v.end()); // Sort in ascending order - - for (int i : v) - std::cout << i << " "; - return 0; -} -``` - - -## 2. Searching Algorithms - -Searching algorithms help you find elements in a container. - -### Common Functions: - -- **find()**: Finds an element in a range. -- **binary_search()**: Checks if an element exists in a sorted range. -- **lower_bound()**: Finds the first position where a value can be inserted to maintain sorted order. -- **upper_bound()**: Finds the last position where a value can be inserted to maintain sorted order. - - -### Example: - -```cpp -#include -#include -#include - -int main() { - std::vector v = {10, 20, 30, 40, 50}; - - // Searching for 30 - if (std::binary_search(v.begin(), v.end(), 30)) { - std::cout << "30 found!" << std::endl; - } else { - std::cout << "30 not found!" << std::endl; - } - - return 0; -} -``` - -## 3. Modifying Algorithms - -These algorithms modify the elements in a container. - - -### Common Functions: -- **reverse()**: Reverses the order of elements in a range. -- **fill()**: Fills a range with a specific value. -- **replace()**: Replaces certain values in a range with a new value. -- **swap()**: Swaps the values of two variables. - -### Example: - -```cpp -#include -#include -#include - -int main() { - std::vector v = {1, 2, 3, 4, 5}; - - std::reverse(v.begin(), v.end()); // Reverse the vector - - for (int i : v) - std::cout << i << " "; // Output: 5 4 3 2 1 - - return 0; -} -``` - -## 4. Non-Modifying Algorithms - -These algorithms do not modify the container but perform specific actions like counting or comparing. - -### Common Functions: - -- **count()**: Counts the occurrences of a value in a range. -- **equal()**: Checks if two ranges are equal. -- **mismatch()**: Finds the first position where two ranges differ. -- **for_each()**: Applies a function to each element in a range. - -### Example: - -```cpp -#include -#include -#include - -void print(int value) { - std::cout << value << " "; -} - -int main() { - std::vector v = {1, 2, 3, 4, 5}; - - // Applying a function to each element - std::for_each(v.begin(), v.end(), print); // Output: 1 2 3 4 5 - - return 0; -} - -``` - -## 5. Partitioning Algorithms - -Partitioning algorithms divide a range of elements based on a condition. - - -### Common Functions: - -- **partition()**: Reorders the elements such that elements satisfying a condition appear before the others. -- **stable_partition()**: Same as partition() but preserves the relative order of elements. -- **is_partitioned()**: Checks if a range is partitioned based on a condition. - -### Example: - -```cpp -#include -#include -#include - -bool isEven(int i) { - return i % 2 == 0; -} - -int main() { - std::vector v = {1, 2, 3, 4, 5, 6}; - - std::partition(v.begin(), v.end(), isEven); // Partition based on even numbers - - for (int i : v) - std::cout << i << " "; // Output will show even numbers before odd ones - - return 0; -} - -``` diff --git a/docs/Standard Template Library/STL-containers.md b/docs/Standard Template Library/STL-containers.md deleted file mode 100644 index 8e5b0bf62..000000000 --- a/docs/Standard Template Library/STL-containers.md +++ /dev/null @@ -1,258 +0,0 @@ ---- -id: introduction-to-STL-containers -title: STL containers -sidebar_label: STL containers -sidebar_position: 7 -description: "STL provides a wide variety of tools that allow C++ developers to write code that is both efficient and reusable. It abstracts away many of the complexities of data structure management and algorithm implementation, making it an essential part of modern C++ programming." -tags: [STL, data-structures, libraries] ---- - -STL (Standard Template Library) containers are data structures that store collections of objects. STL containers are designed to be flexible, efficient, and consistent. They can store a variety of types and provide a range of operations to manipulate their contents. - -### Types of STL Containers - -1. **Sequence Containers**: Maintain elements in a specific sequence (order). - - **Examples**: `vector`, `list`, `deque`, `array`, `forward_list`. - -2. **Associative Containers**: Store elements in sorted order (by key) and allow fast retrieval using keys. - - **Examples**: `set`, `multiset`, `map`, `multimap`. - -3. **Unordered Associative Containers**: Do not maintain any particular order, but allow fast retrieval based on hash tables. - - **Examples**: `unordered_set`, `unordered_map`, `unordered_multiset`, `unordered_multimap`. - -4. **Container Adapters**: Provide a different interface to existing containers. - - **Examples**: `stack`, `queue`, `priority_queue`. - ---- - -### 1. **Sequence Containers** - -#### a. **`vector`**: -- A dynamic array that can grow in size. It supports random access and is highly efficient for element access and insertion/removal at the end. - -```cpp -#include -#include - -int main() { - std::vector vec = {1, 2, 3, 4}; - vec.push_back(5); // Add element at the end - - for (int i : vec) - std::cout << i << " "; // Output: 1 2 3 4 5 -} -``` -**Key operations**: -- `push_back()`, `pop_back()`, `[]` (random access), `size()`, `clear()`. - ---- - -#### b. **`list`**: -- A doubly linked list where elements are stored in nodes that contain pointers to the previous and next elements. - -```cpp -#include -#include - -int main() { - std::list lst = {1, 2, 3}; - lst.push_back(4); - lst.push_front(0); // Add element at the front - - for (int i : lst) - std::cout << i << " "; // Output: 0 1 2 3 4 -} -``` -**Key operations**: -- `push_front()`, `push_back()`, `pop_front()`, `pop_back()`, `insert()`, `erase()`. - ---- - -#### c. **`deque`** (Double-ended Queue): -- Supports fast insertion/removal at both ends but slower access in the middle. - -```cpp -#include -#include - -int main() { - std::deque dq = {2, 3}; - dq.push_front(1); - dq.push_back(4); - - for (int i : dq) - std::cout << i << " "; // Output: 1 2 3 4 -} -``` -**Key operations**: -- `push_front()`, `push_back()`, `pop_front()`, `pop_back()`, `[]` (random access). - ---- - -### 2. **Associative Containers** - -#### a. **`set`**: -- Stores unique elements in sorted order. It allows fast lookup, insertion, and deletion. - -```cpp -#include -#include - -int main() { - std::set s = {3, 1, 4, 2}; - s.insert(5); // Add element - - for (int i : s) - std::cout << i << " "; // Output: 1 2 3 4 5 (sorted order) -} -``` -**Key operations**: -- `insert()`, `find()`, `erase()`, `count()`. - ---- - -#### b. **`map`**: -- Stores key-value pairs where each key is unique and the keys are ordered. - -```cpp -#include -#include - -int main() { - std::map m; - m[1] = "one"; - m[2] = "two"; - - for (const auto &p : m) - std::cout << p.first << ": " << p.second << std::endl; - // Output: - // 1: one - // 2: two -} -``` -**Key operations**: -- `operator[]`, `insert()`, `find()`, `erase()`, `count()`. - ---- - -### 3. **Unordered Associative Containers** - -#### a. **`unordered_set`**: -- Similar to `set`, but the elements are stored in an unordered fashion (using hash tables for fast lookup). - -```cpp -#include -#include - -int main() { - std::unordered_set us = {1, 3, 5}; - us.insert(4); - - for (int i : us) - std::cout << i << " "; // Output order may vary: 1 3 5 4 -} -``` -**Key operations**: -- `insert()`, `find()`, `erase()`, `count()`. - ---- - -#### b. **`unordered_map`**: -- Stores key-value pairs but without any specific order. Uses a hash table for fast key-based lookups. - -```cpp -#include -#include - -int main() { - std::unordered_map um; - um[1] = "one"; - um[2] = "two"; - - for (const auto &p : um) - std::cout << p.first << ": " << p.second << std::endl; - // Output order may vary -} -``` -**Key operations**: -- `operator[]`, `insert()`, `find()`, `erase()`, `count()`. - ---- - -### 4. **Container Adapters** - -#### a. **`stack`**: -- A LIFO (Last In, First Out) data structure that allows pushing and popping elements from the top. - -```cpp -#include -#include - -int main() { - std::stack st; - st.push(1); - st.push(2); - st.push(3); - - while (!st.empty()) { - std::cout << st.top() << " "; // Output: 3 2 1 - st.pop(); - } -} -``` -**Key operations**: -- `push()`, `pop()`, `top()`, `empty()`. - ---- - -#### b. **`queue`**: -- A FIFO (First In, First Out) data structure where elements are added to the back and removed from the front. - -```cpp -#include -#include - -int main() { - std::queue q; - q.push(1); - q.push(2); - q.push(3); - - while (!q.empty()) { - std::cout << q.front() << " "; // Output: 1 2 3 - q.pop(); - } -} -``` -**Key operations**: -- `push()`, `pop()`, `front()`, `back()`, `empty()`. - ---- - -#### c. **`priority_queue`**: -- A specialized queue where elements are stored based on their priority (by default, highest first). - -```cpp -#include -#include - -int main() { - std::priority_queue pq; - pq.push(10); - pq.push(20); - pq.push(5); - - while (!pq.empty()) { - std::cout << pq.top() << " "; // Output: 20 10 5 - pq.pop(); - } -} -``` -**Key operations**: -- `push()`, `pop()`, `top()`, `empty()`. - ---- - -### Conclusion - -STL containers offer flexibility and efficiency for a wide range of tasks. They abstract away low-level details of memory management and algorithm implementation, providing a uniform and convenient interface to handle data. \ No newline at end of file diff --git a/docs/Standard Template Library/STL-iterators.md b/docs/Standard Template Library/STL-iterators.md deleted file mode 100644 index 952580938..000000000 --- a/docs/Standard Template Library/STL-iterators.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: introduction-to-STL-Iterators -title: STL Iterators -sidebar_label: STL Iterators -sidebar_position: 7 -description: "STL provides a wide variety of tools that allow C++ developers to write code that is both efficient and reusable. It abstracts away many of the complexities of data structure management and algorithm implementation, making it an essential part of modern C++ programming." -tags: [STL, data-structures, libraries] ---- - -STL (Standard Template Library) iterators in C++ act as generalized pointers that allow traversal and manipulation of elements in STL containers such as vectors, lists, sets, and maps. Iterators provide an abstraction for traversing containers, without exposing the underlying structure of the container. - -### Types of Iterators - -1. **Input Iterator**: Used for reading data from a container sequentially. It only allows one-way traversal (from beginning to end). - - Example: `std::istream_iterator`, reading integers from input. - -2. **Output Iterator**: Used for writing data to a container sequentially. It also allows one-way traversal but only for output. - - Example: `std::ostream_iterator`, writing integers to output. - -3. **Forward Iterator**: A more versatile version of the input iterator. It allows reading and writing of data. It can traverse a container in a single direction (forward). - - Example: `std::forward_list::iterator`. - -4. **Bidirectional Iterator**: Extends the functionality of forward iterators by allowing traversal in both directions (forward and backward). - - Example: `std::list::iterator`. - -5. **Random Access Iterator**: The most powerful type of iterator, allowing direct access to any element using arithmetic operations (like array subscripting). It can traverse both forward and backward. - - Example: `std::vector::iterator`. - ---- - -### Common Operations on Iterators - -1. **Dereferencing**: Access the element pointed to by the iterator. - ```cpp - std::vector vec = {1, 2, 3, 4, 5}; - std::vector::iterator it = vec.begin(); - std::cout << *it; // Outputs 1 - ``` - -2. **Incrementing**: Move the iterator to the next element. - ```cpp - ++it; // Move to the second element (2) - std::cout << *it; // Outputs 2 - ``` - -3. **Decrementing (for bidirectional and random access iterators)**: Move the iterator to the previous element. - ```cpp - --it; // Move back to the first element - std::cout << *it; // Outputs 1 - ``` - -4. **Arithmetic (for random access iterators)**: Directly move the iterator forward or backward by a specified number of positions. - ```cpp - it += 2; // Move two steps forward - std::cout << *it; // Outputs 3 - ``` - ---- - -### Example: Iterating over a `vector` with an iterator -```cpp -#include -#include - -int main() { - std::vector vec = {1, 2, 3, 4, 5}; - std::vector::iterator it; - - // Iterate through the vector using iterator - for (it = vec.begin(); it != vec.end(); ++it) { - std::cout << *it << " "; // Dereference iterator to access value - } - return 0; -} -``` -**Output**: `1 2 3 4 5` - -### Example: Using Random Access Iterator -```cpp -#include -#include - -int main() { - std::vector vec = {10, 20, 30, 40, 50}; - std::vector::iterator it = vec.begin(); - - std::cout << *(it + 2) << std::endl; // Random access to the third element - it += 3; - std::cout << *it << std::endl; // Now points to the fourth element - - return 0; -} -``` -**Output**: -``` -30 -40 -``` - -### Key Points - -- **Iterator Invalidation**: Be cautious when modifying a container (e.g., inserting or deleting elements) as this can invalidate iterators, leading to undefined behavior. -- **Container-Specific Iterators**: Each STL container provides its own iterator type, like `std::vector::iterator` for vectors, `std::list::iterator` for lists, and so on. -- **`const_iterator`**: If you need read-only access, use `const_iterator`, which prevents modification of the elements. diff --git a/docs/Standard Template Library/STL-theory.md b/docs/Standard Template Library/STL-theory.md deleted file mode 100644 index 2a03e5567..000000000 --- a/docs/Standard Template Library/STL-theory.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -id: introduction-to-STL -title: Standard Template Library -sidebar_label: Standard Template Library -sidebar_position: 7 -description: "STL provides a wide variety of tools that allow C++ developers to write code that is both efficient and reusable. It abstracts away many of the complexities of data structure management and algorithm implementation, making it an essential part of modern C++ programming." -tags: [STL, data-structures, libraries] ---- - -# C++ Standard Template Library (STL) - -The **Standard Template Library (STL)** in C++ is a powerful set of template classes that provide general-purpose, reusable functions and data structures. It is a collection of well-optimized tools that allow developers to manage data structures and algorithms efficiently. - ---- - -## Components of STL - -The STL is divided into three main components: - -1. **Containers** -2. **Algorithms** -3. **Iterators** - ---- - -## 1. Containers - -Containers are objects that store collections of elements. STL containers can be classified into three types: - -### a. Sequence Containers - -These containers store elements in a linear sequence. The most common sequence containers are: - -- **`vector`**: Dynamic array that can resize automatically. -- **`deque`**: Double-ended queue that allows fast insertions and deletions at both ends. -- **`list`**: Doubly linked list that allows fast insertions and deletions anywhere. - -### b. Associative Containers - -Associative containers store elements formed by a combination of a key and a value. They are implemented using balanced binary trees. - -- **`set`**: Stores unique elements in a sorted manner. -- **`multiset`**: Like a `set` but allows duplicate elements. -- **`map`**: Stores key-value pairs, where each key is unique. -- **`multimap`**: Like a `map`, but allows duplicate keys. - -### c. Container Adaptors - -These containers provide a different interface for underlying sequence containers: - -- **`stack`**: Follows the LIFO (Last In First Out) principle. -- **`queue`**: Follows the FIFO (First In First Out) principle. -- **`priority_queue`**: Provides a sorted queue, where the largest element is always at the top. - ---- - -## 2. Algorithms - -STL provides a set of common algorithms like searching, sorting, modifying, etc. that work with containers. These algorithms are implemented as function templates, which makes them reusable for any container type. - -### Common Algorithms: - -- **Sorting**: `sort()`, `partial_sort()` -- **Searching**: `binary_search()`, `find()` -- **Modifying**: `reverse()`, `fill()`, `replace()` -- **Partitioning**: `partition()`, `stable_partition()` -- **Merging**: `merge()`, `inplace_merge()` - -### Example: - -```cpp -#include -#include -#include - -int main() { - std::vector v = {4, 2, 8, 1, 5}; - - // Sorting the vector - std::sort(v.begin(), v.end()); - - // Printing the sorted vector - for (int i : v) - std::cout << i << " "; - - return 0; -} -``` - -## 3. Iterators - -Iterators are used to point to elements in a container. They work similarly to pointers and provide the means to traverse through elements stored in containers. - -Types of Iterators: - -- **Input Iterator**: Used for reading data from a container. -- **Output Iterator**: Used for writing data into a container. -- **Forward Iterator**: Can only move forward. -- **Bidirectional Iterator**: Can move both forward and backward. -- **Random Access Iterator**: Can access any element in constant time. - -### Example: - -```cpp -#include -#include - -int main() { - std::vector v = {1, 2, 3, 4, 5}; - - // Declaring an iterator - std::vector::iterator it; - - // Traversing the vector using the iterator - for (it = v.begin(); it != v.end(); ++it) - std::cout << *it << " "; - - return 0; -} - -``` diff --git a/docs/Strings/Problem-Practice.md b/docs/Strings/Problem-Practice.md deleted file mode 100644 index d531de17c..000000000 --- a/docs/Strings/Problem-Practice.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -id: Practice-Problems-on-strings -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 2 -description: Here are some practice problems for strings -tags: [DSA, algorithms, strings] ---- - - -### Basic problems - -- [Remove Outer Parentheses](https://leetcode.com/problems/remove-outermost-parentheses/) -- [Reverse words in a string](https://leetcode.com/problems/reverse-words-in-a-string/description/) -- [Largest odd number in string](https://leetcode.com/problems/largest-odd-number-in-string/description/) -- [Longest common prefix](https://leetcode.com/problems/longest-common-prefix/description/) -- [Isomorphic string](https://leetcode.com/problems/isomorphic-strings/description/) -- [Rotate string](https://leetcode.com/problems/rotate-string/description/) -- [Valid anagram](https://leetcode.com/problems/valid-anagram/description/) - - -### Medium problems - -- [Sort characters by frequency](https://leetcode.com/problems/sort-characters-by-frequency/description/) -- [Maximum nesting depth of the parentheses](https://leetcode.com/problems/maximum-nesting-depth-of-the-parentheses/description/) -- [Roman to integer](https://leetcode.com/problems/roman-to-integer/description/) -- [String to integer](https://leetcode.com/problems/string-to-integer-atoi/description/) -- [Long palindromic substring](https://leetcode.com/problems/longest-palindromic-substring/description/) -- [Sum of beauty of all substrings](https://leetcode.com/problems/sum-of-beauty-of-all-substrings/description/) -- [Reverse words in a string](https://leetcode.com/problems/reverse-words-in-a-string/description/) - -### Hard problems - -- [Minimum add to make parentheses valid](https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/description/) -- [Count and say](https://leetcode.com/problems/count-and-say/description/) -- [Repeated string match](https://leetcode.com/problems/repeated-string-match/description/) -- [Index of first occurance](https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/description/) -- [Shortest palindrome](https://leetcode.com/problems/shortest-palindrome/description/) -- [Longest happy prefix](https://leetcode.com/problems/longest-happy-prefix/description/) -- [Count palindromic subsequences](https://www.geeksforgeeks.org/problems/count-palindromic-subsequences/1) \ No newline at end of file diff --git a/docs/Tarjan's Algorithm/Tarjan.md b/docs/Tarjan's Algorithm/Tarjan.md deleted file mode 100644 index 8d6e6ae34..000000000 --- a/docs/Tarjan's Algorithm/Tarjan.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: Tarjan -title: "Introduction to Tarjan's Algorithm" -sidebar_label: "Tarjan's Algorithm" -sidebar_position: 1 -description: "Information Tarjan's algorithm" -tags: [Algorithm,tarjan's] ---- - - - -# Tarjan's Algorithm for Strongly Connected Components -## Overview -Tarjan's Algorithm is an efficient DFS-based algorithm used to find all Strongly Connected Components (SCCs) in a directed graph. A strongly connected component of a directed graph is a maximal subset of vertices where each vertex is reachable from every other vertex in the subset. - -## Use Cases -- Optimizing Network Communication: Identifying components in network design where nodes (e.g., servers) can communicate both ways. -- Dependency Analysis: Useful in scenarios where components or modules have dependencies on one another. -- Deadlock Detection: In an operating system, SCCs can be used to identify deadlock cycles in a wait-for graph. - -## Algorithm Details -**Steps** -1. Perform a Depth First Search (DFS) traversal on the graph. -2. Track discovery and low-link values for each node: -- Discovery Time: Order in which a node is visited. -- Low-Link Value: The lowest discovery time reachable from that node. -3. Nodes are pushed to a stack upon their initial discovery and are considered part of an SCC until all reachable nodes are processed. -4. After visiting all nodes from a given node, if the node is the root of an SCC (where its discovery time equals its low-link value), all nodes in the SCC are popped from the stack. - -**Time Complexity** -- O(V + E) where V is the number of vertices and E is the number of edges. This efficiency arises because each node and edge is visited only once. - -![Graph Diagram](./algorithm.png "Example of Graph for Tarjan's Algorithm") - - -## Pseudocode - -```C -function tarjansSCC(graph): - Initialize discovery and low arrays to -1 - Initialize an empty stack and set index = 0 - For each vertex v in graph: - if v is not visited: - DFS(v) - end function - -function DFS(v): - Set discovery[v] = low[v] = index; index++ - Push v to the stack - For each neighbor u of v: - if u is not visited: - DFS(u) - Set low[v] = min(low[v], low[u]) - else if u is in the stack: - Set low[v] = min(low[v], discovery[u]) - end loop - - if discovery[v] == low[v]: - While stack top is not v: - Pop vertex from stack and add to current SCC - Add v to SCC - end if -end function -``` - -## Example Code in C++ -Here’s a C++ implementation of Tarjan's Algorithm: - -```Cpp -#include -#include -#include -using namespace std; - -class TarjansAlgorithm { -private: - vector> adj; - vector discovery, low; - stack stk; - vector onStack; - int time = 0, V; - - void DFS(int v) { - discovery[v] = low[v] = ++time; - stk.push(v); - onStack[v] = true; - - for (int u : adj[v]) { - if (discovery[u] == -1) { // u is not visited - DFS(u); - low[v] = min(low[v], low[u]); - } else if (onStack[u]) { - low[v] = min(low[v], discovery[u]); - } - } - - if (discovery[v] == low[v]) { - cout << "SCC: "; - while (true) { - int u = stk.top(); stk.pop(); - onStack[u] = false; - cout << u << " "; - if (u == v) break; - } - cout << endl; - } - } - -public: - TarjansAlgorithm(int vertices) : V(vertices), adj(vertices), discovery(vertices, -1), low(vertices, -1), onStack(vertices, false) {} - - void addEdge(int v, int u) { - adj[v].push_back(u); - } - - void findSCCs() { - for (int i = 0; i < V; ++i) - if (discovery[i] == -1) - DFS(i); - } -}; - -int main() { - TarjansAlgorithm g(5); - g.addEdge(1, 0); - g.addEdge(0, 2); - g.addEdge(2, 1); - g.addEdge(0, 3); - g.addEdge(3, 4); - cout << "Strongly Connected Components:\n"; - g.findSCCs(); - return 0; -} -``` - -## Explanation of the Code -1. DFS Traversal: The code initiates a DFS for each unvisited node, updating discovery and low values. -2. Stack Operations: Nodes are added to the stack when first visited. If a node completes processing and is the root of an SCC, nodes are popped from the stack until the root node is reached. -3. Printing SCCs: When an SCC is identified (where discovery[v] == low[v]), the SCC is printed. - -## Example Walkthrough -Consider a graph with vertices and edges as shown: - -1. Vertices are visited according to their DFS discovery time. -2. Each SCC is printed as it's identified when discovery == low for that root node. - -### Diagram of SCCs -Below is an example directed graph that Tarjan’s Algorithm would traverse: - -- Nodes: 0, 1, 2, 3, 4 -- Edges: 1 -> 0, 0 -> 2, 2 -> 1, 0 -> 3, 3 -> 4 - -For this graph, SCCs are: -- SCC 1: {0, 1, 2} -- SCC 2: {3} -- SCC 3: {4} - -## Real-World Example -Consider using Tarjan's Algorithm in a call graph of a large software application to identify isolated functional units. Each SCC in this call graph could represent a module that can operate independently or an area where cyclic dependencies might be managed. diff --git a/docs/Tarjan's Algorithm/algorithm.png b/docs/Tarjan's Algorithm/algorithm.png deleted file mode 100644 index 24bec33772b5c70f7ecc0e96ddf4a24702322420..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105711 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%0D;7v=li<3Q)tv|X@wXKsWlRp40&*~aQEKR!Rd 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 1 and key < root.left.key: - return self.right_rotate(root) - # Right Right Case - if balance < -1 and key > root.right.key: - return self.left_rotate(root) - # Left Right Case - if balance > 1 and key > root.left.key: - root.left = self.left_rotate(root.left) - return self.right_rotate(root) - # Right Left Case - if balance < -1 and key < root.right.key: - root.right = self.right_rotate(root.right) - return self.left_rotate(root) - - return root - - def get_height(self, root): - if not root: - return 0 - return root.height - - def get_balance(self, root): - if not root: - return 0 - return self.get_height(root.left) - self.get_height(root.right) - - def right_rotate(self, z): - y = z.left - T3 = y.right - y.right = z - z.left = T3 - z.height = 1 + max(self.get_height(z.left), self.get_height(z.right)) - y.height = 1 + max(self.get_height(y.left), self.get_height(y.right)) - return y - - def left_rotate(self, z): - y = z.right - T2 = y.left - y.left = z - z.right = T2 - z.height = 1 + max(self.get_height(z.left), self.get_height(z.right)) - y.height = 1 + max(self.get_height(y.left), self.get_height(y.right)) - return y -``` - diff --git a/docs/Trees/B-Trees.md b/docs/Trees/B-Trees.md deleted file mode 100644 index 968e23651..000000000 --- a/docs/Trees/B-Trees.md +++ /dev/null @@ -1,268 +0,0 @@ ---- -id: b-tree -title: B-Tree -sidebar_label: B-Tree -sidebar_position: 3 -description: "A B-Tree is a self-balancing tree data structure that maintains sorted data and allows for efficient insertion, deletion, and search operations." -tags: [Data Structures, B-Tree, Algorithms] ---- - -# B-Tree - -## Overview -A **B-Tree** is a self-balancing tree data structure that maintains sorted data and allows for efficient operations such as insertion, deletion, and search. B-Trees are particularly well-suited for systems that read and write large blocks of data, such as databases and filesystems. They ensure that the tree remains balanced, allowing for operations to be performed in **O(log n)** time. - -## Features -- **Balanced Structure**: All leaf nodes are at the same level, ensuring that the tree remains balanced. -- **Node Capacity**: Each node can contain a variable number of keys and children, defined by a minimum degree \( t \). -- **Dynamic Growth**: B-Trees can grow and shrink dynamically as keys are added or removed, maintaining balance without requiring rebalancing operations. - -## Table of Contents -- [How It Works](#how-it-works) -- [Operations](#operations) - - [Insertion](#insertion) - - [Deletion](#deletion) - - [Search](#search) - - [Traversal](#traversal) -- [Code Example](#code-example) -- [Applications](#applications) -- [Time Complexity](#time-complexity) - -## How It Works -In a B-Tree: -- Each node can contain multiple keys and children, allowing for a more compact representation of data. -- The tree maintains a balanced structure where the number of keys in each node is kept within a defined range, ensuring efficient operations. - -### Balancing Techniques -1. **Node Splitting**: When a node becomes full, it is split into two nodes, and the median key is promoted to the parent node. -2. **Merging Nodes**: If a node becomes underflowed after deletion, it may borrow a key from a sibling or merge with a sibling. - -## Operations - -### Insertion -To insert a new value: -1. Start at the root and find the appropriate leaf node. -2. If the leaf node has fewer than \( 2t - 1 \) keys, insert the key directly. -3. If the leaf node is full, split the node and promote the median key to the parent. - -### Deletion -Deletion is performed as follows: -1. Locate the key in the tree. -2. If the key is in a leaf node, remove it directly. -3. If the key is in an internal node, replace it with its predecessor or successor and delete that key. -4. If the node becomes underflowed, perform necessary operations to maintain the B-Tree properties. - -### Search -Search for a value follows a similar mechanism: -1. Start from the root and traverse the tree based on comparisons until the value is found or a `null` pointer is reached. - -### Traversal -1. **In-Order Traversal**: Left children → Current node → Right children. -2. **Pre-Order Traversal**: Current node → Left children → Right children. -3. **Post-Order Traversal**: Left children → Right children → Current node. - -## Code Example - -### C++ Example (B-Tree): - -```cpp -#include -using namespace std; - -class BTreeNode { - int *keys; - int t; - BTreeNode **C; - int n; - bool leaf; - -public: - BTreeNode(int _t, bool _leaf); - - void insertNonFull(int k); - void splitChild(int i, BTreeNode *y); - void traverse(); - - BTreeNode *search(int k); - - friend class BTree; -}; - -class BTree { - BTreeNode *root; - int t; - -public: - BTree(int _t) { - root = NULL; - t = _t; - } - - void traverse() { - if (root != NULL) root->traverse(); - } - - BTreeNode* search(int k) { - return (root == NULL) ? NULL : root->search(k); - } - - void insert(int k); -}; - -BTreeNode::BTreeNode(int t1, bool leaf1) { - t = t1; - leaf = leaf1; - - keys = new int[2*t-1]; - C = new BTreeNode *[2*t]; - n = 0; -} - -void BTreeNode::traverse() { - int i; - for (i = 0; i < n; i++) { - if (leaf == false) - C[i]->traverse(); - cout << " " << keys[i]; - } - - if (leaf == false) - C[i]->traverse(); -} - -BTreeNode *BTreeNode::search(int k) { - int i = 0; - while (i < n && k > keys[i]) - i++; - - if (keys[i] == k) - return this; - - if (leaf == true) - return NULL; - - return C[i]->search(k); -} - -void BTree::insert(int k) { - if (root == NULL) { - root = new BTreeNode(t, true); - root->keys[0] = k; - root->n = 1; - } else { - if (root->n == 2*t-1) { - BTreeNode *s = new BTreeNode(t, false); - s->C[0] = root; - s->splitChild(0, root); - - int i = 0; - if (s->keys[0] < k) - i++; - s->C[i]->insertNonFull(k); - - root = s; - } else - root->insertNonFull(k); - } -} - -void BTreeNode::insertNonFull(int k) { - int i = n-1; - - if (leaf == true) { - while (i >= 0 && keys[i] > k) { - keys[i+1] = keys[i]; - i--; - } - - keys[i+1] = k; - n = n+1; - } else { - while (i >= 0 && keys[i] > k) - i--; - - if (C[i+1]->n == 2*t-1) { - splitChild(i+1, C[i+1]); - - if (keys[i+1] < k) - i++; - } - C[i+1]->insertNonFull(k); - } -} - -void BTreeNode::splitChild(int i, BTreeNode *y) { - BTreeNode *z = new BTreeNode(y->t, y->leaf); - z->n = t - 1; - - for (int j = 0; j < t-1; j++) - z->keys[j] = y->keys[j+t]; - - if (y->leaf == false) { - for (int j = 0; j < t; j++) - z->C[j] = y->C[j+t]; - } - - y->n = t - 1; - - for (int j = n; j >= i+1; j--) - C[j+1] = C[j]; - - C[i+1] = z; - - for (int j = n-1; j >= i; j--) - keys[j+1] = keys[j]; - - keys[i] = y->keys[t-1]; - - n = n + 1; -} - -int main() { - BTree t(3); - t.insert(10); - t.insert(20); - t.insert(5); - t.insert(6); - t.insert(12); - t.insert(30); - t.insert(7); - t.insert(17); - - cout << "Traversal of the constructed tree is "; - t.traverse(); - - return 0; -} - -``` -### Output: -``` -Traversal of the constructed tree is 5 6 7 10 12 17 20 30 -``` -## Applications -``` -- **Databases**: B-Trees are widely used in database systems to maintain sorted data, allowing for efficient retrieval, insertion, and deletion of records. -- **File Systems**: Many file systems use B-Trees to manage file directories and metadata, enabling quick access to files and efficient storage management. -- **Indexing**: B-Trees are used in indexing data structures for search engines and databases, allowing for fast lookups and range queries. -- **Memory Management**: They can efficiently manage free memory blocks in systems, helping to allocate and deallocate memory dynamically. -- **Auto-completion**: B-Trees are utilized in applications that require predictive text suggestions, enabling quick access to a large set of possible completions. -``` - -## Time Complexity -``` - -| Operation | Average Time | Worst Case Time | -|--------------|--------------|-----------------| -| **Search** | O(log n) | O(n) | -| **Insertion**| O(log n) | O(n) | -| **Deletion** | O(log n) | O(n) | -| **Traversal**| O(n) | O(n) | -``` - -> **Note**: The worst-case time complexity arises in unbalanced cases; however, B-Trees are designed to remain balanced, maintaining an average of O(log n) for most operations. - -## Conclusion -``` -B-Trees are essential data structures for efficient data management, particularly in applications that require dynamic datasets. Their ability to maintain balance ensures fast search, insertion, and deletion operations, making them ideal for databases, file systems, and other applications where performance is critical. The versatility and efficiency of B-Trees make them a fundamental choice for managing large volumes of data. -``` diff --git a/docs/Trees/Expression-tree.md b/docs/Trees/Expression-tree.md deleted file mode 100644 index 08aa03608..000000000 --- a/docs/Trees/Expression-tree.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -id: expression-tree -title: Expression-tree -sidebar_label: Expression-tree -description: "An Expression Tree is a binary tree representing expressions with operators as internal nodes and operands as leaves." -tags: [dsa, algorithms, trees] ---- - -### Definition: -An Expression Tree is a binary tree in which each internal node represents an operator, and each leaf node represents an operand. By performing an inorder traversal of this tree, the corresponding infix expression can be retrieved. This structure is useful for evaluating expressions and converting between different notations (infix, postfix, prefix). - -### Problem Statement: -Given a postfix expression, construct an expression tree where: -- Operators are stored as internal nodes. -- Operands are stored as leaves. - -### The program should support: -1. **Tree Construction**: Build the expression tree from a postfix expression. -2. **Inorder Traversal**: Traverse the tree in inorder to display the infix expression. - -### Algorithm - -1. Use a stack to construct the tree from the postfix expression. -2. For each character in the postfix expression: - - If the character is an operand, create a node and push it onto the stack. - - If the character is an operator, pop two nodes from the stack, create a new node for the operator, and set the popped nodes as its left and right children. -3. The final node remaining in the stack becomes the root of the expression tree. - -### Structure: -1. **Node Structure**: -Each node represents an element (operator or operand) in the expression: - - `value`: Stores either an operand or operator. - - `left`: Pointer to the left child. - - `right`: Pointer to the right child. - -2. **Functions** - - `isOperator(char c)`: Checks if a character is an operator. - - `constructExpressionTree(const std::string& postfix)`: Builds the expression tree from a postfix expression. - - `inorderTraversal(Node* root)`: Performs an inorder traversal of the expression tree to display the infix expression with parentheses for operator precedence. - -3. **Main Function** - - Takes a postfix expression as input. - - Constructs the tree using `constructExpressionTree()`. - - Executes `inorderTraversal()` to display the infix expression. - -### Time Complexity -- Each function runs in `O(n)` time, where `n` is the number of characters in the postfix expression. Building the tree and performing inorder traversal both require visiting each node once. - -### Space Complexity -- The space complexity is `O(n)` due to the expression tree nodes and the stack used during construction. - -### Sample Input: -Enter postfix expression: PQR*-X/ - -### Sample Output: -Infix expression: ((P-(Q*R))/X) - - -### C++ Implementation: - -```cpp - -#include -#include -#include - -// Node structure for expression tree -struct Node { - char value; - Node* left; - Node* right; - - Node(char val) : value(val), left(nullptr), right(nullptr) {} -}; - -// Function to check if a character is an operator -bool isOperator(char c) { - return (c == '+' || c == '-' || c == '*' || c == '/'); -} - -// Function to construct an expression tree from a postfix expression -Node* constructExpressionTree(const std::string& postfix) { - std::stack stack; - - for (char ch : postfix) { - if (isOperator(ch)) { - Node* node = new Node(ch); - // Pop two operands for the operator - node->right = stack.top(); - stack.pop(); - node->left = stack.top(); - stack.pop(); - stack.push(node); - } else { - // Operand, push to stack - stack.push(new Node(ch)); - } - } - - // The root of the expression tree - return stack.top(); -} - -// Inorder traversal of the expression tree to get the infix expression -void inorderTraversal(Node* node) { - if (!node) return; - - // Print left operand with parentheses for correct infix form - if (isOperator(node->value)) std::cout << "("; - - inorderTraversal(node->left); - std::cout << node->value; - inorderTraversal(node->right); - - if (isOperator(node->value)) std::cout << ")"; -} - -int main() { - std::string postfix; - std::cout << "Enter postfix expression: "; - std::cin >> postfix; - - Node* root = constructExpressionTree(postfix); - - std::cout << "Infix expression: "; - inorderTraversal(root); - std::cout << std::endl; - - return 0; -} - - -``` diff --git a/docs/Trees/Heap-tree.md b/docs/Trees/Heap-tree.md deleted file mode 100644 index f263586c3..000000000 --- a/docs/Trees/Heap-tree.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: heap-tree-algorithm -title: Heap Tree Algorithm -sidebar_label: Heap Tree Algorithm -sidebar_position: 2 -description: "The Heap Tree is a specialized binary tree used for efficient priority queue operations and sorting." -tags: [Data Structures, heap-tree-algorithm, Priority Queue, Sorting, Algorithms] ---- - -# Heap Tree Algorithm - -## Overview -A Heap Tree is a specialized binary tree-based data structure that satisfies the heap property. It is widely used in implementing priority queues and for heap sort algorithms. The heap property ensures that the parent node is always greater than or equal to (in a max-heap) or less than or equal to (in a min-heap) its child nodes. - -## Introduction -A Heap Tree can be either a max-heap or a min-heap: -- **Max-Heap**: The value of each node is greater than or equal to the values of its children. -- **Min-Heap**: The value of each node is less than or equal to the values of its children. - -Heap Trees are typically implemented using arrays for efficient indexing and manipulation. - -## Characteristics of Heap Tree Algorithm -- **Efficient Priority Queue Operations**: Supports efficient insertion, deletion, and retrieval of the highest (or lowest) priority element. -- **Complete Binary Tree**: Always maintains a complete binary tree structure, ensuring balanced tree properties. -- **Heap Property**: Ensures that the tree satisfies the heap property, making it suitable for priority-based operations. - -## How the Heap Tree Algorithm Works -1. **Insertion**: - - Add the new element at the end of the tree (or array). - - Restore the heap property by "bubbling up" the new element to its correct position. - -2. **Deletion**: - - Remove the root element (highest or lowest priority). - - Replace the root with the last element in the tree (or array). - - Restore the heap property by "bubbling down" the replaced element to its correct position. - -3. **Heapify**: - - Convert an arbitrary array into a heap by iteratively applying the heap property from the bottom up. - -## Step-by-Step Execution - -Here’s an example of how the Heap Tree Algorithm works on a small dataset: - -### Max-Heap Example - -1. **Initial Array**: [4, 10, 3, 5, 1] -2. **Build Max-Heap**: - - Start from the last non-leaf node and apply the heap property. - - Resulting Max-Heap: [10, 5, 3, 4, 1] - - -```mermaid -graph TB - A((4)) --> B((10)) - A --> C((3)) - B --> D((5)) - B --> E((1)) -``` - -### Min-Heap Example - -1. **Initial Array**: [4, 10, 3, 5, 1] -2. **Build Min-Heap**: - - Start from the last non-leaf node and apply the heap property. - - Resulting Min-Heap: [1, 4, 3, 10, 5] - -```mermaid -graph TB - A((1)) --> B((4)) - A --> C((3)) - B --> D((10)) - B --> E((5)) -``` -## Execution Steps -1. **Insertion**: - - Add the element to the end of the array. - - Bubble up to maintain the heap property. - -2. **Deletion**: - - Remove the root element. - - Replace the root with the last element. - - Bubble down to maintain the heap property. - -## Time Complexity -- Insertion: **O(log n)** due to the bubbling up process. -- Deletion: **O(log n)** due to the bubbling down process. -- Building a Heap: **O(n)** using the bottom-up approach. - -## Applications -- **Priority Queues**: Efficiently manage and retrieve elements based on priority. -- **Heap Sort**: An efficient comparison-based sorting algorithm. -- **Graph Algorithms**: Used in algorithms like Dijkstra's shortest path and Prim's minimum spanning tree. - -## Pseudocode - -1. **Insert an element**: - - Add the element to the end of the array. - - Bubble up to maintain the heap property. - -2. **Delete the root**: - - Replace the root with the last element. - - Bubble down to maintain the heap property. - -3. **Heapify an array**: - - Start from the last non-leaf node and apply the heap property. - -## Advantages of Heap Tree Algorithm -- **Efficient Priority Management**: Ideal for applications requiring dynamic priority management. -- **Balanced Structure**: Maintains a complete binary tree, ensuring balanced operations. -- **Versatile**: Can be used for both max-heap and min-heap implementations. - -## Limitations -- **Not Suitable for Search Operations**: Inefficient for searching arbitrary elements compared to balanced search trees. -- **Fixed Structure**: Requires a complete binary tree structure, limiting flexibility. - -# Heap Tree vs. Binary Search Tree - -| Feature | Heap Tree | Binary Search Tree | -|-----------------|-------------------------------------------------------------------------|-----------------------------------------------------------| -| **Data Storage** | Stores elements to satisfy the heap property | Stores elements to satisfy the binary search property | -| **Priority Operations** | Efficient insertion, deletion, and retrieval of priority elements | Efficient search, insertion, and deletion of arbitrary elements | -| **Time Complexity** | O(log n) for insertion and deletion | O(log n) for search, insertion, and deletion (balanced) | -| **Use Case** | Used for priority queues and heap sort | Used for dynamic set operations and searching | - -## Conclusion - -The Heap Tree Algorithm is a fundamental data structure for efficient priority queue operations and sorting. Its balanced structure and heap property make it essential for applications in priority management and sorting algorithms. Understanding Heap Trees is crucial for anyone working in data structures and algorithm design. \ No newline at end of file diff --git a/docs/Trees/Practice Problems.md b/docs/Trees/Practice Problems.md deleted file mode 100644 index a2e70e75a..000000000 --- a/docs/Trees/Practice Problems.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: practice-problems-on-trees -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 16 -Description: Here are some practice problems for Tree Data Structure divided into topic-wise and difficulty wise. -tags: [DSA, algorithms,Trees, dsa] ---- - -### 1. Easy Level - - [Binary Tree Inorder Traversal]( https://leetcode.com/problems/binary-tree-inorder-traversal/description/) - - [Binary Tree Preorder Traversal]( https://leetcode.com/problems/binary-tree-preorder-traversal/description/) - - [Binary Tree Postorder Traversal]( https://leetcode.com/problems/binary-tree-postorder-traversal/description/) - - [Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/) - - [Same Tree]( https://leetcode.com/problems/same-tree/description/) - - [Invert Binary Tree]( https://leetcode.com/problems/invert-binary-tree/description/) - - [Symmetric Tree]( https://leetcode.com/problems/symmetric-tree/description/) - - [Path Sum]( https://leetcode.com/problems/path-sum/description/) - - [Count Complete Tree Nodes]( https://leetcode.com/problems/count-complete-tree-nodes/description/) - - [Average of Levels in Binary Tree]( https://leetcode.com/problems/average-of-levels-in-binary-tree/description/) - - [Minimum Absolute Difference in BST]( https://leetcode.com/problems/minimum-absolute-difference-in-bst/description/) - - [Search in a Binary Search Tree]( https://leetcode.com/problems/search-in-a-binary-search-tree/description/) - - [Leaf-Similar Trees]( https://leetcode.com/problems/leaf-similar-trees/description/) - ---- - -### 2. Medium Level - - - [Construct Binary Tree from Preorder and Inorder Traversal]( https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/) - - [Construct Binary Tree from Inorder and Postorder Traversal]( https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/) - - [Populating Next Right Pointers in Each Node II]( https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/description/) - - [Flatten Binary Tree to Linked List]( https://leetcode.com/problems/flatten-binary-tree-to-linked-list/description/) - - [Sum Root to Leaf Numbers]( https://leetcode.com/problems/sum-root-to-leaf-numbers/description/) - - [Binary Search Tree Iterator]( https://leetcode.com/problems/binary-search-tree-iterator/description/) - - [Lowest Common Ancestor of a Binary Tree]( https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/) - - [Binary Tree Right Side View]( https://leetcode.com/problems/binary-tree-right-side-view/description/) - - [Binary Tree Level Order Traversal]( https://leetcode.com/problems/binary-tree-level-order-traversal/description/) - - [Binary Tree Zigzag Level Order Traversal]( https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/description/) - - [Kth Smallest Element in a BST]( https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/) -- [Validate Binary Search Tree]( https://leetcode.com/problems/validate-binary-search-tree/description/) -- [Count Good Nodes in Binary Tree]( https://leetcode.com/problems/count-good-nodes-in-binary-tree/description/) - - [Path Sum III]( https://leetcode.com/problems/path-sum-iii/description/) - -[Delete Node in a BST]( https://leetcode.com/problems/delete-node-in-a-bst/description/) ---- -### 3. Hard Level - - - [Binary Tree Maximum Path Sum]( https://leetcode.com/problems/binary-tree-maximum-path-sum/description) ---- diff --git a/docs/Trees/Sum-tree.md b/docs/Trees/Sum-tree.md deleted file mode 100644 index fe303c135..000000000 --- a/docs/Trees/Sum-tree.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: sum-tree -title: Sum-tree -sidebar_label: Sum-tree -description: "A Sum Tree is a binary tree where each node's value is equal to the sum of the values of its left and right children, with the property holding true for all nodes in the tree." -tags: [dsa, algorithms, tree] ---- - -### Problem Statement: -Given a binary tree, the task is to check if it is a Sum Tree. A Sum Tree is a Binary Tree where the value of a node is equal to the sum of the nodes present in its left subtree and right subtree. An empty tree is Sum Tree and the sum of an empty tree can be considered as 0. A leaf node is also considered a Sum Tree. - -### Appraoch -The approach to checking if a binary tree is a Sum Tree involves recursively traversing the tree, where each node checks if it is `nullptr` or a leaf. The algorithm computes the sums of the left and right subtrees, then verifies if the current node's value equals the combined sum of its children. If all nodes satisfy this condition, the tree is classified as a Sum Tree; otherwise, it is not. - -### Algorithm Steps: - -1. Pass the root node of the binary tree to the Sum Tree check function. -2. If the node is `nullptr`, return `true` with a sum of 0; if it's a leaf, return `true` with its value. -3. Recursively call the function for the left child and right child to get their sums and check for Sum Tree property. -4. Add the values of the left and right subtree sums to the current node’s value. -5. Return `true` if the current node's value equals the sum of its left and right subtree sums; otherwise, return `false`. -6. If the root’s check passes, return `true` ; if any node fails, return `false`. - -### Time Complexity: -- The time complexity of checking if a binary tree is a Sum Tree is `O(n)`, where `n` is the number of nodes in the tree. This is because the algorithm visits each node exactly once to compute sums and check the Sum Tree property, resulting in linear traversal. - -### Space Complexity: -- The space complexity of the algorithm for checking if a binary tree is a Sum Tree is `O(h)`, where `h` is the height of the tree, due to the recursive call stack. In the worst case, this can be `O(n)` for a skewed tree, while for a balanced tree, it is `O(log n)`. - -### Sample Input: -Insert: 26 -Insert: 10 -Insert: 3 -Insert: 4 -Insert: 6 -Insert: 3 - -### Sample Output: -The binary tree is a Sum Tree. - -### Explanation of Sample: - -- The binary tree's structure shows that each node has a specific value, represented visually with branches connecting parent and child nodes. -- Each node’s value must equal the sum of its left and right children's values for the tree to qualify as a Sum Tree. -- In this example, the root node (26) equals the sum of its children (10 + 3), and the left child (10) equals (4 + 6). -- Since all nodes satisfy this condition, the conclusion is that the binary tree is indeed a Sum Tree. - -### C++ Implementation: - -```cpp -#include -struct TreeNode { - int value; - TreeNode* left; - TreeNode* right; - TreeNode(int val) : value(val), left(nullptr), right(nullptr) {} -}; - -bool isSumTree(TreeNode* root, int& sum) { - // An empty tree is a Sum Tree - if (root == nullptr) { - sum = 0; - return true; - } - // Leaf nodes are Sum Trees - if (root->left == nullptr && root->right == nullptr) { - sum = root->value; - return true; - } - int leftSum = 0, rightSum = 0; - // Recursively check the left and right subtrees - bool leftIsSumTree = isSumTree(root->left, leftSum); - bool rightIsSumTree = isSumTree(root->right, rightSum); - // The current node's value should equal the sum of left and right subtrees - sum = leftSum + rightSum + root->value; - return leftIsSumTree && rightIsSumTree && (root->value == leftSum + rightSum); -} -// Helper function to initiate the check -bool isSumTree(TreeNode* root) { - int sum = 0; - return isSumTree(root, sum); -} - -int main() { - // Creating a binary tree - TreeNode* root = new TreeNode(26); - root->left = new TreeNode(10); - root->right = new TreeNode(3); - root->left->left = new TreeNode(4); - root->left->right = new TreeNode(6); - root->right->right = new TreeNode(3); - if (isSumTree(root)) { - std::cout << "The binary tree is a Sum Tree." << std::endl; - } else { - std::cout << "The binary tree is NOT a Sum Tree." << std::endl; - } - return 0; -} - -``` diff --git a/docs/Trees/Trees Practice Problems.md b/docs/Trees/Trees Practice Problems.md deleted file mode 100644 index ebdd228bf..000000000 --- a/docs/Trees/Trees Practice Problems.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -id: tree-practice-problems -title: Practice Problems on Trees -sidebar_label: Practice Problems - -description: "In this post, we'll provide a list of curated practice problems on Trees from platforms like LeetCode and GeeksforGeeks. Trees are fundamental data structures in computer science, and practicing these problems will help strengthen your understanding of tree concepts and algorithms." - -tags: [dsa, algorithms, trees, practice-problems] ---- - -## Trees Practice Problems - -To start solving tree problems, first ensure you understand the basic tree concepts such as traversals, node structures, and common properties. Begin by practicing easy problems to build your confidence, and gradually move to medium and hard problems as you become more comfortable. - -### Easy Problems - -- [Binary Tree Preorder Traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/) -- [Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) -- [Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/) -- [Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) -- [Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) -- [Same Tree](https://leetcode.com/problems/same-tree/) -- [Symmetric Tree](https://leetcode.com/problems/symmetric-tree/) - -### Medium Problems - -- [Check if the Binary Tree is Height-Balanced](https://leetcode.com/problems/balanced-binary-tree/) -- [Diameter of Binary Tree](https://leetcode.com/problems/diameter-of-binary-tree/) -- [Height of a Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) -- [Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) -- [Zigzag Level Order Traversal](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) -- [Boundary Traversal of Binary Tree](https://leetcode.com/problems/boundary-of-binary-tree/) -- [Vertical Order Traversal of Binary Tree](https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree/) -- [Top View of Binary Tree](https://practice.geeksforgeeks.org/problems/top-view-of-binary-tree/1) -- [Bottom View of Binary Tree](https://practice.geeksforgeeks.org/problems/bottom-view-of-binary-tree/1) - -### Hard Problems - -- [Root to Node Path in Binary Tree](https://bit.ly/3QA600D) -- [Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) -- [Maximum Width of Binary Tree](https://leetcode.com/problems/maximum-width-of-binary-tree/) -- [Check for Children Sum Property](https://bit.ly/3dEr73g) -- [Print All Nodes at Distance K in a Binary Tree](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/) -- [Minimum Time to Burn the Binary Tree from a Node](https://bit.ly/3wcg7k1) -- [Count Total Nodes in a Complete Binary Tree](https://leetcode.com/problems/count-complete-tree-nodes/) -- [Requirements Needed to Construct a Unique Binary Tree | Theory](https://bit.ly/3UVCR1U) -- [Construct Binary Tree from Inorder and Preorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) - diff --git a/docs/Trees/Types of Trees.md b/docs/Trees/Types of Trees.md deleted file mode 100644 index dd83f5ff0..000000000 --- a/docs/Trees/Types of Trees.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -id: types-of-trees -title: Types of Trees -sidebar_label: Types of Trees - -description: "This document provides an overview of various types of trees in computer science. Understanding these tree types is essential for selecting the right data structure for your specific needs." - -tags: [dsa, trees, data-structures] ---- - -## Types of Trees - -### 1. Binary Tree -A tree structure in which each node has at most two children, referred to as the left child and the right child. It is the simplest form of a tree and serves as the foundation for more complex tree structures. - -### 2. Binary Search Tree (BST) -A binary tree in which each node follows the property that the left child contains only nodes with values less than the parent node, and the right child contains only nodes with values greater than the parent node. This property allows for efficient searching, insertion, and deletion operations. - -### 3. Balanced Trees -Balanced trees maintain their height in a logarithmic range to ensure efficient operations. Common types include: -- **AVL Tree**: A self-balancing binary search tree where the difference in heights between the left and right subtrees of any node is at most one. -- **Red-Black Tree**: A binary search tree with an extra bit of storage for each node to maintain balance during insertions and deletions, ensuring that no path from the root to a leaf is more than twice as long as any other such path. - -### 4. Complete Binary Tree -A binary tree in which all levels are fully filled except possibly for the last level, which is filled from left to right. This structure is useful for implementing heaps. - -### 5. Full Binary Tree -A binary tree in which every node other than the leaves has two children. This property makes full binary trees a special case of complete binary trees. - -### 6. N-ary Tree -A tree in which a node can have at most N children. N-ary trees are generalizations of binary trees and are often used to represent hierarchical data. - -### 7. Trie (Prefix Tree) -A specialized tree structure used for storing associative data structures, particularly strings. Each node represents a single character of a key, and paths down the tree represent prefixes of keys. - -### 8. Segment Tree -A tree data structure used for storing intervals or segments. It allows querying which segments contain a given point and is commonly used in scenarios involving range queries. - -### 9. B-tree -A self-balancing search tree that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time. B-trees are commonly used in databases and file systems. - -### 10. B+ Tree -An extension of the B-tree that maintains sorted data and allows for efficient range queries. In a B+ tree, all values are stored at the leaf level, making it particularly suitable for database systems. diff --git a/docs/Trees/balanced-tree.md b/docs/Trees/balanced-tree.md deleted file mode 100644 index 1b9ce8456..000000000 --- a/docs/Trees/balanced-tree.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -id: balanced-tree -title: Balanced Tree -sidebar_label: Balanced Tree -sidebar_position: 2 -description: "A Balanced Tree is a data structure that maintains a balanced height to ensure efficient operations." -tags: [Data Structures, Balanced Tree, Algorithms] ---- - -# Balanced Tree - -## Overview -A **Balanced Tree** is a data structure that automatically keeps its height (depth) small in comparison to the number of nodes. This ensures that operations such as insertion, deletion, and search can be performed efficiently, typically in **O(log n)** time. Common types of balanced trees include **AVL trees**, **Red-Black trees**, and **B-trees**. - -## Features -- **Height-Balancing**: Maintains a balanced height to ensure operations remain efficient. -- **Self-Balancing**: Automatically adjusts structure during insertion and deletion to maintain balance. -- **Binary Tree Structure**: Often structured as a binary tree, but can extend to N-ary trees. - -## Table of Contents -- [How It Works](#how-it-works) -- [Operations](#operations) - - [Insertion](#insertion) - - [Deletion](#deletion) - - [Search](#search) - - [Traversal](#traversal) -- [Code Example](#code-example) -- [Applications](#applications) -- [Time Complexity](#time-complexity) - -## How It Works -In a balanced tree: -- The tree maintains a balanced structure where the difference in height between left and right subtrees of any node is minimized. -- Rotations are used to adjust the structure during insertion and deletion to maintain balance. - -### Balancing Techniques -1. **Rotations**: Adjust the tree structure to ensure balance. - - **Left Rotation**: Used when the right subtree becomes too heavy. - - **Right Rotation**: Used when the left subtree becomes too heavy. - -2. **Rebalancing**: After insertion or deletion, the tree is checked and rebalanced if necessary. - -## Operations - -### Insertion -To insert a new value: -1. Insert the value using standard BST insertion rules. -2. Check for balance and apply rotations if needed. - -### Deletion -Deletion is performed in similar ways as a BST, with additional steps to maintain balance: -1. Remove the node as in a standard BST. -2. Check for balance and apply rotations if needed. - -### Search -Search for a value follows the same mechanism as in a BST: -1. Start from the root and traverse left or right based on comparisons until the value is found or a `null` pointer is reached. - -### Traversal -1. **In-Order Traversal**: Left subtree → Root → Right subtree. -2. **Pre-Order Traversal**: Root → Left subtree → Right subtree. -3. **Post-Order Traversal**: Left subtree → Right subtree → Root. - -## Code Example - -### Python Example (AVL Tree): - -```python -class Node: - def __init__(self, key): - self.left = None - self.right = None - self.value = key - self.height = 1 - -class AVLTree: - def insert(self, root, key): - if not root: - return Node(key) - elif key < root.value: - root.left = self.insert(root.left, key) - else: - root.right = self.insert(root.right, key) - - root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right)) - balance = self.getBalance(root) - - # Left Left Case - if balance > 1 and key < root.left.value: - return self.rightRotate(root) - - # Right Right Case - if balance < -1 and key > root.right.value: - return self.leftRotate(root) - - # Left Right Case - if balance > 1 and key > root.left.value: - root.left = self.leftRotate(root.left) - return self.rightRotate(root) - - # Right Left Case - if balance < -1 and key < root.right.value: - root.right = self.rightRotate(root.right) - return self.leftRotate(root) - - return root - - def leftRotate(self, z): - y = z.right - T2 = y.left - - y.left = z - z.right = T2 - - z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) - y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) - - return y - - def rightRotate(self, z): - y = z.left - T3 = y.right - - y.right = z - z.left = T3 - - z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) - y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) - - return y - - def getHeight(self, root): - if not root: - return 0 - return root.height - - def getBalance(self, root): - if not root: - return 0 - return self.getHeight(root.left) - self.getHeight(root.right) - - def inorder(self, root): - if root: - self.inorder(root.left) - print(root.value, end=" ") - self.inorder(root.right) - -# Example usage: -avl = AVLTree() -root = None -values = [10, 20, 30, 40, 50, 25] -for value in values: - root = avl.insert(root, value) - -print("Inorder traversal:") -avl.inorder(root) -``` - -### Output: -``` -Inorder traversal: -10 20 25 30 40 50 -``` - -## Applications -- **Databases**: Used for maintaining sorted data in databases where frequent insertions and deletions are required. -- **Memory Management**: Efficiently manage free memory blocks in systems. -- **Auto-completion**: Used in applications that require predictive text suggestions. - -## Time Complexity - -| Operation | Average Time | Worst Case Time | -|--------------|--------------|-----------------| -| **Search** | O(log n) | O(n) | -| **Insertion**| O(log n) | O(n) | -| **Deletion** | O(log n) | O(n) | -| **Traversal**| O(n) | O(n) | - -> **Note**: The worst-case time complexity arises in unbalanced cases; balanced trees maintain an average of O(log n) for most operations. - -## Conclusion -Balanced trees are crucial data structures for efficient data management, allowing for fast search, insertion, and deletion operations. They are essential for applications that require maintaining dynamic datasets. ---- diff --git a/docs/Trees/binary-search-tree.md b/docs/Trees/binary-search-tree.md deleted file mode 100644 index 7431bb309..000000000 --- a/docs/Trees/binary-search-tree.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -id: binary-search-tree -title: Binary Search Tree -sidebar_label: Binary Search Tree -sidebar_position: 4 -description: "A Binary Search Tree (BST) is a data structure that facilitates efficient searching, insertion, and deletion operations." -tags: [Data Structures, Binary Search Tree, Algorithms] ---- - -# Binary Search Tree (BST) - -## Overview -A **Binary Search Tree (BST)** is a binary tree where each node follows the binary search property: -- The left subtree of a node contains only nodes with values less than the node's key. -- The right subtree of a node contains only nodes with values greater than the node's key. -- Both left and right subtrees must also be binary search trees. - -BSTs are commonly used for searching, insertion, and deletion operations, all of which can be performed efficiently with an average time complexity of **O(log n)** for balanced trees. - -## Features -- **Efficient Search**: Lookup operations are performed in **O(log n)** time. -- **Insertion**: New elements are added in the correct position in **O(log n)** time. -- **Deletion**: Nodes can be removed while maintaining the binary search property. -- **Traversal**: In-order, pre-order, and post-order traversals are supported to explore tree elements. -- **Balanced Tree Variants**: Variants like AVL and Red-Black trees ensure balancing to maintain performance. - -## Table of Contents -- [How It Works](#how-it-works) -- [Operations](#operations) - - [Insertion](#insertion) - - [Deletion](#deletion) - - [Search](#search) - - [Traversal](#traversal) -- [Code Example](#code-example) -- [Applications](#applications) -- [Time Complexity](#time-complexity) - -## How It Works -In a BST: -- Each node contains a value (key), a pointer to the left child, and a pointer to the right child. -- The left subtree contains values smaller than the node’s key. -- The right subtree contains values greater than the node’s key. - -### Binary Search Property: -- For every node `N`, all values in the left subtree are smaller than `N`. -- All values in the right subtree are greater than `N`. - -## Operations - -### Insertion -To insert a new value: -1. Start at the root. -2. Recursively move to the left or right subtree depending on whether the new value is smaller or greater than the current node. -3. Insert the new value in the appropriate position once you find an empty subtree. - -### Deletion -Deletion is performed in three cases: -1. **Node has no children**: Simply remove the node. -2. **Node has one child**: Replace the node with its child. -3. **Node has two children**: Replace the node with its in-order predecessor or successor (the largest value in the left subtree or the smallest value in the right subtree). - -### Search -To search for a value: -1. Start at the root. -2. Recursively traverse left if the value is smaller, or right if it's larger. -3. Stop when you find the value or hit a `null` pointer. - -### Traversal -1. **In-Order Traversal**: Left subtree → Root → Right subtree. -2. **Pre-Order Traversal**: Root → Left subtree → Right subtree. -3. **Post-Order Traversal**: Left subtree → Right subtree → Root. - -## Code Example - -### Python Example: - -```python -class Node: - def __init__(self, key): - self.left = None - self.right = None - self.value = key - -class BinarySearchTree: - def __init__(self): - self.root = None - - def insert(self, key): - if self.root is None: - self.root = Node(key) - else: - self._insert(self.root, key) - - def _insert(self, node, key): - if key < node.value: - if node.left is None: - node.left = Node(key) - else: - self._insert(node.left, key) - else: - if node.right is None: - node.right = Node(key) - else: - self._insert(node.right, key) - - def inorder(self): - self._inorder(self.root) - - def _inorder(self, node): - if node: - self._inorder(node.left) - print(node.value, end=" ") - self._inorder(node.right) - -# Example usage: -bst = BinarySearchTree() -bst.insert(50) -bst.insert(30) -bst.insert(70) -bst.insert(20) -bst.insert(40) -bst.insert(60) -bst.insert(80) - -print("Inorder traversal:") -bst.inorder() -``` - -### Output: -``` -Inorder traversal: -20 30 40 50 60 70 80 -``` - -## Applications -- **Search Applications**: Used to store data for fast lookup, like phone directories or databases. -- **In-Memory Data**: Efficient for in-memory data representation where fast insertion, deletion, and lookup are required. -- **Sorting**: In-order traversal gives a sorted sequence of elements in the BST. - -## Time Complexity - -| Operation | Average Time | Worst Case Time (Unbalanced) | -|--------------|--------------|-----------------------------| -| **Search** | O(log n) | O(n) | -| **Insertion**| O(log n) | O(n) | -| **Deletion** | O(log n) | O(n) | -| **Traversal**| O(n) | O(n) | - -> **Note**: In a balanced BST (like AVL or Red-Black Tree), all operations maintain an O(log n) time complexity. In an unbalanced BST, the time complexity can degrade to O(n) in the worst case (degenerating into a linked list). - -## Conclusion -A Binary Search Tree is an essential data structure for efficient data management, offering quick search, insertion, and deletion operations. Understanding its structure and algorithms is crucial for optimizing tasks that involve dynamic sets of data. - ---- - diff --git a/docs/Trees/binary-tree.md b/docs/Trees/binary-tree.md deleted file mode 100644 index 3f6fd0512..000000000 --- a/docs/Trees/binary-tree.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -id: binary-tree-algorithm -title: Binary Tree Algorithm -sidebar_label: Binary Tree Algorithm -sidebar_position: 3 -description: "A Binary Tree is a data structure in which each node has at most two children." -tags: [Data Structures, binary-tree-algorithm, Algorithms] ---- - -# Binary Tree Algorithm - -## Overview -A Binary Tree is a hierarchical data structure in which each node has at most two children, referred to as the left child and the right child. It is widely used for various applications, including search algorithms, expression parsing, and organizing data. - -## Introduction -A Binary Tree can take various forms, including: -- **Full Binary Tree**: Every node has either 0 or 2 children. -- **Complete Binary Tree**: All levels are fully filled except possibly the last level, which is filled from left to right. -- **Perfect Binary Tree**: All internal nodes have two children and all leaf nodes are at the same level. -- **Skewed Binary Tree**: All nodes have only one child, either left or right. - -## Characteristics of Binary Tree Algorithm -- **Hierarchical Structure**: Organizes data in a hierarchical manner. -- **Efficient Traversals**: Supports various tree traversal methods (preorder, inorder, postorder). -- **Flexible Structure**: Can represent a variety of structures like binary search trees, heaps, etc. - -## How the Binary Tree Algorithm Works -1. **Insertion**: - - New nodes are typically added in level order, starting from the root. - - Can also follow specific rules based on the type of binary tree (e.g., BST). - -2. **Traversal**: - - Visit nodes in a specific order (e.g., inorder, preorder, postorder). - -3. **Deletion**: - - Removing a node while maintaining the tree structure. - - Specific rules apply based on whether the node is a leaf, has one child, or has two children. - -## Step-by-Step Execution - -Here’s an example of how the Binary Tree Algorithm works on a small dataset: - -### Example - -1. **Initial Insertion**: - - Insert elements: 10, 5, 15, 3, 7, 12, 18 - -```mermaid -graph TB - A((10)) --> B((5)) - A --> C((15)) - B --> D((3)) - B --> E((7)) - C --> F((12)) - C --> G((18)) -``` - -### Traversal Orders - -- **Preorder (Root, Left, Right)**: 10, 5, 3, 7, 15, 12, 18 -- **Inorder (Left, Root, Right)**: 3, 5, 7, 10, 12, 15, 18 -- **Postorder (Left, Right, Root)**: 3, 7, 5, 12, 18, 15, 10 - -## Execution Steps -1. **Insertion**: - - Add the element to the appropriate position based on the tree rules. - -2. **Traversal**: - - Implement algorithms for various tree traversal methods. - -3. **Deletion**: - - Identify the node to be deleted and adjust pointers accordingly. - -## Time Complexity -- Insertion: **O(log n)** for balanced trees (like BST), **O(n)** for skewed trees. -- Traversal: **O(n)** for all types of traversals since each node is visited once. -- Deletion: **O(log n)** for balanced trees, **O(n)** for skewed trees. - -## Applications -- **Binary Search Trees (BST)**: Efficiently manage dynamic datasets for searching, insertion, and deletion. -- **Expression Trees**: Used to represent and evaluate expressions in compilers. -- **Huffman Coding Trees**: Used in data compression algorithms. - -## Pseudocode - -1. **Insert an element**: - - Create a new node. - - Traverse to find the correct position based on the type of binary tree. - -2. **Delete a node**: - - Find the node to be deleted. - - Adjust pointers based on whether the node is a leaf, has one child, or two children. - -3. **Traverse the tree**: - - Implement the desired traversal method (preorder, inorder, postorder). - -## Advantages of Binary Tree Algorithm -- **Hierarchical Representation**: Naturally represents hierarchical relationships. -- **Flexible**: Can be modified to create specialized trees (e.g., BST, AVL, Red-Black). -- **Versatile Traversal**: Multiple traversal methods allow flexibility in data access. - -## Limitations -- **Not Always Balanced**: Unbalanced trees can lead to inefficient operations (O(n)). -- **Memory Overhead**: Each node requires additional memory for pointers to children. - -# Binary Tree vs. Binary Search Tree - -| Feature | Binary Tree | Binary Search Tree | -|----------------------|------------------------------------------------------|-----------------------------------------------------| -| **Structure** | Each node has at most two children | Each node follows the binary search property | -| **Insertion** | Can be arbitrary | Follows specific rules based on key comparison | -| **Traversal** | Supports various traversal methods | Supports all binary tree traversal methods | -| **Time Complexity** | O(n) for unbalanced trees; O(log n) for balanced trees | O(log n) for search, insertion, and deletion (balanced) | -| **Use Case** | General representation of data | Efficient searching and sorted data operations | - -## Conclusion - -The Binary Tree Algorithm is a fundamental data structure used in various applications ranging from searching and sorting to hierarchical data representation. Understanding Binary Trees is crucial for anyone working in data structures and algorithm design. - -``` - diff --git a/docs/Trees/k-d tree algorithm.md b/docs/Trees/k-d tree algorithm.md deleted file mode 100644 index 0d0168bed..000000000 --- a/docs/Trees/k-d tree algorithm.md +++ /dev/null @@ -1,193 +0,0 @@ ---- -id: kd-tree -title: K-D Tree -sidebar_label: K-D Tree -sidebar_position: 3 -description: "A K-D Tree is a space-partitioning data structure for organizing points in a k-dimensional space." -tags: [Data Structures, K-D Tree, Algorithms] ---- - -# K-D Tree - -## Overview -A **K-D Tree** (short for k-dimensional tree) is a space-partitioning data structure used for organizing points in a k-dimensional space. K-D Trees are useful for various applications such as range searches and nearest neighbor searches. They are a generalization of binary search trees to multiple dimensions. - -## Features -- **Space Partitioning**: Divides the space into nested half-spaces. -- **Efficient Searches**: Supports efficient range and nearest neighbor searches. -- **Balanced Structure**: Can be balanced to ensure efficient operations. - -## Table of Contents -- [How It Works](#how-it-works) -- [Operations](#operations) - - [Insertion](#insertion) - - [Deletion](#deletion) - - [Search](#search) - - [Nearest Neighbor Search](#nearest-neighbor-search) -- [Code Example](#code-example) -- [Applications](#applications) -- [Time Complexity](#time-complexity) - -## How It Works -In a K-D Tree: -- Each node represents a k-dimensional point. -- The tree alternates between the k dimensions at each level of the tree. -- The root node splits the space into two half-spaces based on the first dimension, the children of the root split based on the second dimension, and so on. - -### Construction -1. **Choose Axis**: Select the axis based on the depth of the node modulo k. -2. **Sort Points**: Sort the points based on the chosen axis. -3. **Median Point**: Choose the median point to ensure balanced partitions. -4. **Recursively Construct**: Recursively construct the left and right subtrees using the points before and after the median. - -## Operations - -### Insertion -To insert a new point: -1. Start at the root and choose the axis based on the depth. -2. Compare the point with the current node's point based on the chosen axis. -3. Recursively insert the point into the left or right subtree based on the comparison. - -### Deletion -To delete a point: -1. Find the node containing the point. -2. Replace the node with a suitable candidate from its subtrees to maintain the K-D Tree properties. -3. Recursively adjust the tree to ensure balance. - -### Search -To search for a point: -1. Start at the root and choose the axis based on the depth. -2. Compare the point with the current node's point based on the chosen axis. -3. Recursively search the left or right subtree based on the comparison. - -### Nearest Neighbor Search -To find the nearest neighbor: -1. Start at the root and traverse the tree to find the leaf node closest to the target point. -2. Backtrack and check if there are closer points in the other half-spaces. -3. Use a priority queue to keep track of the closest points found. - -## Code Example - -### Python Example (K-D Tree): - -```python -class Node: - def __init__(self, point, axis, left=None, right=None): - self.point = point - self.axis = axis - self.left = left - self.right = right - -class KDTree: - def __init__(self, points): - self.k = len(points[0]) if points else 0 - self.root = self.build_tree(points, depth=0) - - def build_tree(self, points, depth): - if not points: - return None - - axis = depth % self.k - points.sort(key=lambda x: x[axis]) - median = len(points) // 2 - - return Node( - point=points[median], - axis=axis, - left=self.build_tree(points[:median], depth + 1), - right=self.build_tree(points[median + 1:], depth + 1) - ) - - def insert(self, root, point, depth=0): - if root is None: - return Node(point, depth % self.k) - - axis = root.axis - if point[axis] < root.point[axis]: - root.left = self.insert(root.left, point, depth + 1) - else: - root.right = self.insert(root.right, point, depth + 1) - - return root - - def search(self, root, point, depth=0): - if root is None or root.point == point: - return root - - axis = root.axis - if point[axis] < root.point[axis]: - return self.search(root.left, point, depth + 1) - else: - return self.search(root.right, point, depth + 1) - - def nearest_neighbor(self, root, point, depth=0, best=None): - if root is None: - return best - - axis = root.axis - next_best = None - next_branch = None - - if best is None or self.distance(point, root.point) < self.distance(point, best.point): - next_best = root - else: - next_best = best - - if point[axis] < root.point[axis]: - next_branch = root.left - other_branch = root.right - else: - next_branch = root.right - other_branch = root.left - - next_best = self.nearest_neighbor(next_branch, point, depth + 1, next_best) - - if self.distance(point, next_best.point) > abs(point[axis] - root.point[axis]): - next_best = self.nearest_neighbor(other_branch, point, depth + 1, next_best) - - return next_best - - def distance(self, point1, point2): - return sum((x - y) ** 2 for x, y in zip(point1, point2)) ** 0.5 - -# Example usage: -points = [(2, 3), (5, 4), (9, 6), (4, 7), (8, 1), (7, 2)] -kd_tree = KDTree(points) - -# Insert a new point -kd_tree.insert(kd_tree.root, (3, 6)) - -# Search for a point -result = kd_tree.search(kd_tree.root, (5, 4)) -print("Found:", result.point if result else "Not found") - -# Find the nearest neighbor -nearest = kd_tree.nearest_neighbor(kd_tree.root, (9, 2)) -print("Nearest neighbor:", nearest.point if nearest else "None") -``` - -### Output: -``` -Found: (5, 4) -Nearest neighbor: (8, 1) -``` - -## Applications -- **Databases**: Used for maintaining sorted data in databases where frequent insertions and deletions are required. -- **Memory Management**: Efficiently manage free memory blocks in systems. -- **Auto-completion**: Used in applications that require predictive text suggestions. - -## Time Complexity - -| Operation | Average Time | Worst Case Time | -|----------------------|--------------|-----------------| -| **Search** | O(log n) | O(n) | -| **Insertion** | O(log n) | O(n) | -| **Deletion** | O(log n) | O(n) | -| **Nearest Neighbor** | O(log n) | O(n) | - -> **Note**: The worst-case time complexity arises in unbalanced cases; balanced K-D Trees maintain an average of O(log n) for most operations. - -## Conclusion -K-D Trees are powerful data structures for organizing and searching points in multi-dimensional spaces. They are essential for applications that require efficient spatial searches and nearest neighbor queries. ---- \ No newline at end of file diff --git a/docs/Trees/tree-data-structure.md b/docs/Trees/tree-data-structure.md deleted file mode 100644 index 47998bc90..000000000 --- a/docs/Trees/tree-data-structure.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -id: tree-data-structures -title: Tree Data Structures -sidebar_label: Tree Data Structures -description: "An in-depth guide to tree data structures, covering types of trees, traversal methods, balancing, and algorithms with implementations." -tags: [dsa, trees, algorithms, binary-trees] ---- - -### Introduction - -A **Tree** is a widely used data structure that simulates a hierarchical tree structure with a set of nodes. It is a non-linear data structure, meaning data elements are not arranged in a sequential manner. - -- **Root**: The topmost node in a tree. -- **Node**: Each element in a tree, containing a value or data, and references to other nodes. -- **Edge**: The link between two nodes. -- **Parent and Child**: The connected nodes, where one is higher in the hierarchy (parent) and others are lower (children). -- **Leaf**: A node without children. -- **Depth**: The number of edges from the root to the node. -- **Height**: The number of edges in the longest path from a node to a leaf. - -### Types of Trees - -1. **Binary Tree**: A tree where each node has at most two children. - - **Full Binary Tree**: Every node has either 0 or 2 children. - - **Complete Binary Tree**: All levels are fully filled except possibly the last level. - - **Perfect Binary Tree**: All levels are fully filled, including the last level. - - **Balanced Binary Tree**: The height difference between left and right subtrees of every node is at most one. - -2. **Binary Search Tree (BST)**: A binary tree with the left child containing nodes with lesser values, and the right child containing nodes with greater values. - -3. **AVL Tree**: A self-balancing binary search tree where the difference in heights of left and right subtrees is at most one for all nodes. - -4. **Red-Black Tree**: A balanced binary search tree with additional properties to ensure balance through color-coding. - -5. **B-Tree**: A self-balancing tree data structure that maintains sorted data and allows searches, insertions, deletions, and sequential access in logarithmic time. - -6. **Trie**: A tree-like data structure used for storing a dynamic set of strings, often used for searching words. - -### Tree Traversals - -Tree traversal refers to the process of visiting each node in a tree exactly once in a specific order. The main types of tree traversal are: - -1. **In-Order Traversal** (for BSTs): - - Traverse the left subtree. - - Visit the root node. - - Traverse the right subtree. - - *Use Case*: To retrieve data in a sorted order in a BST. - -2. **Pre-Order Traversal**: - - Visit the root node. - - Traverse the left subtree. - - Traverse the right subtree. - - *Use Case*: Used for creating a copy of the tree. - -3. **Post-Order Traversal**: - - Traverse the left subtree. - - Traverse the right subtree. - - Visit the root node. - - *Use Case*: Used for deleting the tree. - -4. **Level-Order Traversal**: - - Visit nodes level by level from the root. - - *Use Case*: Finding the shortest path or level-by-level operations. - -### Tree Balancing - -Balancing a tree ensures that the tree maintains its structure for efficient operations. The two most common balanced trees are **AVL Trees** and **Red-Black Trees**. - -- **AVL Tree**: Self-balances by performing rotations (Left, Right, Left-Right, Right-Left) to maintain a height difference of at most one between subtrees. - -- **Red-Black Tree**: Uses coloring and rotations to ensure that no path is more than twice as long as any other, leading to `O(log n)` time complexity for operations. - -### Tree Algorithms - -1. **Insertion**: - - Binary Search Tree (BST): Place the new node in a position that maintains the BST property. - - AVL Tree: After insertion, rotate nodes as needed to balance the tree. - - Red-Black Tree: Insert a new node as a red node and recolor or rotate as needed. - -2. **Deletion**: - - BST: Remove the node and reorganize the subtree if necessary. - - AVL Tree: After deletion, rebalance the tree using rotations. - - Red-Black Tree: Remove the node, then perform recoloring or rotations to maintain balance. - -3. **Search**: - - BST: Use a binary search strategy to find the element. - - Trie: Traverse through nodes based on characters of the string. - -### Example: Binary Search Tree Implementation in Java - -```java -class Node { - int key; - Node left, right; - - public Node(int item) { - key = item; - left = right = null; - } -} - -class BinarySearchTree { - Node root; - - BinarySearchTree() { - root = null; - } - - // Insert a new node with given key - void insert(int key) { - root = insertRec(root, key); - } - - Node insertRec(Node root, int key) { - if (root == null) { - root = new Node(key); - return root; - } - if (key < root.key) - root.left = insertRec(root.left, key); - else if (key > root.key) - root.right = insertRec(root.right, key); - return root; - } - - // Inorder traversal of the tree - void inorder() { - inorderRec(root); - } - - void inorderRec(Node root) { - if (root != null) { - inorderRec(root.left); - System.out.print(root.key + " "); - inorderRec(root.right); - } - } - - // Delete a node with given key - void deleteKey(int key) { - root = deleteRec(root, key); - } - - Node deleteRec(Node root, int key) { - if (root == null) return root; - - if (key < root.key) - root.left = deleteRec(root.left, key); - else if (key > root.key) - root.right = deleteRec(root.right, key); - else { - if (root.left == null) - return root.right; - else if (root.right == null) - return root.left; - - root.key = minValue(root.right); - root.right = deleteRec(root.right, root.key); - } - return root; - } - - int minValue(Node root) { - int minValue = root.key; - while (root.left != null) { - minValue = root.left.key; - root = root.left; - } - return minValue; - } -} -``` \ No newline at end of file diff --git a/docs/Tries/Problem-Practice.md b/docs/Tries/Problem-Practice.md deleted file mode 100644 index bac848dcc..000000000 --- a/docs/Tries/Problem-Practice.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -id: Practice-Problems-on-tries -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 2 -description: Here are some practice problems for tries -tags: [DSA, algorithms, tries] ---- - -### Problems on tries: - -- [Implement trie](https://leetcode.com/problems/implement-trie-prefix-tree/description/) -- [Implement trie-2](https://leetcode.com/problems/implement-trie-ii-prefix-tree/description/) -- [Longest word with all prefixes](https://leetcode.com/problems/longest-word-with-all-prefixes/description/) -- [Number of distinct substrings in a string](https://leetcode.com/problems/number-of-distinct-substrings-in-a-string/description/) -- [Maximum XOR of 2 numbers in an array](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/description/) -- [Maximum xor with an element from array](https://leetcode.com/problems/maximum-xor-with-an-element-from-array/description/) -- [Palindrome Pairs](https://leetcode.com/problems/palindrome-pairs/description/) -- [Phone directory](https://www.geeksforgeeks.org/problems/phone-directory4628/1) -- [Print Anagrams Together](https://www.geeksforgeeks.org/problems/print-anagrams-together/1) -- [Design Add and Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/description/) -- [Word Break (Trie)](https://www.geeksforgeeks.org/problems/word-break-trie--141631/1?itm_source=geeksforgeeks&itm_medium=article&itm_campaign=practice_card) \ No newline at end of file diff --git a/docs/Tries/Tries and its Implementation.md b/docs/Tries/Tries and its Implementation.md deleted file mode 100644 index 14eccded9..000000000 --- a/docs/Tries/Tries and its Implementation.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -id: trie-intro -sidebar_position: 11 -title: Tries (Prefix Trees) -sidebar_label: Tries -description: "In this blog post, we'll explore Tries, a powerful data structure for string-based operations like prefix searches and autocomplete." -tags: [dsa, data structures, tries] ---- - -## Introduction -Tries, also known as **Prefix Trees**, are a specialized data structure used primarily for **efficient retrieval of keys** in a dataset of strings. Tries are particularly useful when dealing with problems involving dynamic sets of strings, such as word searches, dictionary implementations, or autocomplete systems. Unlike other data structures such as hash tables, tries store characters at each level, providing a more structured representation of the key itself. - -## Definition and Structure -A Trie is a tree-like data structure where each node represents a single character of a string. The root node is typically an empty node, and each path down the tree represents a word or prefix. - -Key components of a Trie node: -- **Children**: References to its child nodes, typically stored in an array or hash map. -- **End of Word**: A boolean flag to indicate if the current node represents the end of a valid word. - -**Example Trie storing ["and", "ant", "do", "dad"]:** -``` - (root) - / \ - a d - / / \ - n o a - / \ / \ - d t (do) d - / \ \ -(and) (ant) (dad) -``` - - -## Properties -- **Prefix-based Search**: Tries excel in finding all words that share a common prefix. -- **Space Efficiency**: Although tries can be space-heavy in some cases, they eliminate the need to store redundant prefixes, making them more space-efficient for large datasets of similar strings. -- **Time Complexity**: Trie operations such as insertion, search, and deletion have a time complexity of **O(m)**, where **m** is the length of the word or prefix being processed. - -## Types of Tries -1. **Standard Trie**: Every node has 26 possible children (if dealing with lowercase alphabets), and each child represents one of the letters of the alphabet. - ``` - Insert words: "cat", "can" - - root - / - c - / - a - / \ - t n - ``` - -2. **Compressed Trie (Radix Tree)**: In a compressed trie, chains of single children are compressed into one node, reducing the overall size of the trie. - ``` - Insert words: "cat", "car" - - root - / - c - / - a - / \ - t r - ``` - -3. **Suffix Trie**: A specialized trie used for storing all possible suffixes of a given string. Suffix tries are useful in **pattern matching** problems. - -## Operations on Tries - -### 1. **Insertion** -To insert a word into a trie, we traverse through each character of the word and insert it into the corresponding child node if it does not already exist. Once we have processed the last character, we mark the current node as the end of the word. - -### 2. **Search** -Searching for a word in a trie follows a similar traversal as insertion. If we can traverse through all the characters of the word, and the final node is marked as the end of the word, then the word exists in the trie. - -### 3. **Deletion** -Deleting a word requires careful handling to avoid breaking the structure of the trie. If the word to be deleted is a prefix of other words, we should only unmark the end of the word flag. If no other words depend on the nodes being deleted, we can remove them safely. - -## Implementation - -Here’s an example of how you can implement a Trie in C++: - -```cpp -class TrieNode { -public: - unordered_map children; - bool isEndOfWord; - - TrieNode() { - isEndOfWord = false; - } -}; - -class Trie { -public: - TrieNode* root; - - Trie() { - root = new TrieNode(); - } - - void insert(string word) { - TrieNode* node = root; - for (char c : word) { - if (node->children.find(c) == node->children.end()) { - node->children[c] = new TrieNode(); - } - node = node->children[c]; - } - node->isEndOfWord = true; - } - - bool search(string word) { - TrieNode* node = root; - for (char c : word) { - if (node->children.find(c) == node->children.end()) { - return false; - } - node = node->children[c]; - } - return node->isEndOfWord; - } - - bool startsWith(string prefix) { - TrieNode* node = root; - for (char c : prefix) { - if (node->children.find(c) == node->children.end()) { - return false; - } - node = node->children[c]; - } - return true; - } -}; - -int main() { - Trie* trie = new Trie(); - trie->insert("apple"); - cout << trie->search("apple") << endl; // true - cout << trie->search("app") << endl; // false - cout << trie->startsWith("app") << endl; // true - trie->insert("app"); - cout << trie->search("app") << endl; // true -} -``` -## Advantages and Disadvantages - -**Advantages:** -- **Prefix Search**: Tries enable fast lookups for words or prefixes, making them ideal for autocomplete functionality. -- **Efficient Storage**: Common prefixes are stored once, reducing redundancy. -- **Fast Insertions and Searches**: Operations on a Trie (insertion, search, and deletion) are fast with a time complexity of **O(m)**, where **m** is the length of the word. -- **No Hash Collisions**: Unlike hash tables, tries do not suffer from hash collisions, ensuring consistent performance for string operations. - -**Disadvantages:** -- **Space Consumption**: Tries can consume a significant amount of memory, especially when the alphabet size is large, due to the need for pointers in each node. -- **Implementation Complexity**: Compared to hash tables or arrays, tries are more complex to implement, especially with memory management. - -## Applications of Tries - -- **Autocomplete Systems**: - Tries are used in search engines and text editors to provide efficient autocomplete suggestions based on a prefix. - -- **Spell Checking**: - Tries can quickly validate whether a word exists in a dictionary, making them suitable for spell check systems. - -- **IP Routing**: - Tries, specifically compressed tries, are used in IP routing tables to store and retrieve routing paths efficiently. - -- **Word Games**: - Many word-based games like Scrabble or Boggle use tries to validate possible word combinations and optimize the search for valid words. - -- **Pattern Matching Algorithms**: - Tries, particularly suffix tries, are used in string pattern matching problems like substring search, and are efficient for tasks like finding all occurrences of a word or a prefix. - diff --git a/docs/Tries/tries-examples.md b/docs/Tries/tries-examples.md deleted file mode 100644 index af1b4e403..000000000 --- a/docs/Tries/tries-examples.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -id: trie-intro-3 -sidebar_position: 11 -title: Tries (Prefix Trees examples) -sidebar_label: Tries -description: "In this blog post, we'll explore Tries, a powerful data structure for string-based operations like prefix searches and autocomplete." -tags: [dsa, data structures, tries] ---- -# Trie Examples - -This repository contains several examples of how to use a Trie (prefix tree) for common tasks such as word insertion, search, autocomplete, and prefix matching. - -## Example 1: Inserting Words into a Trie - -This example demonstrates how to insert words into a Trie and how to search for words. - -```cpp -#include -#include -using namespace std; - -struct TrieNode { - unordered_map children; - bool isEndOfWord; - - TrieNode() { - isEndOfWord = false; - } -}; - -class Trie { - TrieNode* root; -public: - Trie() { - root = new TrieNode(); - } - - // Insert a word into the Trie - void insert(string word) { - TrieNode* node = root; - for (char c : word) { - if (!node->children.count(c)) { - node->children[c] = new TrieNode(); - } - node = node->children[c]; - } - node->isEndOfWord = true; - } - - // Search for a word in the Trie - bool search(string word) { - TrieNode* node = root; - for (char c : word) { - if (!node->children.count(c)) return false; - node = node->children[c]; - } - return node->isEndOfWord; - } -}; - -int main() { - Trie trie; - trie.insert("apple"); - trie.insert("banana"); - cout << trie.search("apple") << endl; // Outputs: 1 (true) - cout << trie.search("bat") << endl; // Outputs: 0 (false) - return 0; -} -``` - -## Example 2: Implementing Autocomplete with a Trie -This example demonstrates how to implement an autocomplete feature using a Trie. - -```cpp -Copy code -#include -#include -#include -using namespace std; - -struct TrieNode { - unordered_map children; - bool isEndOfWord; - - TrieNode() { - isEndOfWord = false; - } -}; - -class Trie { - TrieNode* root; - - void getWords(TrieNode* node, string prefix, vector& result) { - if (node->isEndOfWord) result.push_back(prefix); - for (auto& p : node->children) { - getWords(p.second, prefix + p.first, result); - } - } - -public: - Trie() { - root = new TrieNode(); - } - - // Insert a word into the Trie - void insert(string word) { - TrieNode* node = root; - for (char c : word) { - if (!node->children.count(c)) { - node->children[c] = new TrieNode(); - } - node = node->children[c]; - } - node->isEndOfWord = true; - } - - // Get all words with a given prefix - vector autocomplete(string prefix) { - TrieNode* node = root; - vector result; - for (char c : prefix) { - if (!node->children.count(c)) return result; - node = node->children[c]; - } - getWords(node, prefix, result); - return result; - } -}; - -int main() { - Trie trie; - trie.insert("cat"); - trie.insert("car"); - trie.insert("cart"); - trie.insert("dog"); - - vector result = trie.autocomplete("ca"); - for (string word : result) { - cout << word << endl; // Outputs: cat, car, cart - } - - return 0; -} - -``` - -## Example 3: Prefix Matching with a Trie -This example shows how to check if a prefix exists in a Trie. - -```cpp -Copy code -#include -#include -using namespace std; - -struct TrieNode { - unordered_map children; - bool isEndOfWord; - - TrieNode() { - isEndOfWord = false; - } -}; - -class Trie { - TrieNode* root; -public: - Trie() { - root = new TrieNode(); - } - - // Insert a word into the Trie - void insert(string word) { - TrieNode* node = root; - for (char c : word) { - if (!node->children.count(c)) { - node->children[c] = new TrieNode(); - } - node = node->children[c]; - } - node->isEndOfWord = true; - } - - // Check if there is any word in the Trie that starts with a given prefix - bool startsWith(string prefix) { - TrieNode* node = root; - for (char c : prefix) { - if (!node->children.count(c)) return false; - node = node->children[c]; - } - return true; - } -}; - -int main() { - Trie trie; - trie.insert("hello"); - trie.insert("help"); - trie.insert("world"); - - cout << trie.startsWith("he") << endl; // Outputs: 1 (true) - cout << trie.startsWith("wor") << endl; // Outputs: 1 (true) - cout << trie.startsWith("woe") << endl; // Outputs: 0 (false) - - return 0; -} -``` \ No newline at end of file diff --git a/docs/Tries/tries-theory.md b/docs/Tries/tries-theory.md deleted file mode 100644 index 84a31fa5d..000000000 --- a/docs/Tries/tries-theory.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -id: trie-intro-2 -sidebar_position: 11 -title: Tries (Prefix Trees theory) -sidebar_label: Tries -description: "In this blog post, we'll explore Tries, a powerful data structure for string-based operations like prefix searches and autocomplete." -tags: [dsa, data structures, tries] ---- - -# Trie Data Structure - -## Introduction - -A **Trie** (also called a **Prefix Tree**) is a special type of tree used to store collections of strings. It is commonly used for tasks involving prefix-based search, such as autocomplete, dictionary implementations, and spell checking. - -The key idea of a Trie is to use the **prefixes** of words to share common parts and reduce memory usage. Each node in a Trie represents a single character, and the paths from the root to a leaf represent words. - -## Key Concepts - -1. **Root**: The Trie starts from the root node, which is an empty node or a node with no character. -2. **Edges**: Each edge represents a character from the alphabet. -3. **Nodes**: Each node stores a character and points to its children (the next characters in words that share the same prefix). -4. **End of Word**: Some nodes are marked as "end of word" nodes, indicating that the characters from the root to this node form a valid word. - -## Operations - -### 1. **Insert Operation** - -The insert operation is used to add a word to the Trie. The process is as follows: -- Start from the root and for each character in the word, check if it already exists as a child of the current node. -- If not, create a new node for that character. -- Mark the final node as the "end of word" to signify that the path represents a complete word. - -### 2. **Search Operation** - -The search operation checks whether a given word exists in the Trie: -- Start at the root and for each character in the word, check if it exists as a child node. -- If you reach the end of the word and the current node is marked as the "end of word", then the word exists in the Trie. - -### 3. **Prefix Search** - -A common use case of a Trie is to find all words that start with a given prefix: -- Traverse the Trie using the characters of the prefix. -- Once the prefix is found, collect all the words that follow from the remaining nodes. - -## Example - -Here is a simple visualization of a Trie that stores the words "cat", "car", "dog", and "dot": - - - -In this Trie: -- "cat", "car", "dog", and "dot" are stored. -- The nodes marked as **(EOW)** indicate the "end of word". - -## Time Complexity - -- **Insert**: O(m) where *m* is the length of the word being inserted. -- **Search**: O(m) where *m* is the length of the word being searched. -- **Prefix Search**: O(m + k) where *m* is the length of the prefix and *k* is the number of characters in the words that match the prefix. - -## Advantages of Trie - -1. **Efficient for Prefix Search**: Tries are optimal for prefix searches, as they can find all words with a given prefix in linear time relative to the length of the prefix. -2. **Reduced Space for Shared Prefixes**: By sharing common prefixes, Tries can reduce the memory usage for storing large sets of related words. - -## Disadvantages of Trie - -1. **Memory Usage**: While Tries are efficient in terms of search, they may use more memory than other data structures like hash maps if there are many different words with few shared prefixes. -2. **Complexity**: Implementing a Trie from scratch can be more complex compared to other data structures. - -## Common Applications - -- **Autocomplete systems**: Finding all words that begin with a given prefix. -- **Spell checking**: Checking if a given word exists in a dictionary. -- **IP routing**: Tries can be used to represent routing tables in networking. - ---- - -## Example Code (C++) - -```cpp -#include -#include -using namespace std; - -struct TrieNode { - unordered_map children; - bool isEndOfWord; - - TrieNode() { - isEndOfWord = false; - } -}; - -class Trie { - TrieNode* root; -public: - Trie() { - root = new TrieNode(); - } - - // Insert a word into the Trie - void insert(string word) { - TrieNode* node = root; - for (char c : word) { - if (!node->children.count(c)) { - node->children[c] = new TrieNode(); - } - node = node->children[c]; - } - node->isEndOfWord = true; - } - - // Search for a word in the Trie - bool search(string word) { - TrieNode* node = root; - for (char c : word) { - if (!node->children.count(c)) return false; - node = node->children[c]; - } - return node->isEndOfWord; - } -}; - -int main() { - Trie trie; - trie.insert("cat"); - trie.insert("car"); - trie.insert("dog"); - - cout << trie.search("cat") << endl; // Outputs: 1 (true) - cout << trie.search("car") << endl; // Outputs: 1 (true) - cout << trie.search("bat") << endl; // Outputs: 0 (false) - - return 0; -} -``` \ No newline at end of file diff --git a/docs/advance-data-structure/_category_.json b/docs/advance-data-structure/_category_.json deleted file mode 100644 index e01b7363f..000000000 --- a/docs/advance-data-structure/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Advanced Data Structures", - "position": 9, - "link": { - "type": "generated-index", - "description": "Discover the key roadmap for mastering advanced data structure concepts and techniques." - } -} diff --git a/docs/advance-data-structure/disjoint-set.md b/docs/advance-data-structure/disjoint-set.md deleted file mode 100644 index df83f8a8a..000000000 --- a/docs/advance-data-structure/disjoint-set.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -id: disjoint-set-union -sidebar_position: 1 -title: Disjoint Set Union (Union-Find) -sidebar_label: Disjoint Set Union -description: "Disjoint Set Union (Union-Find) is an efficient data structure to track the union of disjoint sets." -tags: [union-find, advance data structures, disjoint set] ---- - -# Disjoint Set Union (Union-Find) - -The **Disjoint Set Union (DSU)**, also known as **Union-Find**, is an efficient data structure that tracks a collection of disjoint (non-overlapping) sets. It supports two main operations efficiently: - -- **Find**: Determine the root or representative of the set containing a specific element. -- **Union**: Merge two sets into a single set. - -## Purpose - -The Union-Find data structure is widely used in algorithms that require grouping elements and checking for connectivity, such as: - -- **Dynamic connectivity problems**. -- **Kruskal’s Algorithm** for finding the Minimum Spanning Tree (MST) in graphs. -- **Network connectivity**. - -## Operations - -1. **Make Set**: Initialize a set with a single element. -2. **Find**: Determine the root of the set containing the element. -3. **Union**: Join two sets. - -## Time Complexity - -- **Time Complexity**: $O(α(n))$ per operation, where $α(n)$ is the inverse Ackermann function, which grows extremely slowly. - -## Implementations - -### C++ - -```cpp -#include -using namespace std; - -class DisjointSet { - int *parent, *rank; - int n; - -public: - DisjointSet(int n) { - this->n = n; - parent = new int[n]; - rank = new int[n]; - for (int i = 0; i < n; i++) { - parent[i] = i; - rank[i] = 0; - } - } - - int find(int v) { - if (v == parent[v]) - return v; - return parent[v] = find(parent[v]); // Path compression - } - - void unionSets(int a, int b) { - a = find(a); - b = find(b); - if (a != b) { - if (rank[a] < rank[b]) - swap(a, b); - parent[b] = a; - if (rank[a] == rank[b]) - rank[a]++; - } - } -}; -``` -### Java -```java -class DisjointSet { - private int[] parent, rank; - - public DisjointSet(int n) { - parent = new int[n]; - rank = new int[n]; - for (int i = 0; i < n; i++) { - parent[i] = i; - rank[i] = 0; - } - } - - public int find(int v) { - if (v == parent[v]) - return v; - return parent[v] = find(parent[v]); // Path compression - } - - public void union(int a, int b) { - a = find(a); - b = find(b); - if (a != b) { - if (rank[a] < rank[b]) - swap(a, b); - parent[b] = a; - if (rank[a] == rank[b]) - rank[a]++; - } - } - - private void swap(int a, int b) { - int temp = a; - a = b; - b = temp; - } -} -``` -### Python -```python -class DisjointSet: - def __init__(self, n): - self.parent = [i for i in range(n)] - self.rank = [0] * n - - def find(self, v): - if v != self.parent[v]: - self.parent[v] = self.find(self.parent[v]) # Path compression - return self.parent[v] - - def union(self, a, b): - a = self.find(a) - b = self.find(b) - if a != b: - if self.rank[a] < self.rank[b]: - a, b = b, a - self.parent[b] = a - if self.rank[a] == self.rank[b]: - self.rank[a] += 1 -``` -### Pseudo Code -``` -function makeSet(n): - parent = array of size n - rank = array of size n - for i from 0 to n-1: - parent[i] = i - rank[i] = 0 - -function find(v): - if v == parent[v]: - return v - parent[v] = find(parent[v]) // Path compression - return parent[v] - -function union(a, b): - a = find(a) - b = find(b) - if a != b: - if rank[a] < rank[b]: - swap(a, b) - parent[b] = a - if rank[a] == rank[b]: - rank[a] += 1 -``` -### Conclusion -The Disjoint Set Union (Union-Find) is an essential data structure for efficiently managing disjoint sets and performing union and find operations. -Its applications in network connectivity and graph algorithms make it a fundamental topic in data structures and algorithms. \ No newline at end of file diff --git a/docs/advance-data-structure/fenwick-tree.md b/docs/advance-data-structure/fenwick-tree.md deleted file mode 100644 index 2d7efc21c..000000000 --- a/docs/advance-data-structure/fenwick-tree.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: fenwick-tree -sidebar_position: 3 -title: Fenwick Tree (Binary Indexed Tree) -sidebar_label: Fenwick Tree -description: "Fenwick Tree (Binary Indexed Tree) is a more space-efficient data structure for cumulative frequency tables." -tags: [fenwick tree, binary indexed tree, advance data structures] ---- - -# Fenwick Tree (Binary Indexed Tree) - -The **Fenwick Tree**, also known as the **Binary Indexed Tree (BIT)**, is a data structure that provides efficient methods for maintaining cumulative frequency tables. It allows for both updates and prefix sum calculations to be performed in logarithmic time. - -## Purpose - -The Fenwick Tree is used in situations where you need to efficiently perform the following operations: - -- **Update**: Update an element in the array. -- **Query**: Calculate the sum of elements from the start of the array to a given index. - -It is particularly useful in scenarios involving cumulative frequency tables, such as in statistical computations, game score calculations, and in various algorithms requiring range queries. - -## Operations - -1. **Update**: Increment an element at a specific index by a given value. -2. **Query**: Compute the sum of the elements from the start of the array to a given index. - -## Time Complexity - -- **Time Complexity**: $O(log \ n)$ for both update and query operations, where n is the number of elements in the array. - -## Space Complexity - -- **Space Complexity**: $O(n)$ for storing the tree, where n is the number of elements. - -## Implementations - -### C++ - -```cpp -#include -#include -using namespace std; - -class FenwickTree { - vector tree; - int n; - -public: - FenwickTree(int size) { - n = size; - tree.resize(n + 1, 0); - } - - void update(int index, int value) { - for (; index <= n; index += index & -index) { - tree[index] += value; - } - } - - int query(int index) { - int sum = 0; - for (; index > 0; index -= index & -index) { - sum += tree[index]; - } - return sum; - } -}; -``` -### Java -```java -class FenwickTree { - private int[] tree; - private int n; - - public FenwickTree(int size) { - n = size; - tree = new int[n + 1]; - } - - public void update(int index, int value) { - for (; index <= n; index += index & -index) { - tree[index] += value; - } - } - - public int query(int index) { - int sum = 0; - for (; index > 0; index -= index & -index) { - sum += tree[index]; - } - return sum; - } -} -``` -### Python -```python -class FenwickTree: - def __init__(self, size): - self.size = size - self.tree = [0] * (size + 1) - - def update(self, index, value): - while index <= self.size: - self.tree[index] += value - index += index & -index - - def query(self, index): - sum = 0 - while index > 0: - sum += self.tree[index] - index -= index & -index - return sum -``` -### Pseudo Code -``` -function FenwickTree(size): - tree = array of size (size + 1) - initialize all elements to 0 - -function update(index, value): - while index <= size: - tree[index] += value - index += index & -index - -function query(index): - sum = 0 - while index > 0: - sum += tree[index] - index -= index & -index - return sum -``` -### Conclusion -The Fenwick Tree (Binary Indexed Tree) is a powerful data structure for efficiently managing cumulative frequency tables and performing range queries. Its ability to update and query sums in logarithmic time makes it a valuable tool in various algorithmic applications. \ No newline at end of file diff --git a/docs/advance-data-structure/segment-tree.md b/docs/advance-data-structure/segment-tree.md deleted file mode 100644 index a99032368..000000000 --- a/docs/advance-data-structure/segment-tree.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -id: segment-trees -sidebar_position: 2 -title: Segment Trees -sidebar_label: Segment Trees -description: "Segment Trees are used for efficient range queries." -tags: [segment trees, advance data structures, trees, range queries] ---- - -# Segment Trees - -**Segment Trees** are a versatile and efficient data structure used for solving range query problems. They allow for quick querying of information over a range of elements in an array, making them particularly useful in scenarios where the data may change frequently. - -## Purpose - -Segment Trees are commonly used for: - -- **Range sum queries**: Quickly calculating the sum of elements in a specific range. -- **Range minimum/maximum queries**: Finding the minimum or maximum element in a range. -- **Range updates**: Modifying the values of elements in a range efficiently. - -## Operations - -1. **Build**: Construct the segment tree from the given array. -2. **Query**: Retrieve information about a specific range (e.g., sum, minimum, maximum). -3. **Update**: Modify the value of a specific element and update the tree accordingly. - -## Time Complexity - -- **Building the Segment Tree**: $O(n)$ -- **Querying**: $O(log \ n)$ -- **Updating**: $O(log \ n)$ - -## Implementations - -### C++ - -```cpp -#include -#include -using namespace std; - -class SegmentTree { - vector tree; - int n; - -public: - SegmentTree(int arr[], int size) { - n = size; - tree.resize(4 * n); - buildTree(arr, 0, 0, n - 1); - } - - void buildTree(int arr[], int node, int start, int end) { - if (start == end) { - tree[node] = arr[start]; - } else { - int mid = (start + end) / 2; - buildTree(arr, 2 * node + 1, start, mid); - buildTree(arr, 2 * node + 2, mid + 1, end); - tree[node] = tree[2 * node + 1] + tree[2 * node + 2]; - } - } - - int query(int node, int start, int end, int l, int r) { - if (r < start || end < l) { - return 0; // Out of range - } - if (l <= start && end <= r) { - return tree[node]; // Total overlap - } - int mid = (start + end) / 2; - return query(2 * node + 1, start, mid, l, r) + - query(2 * node + 2, mid + 1, end, l, r); // Partial overlap - } - - void update(int node, int start, int end, int idx, int val) { - if (start == end) { - tree[node] = val; // Update leaf node - } else { - int mid = (start + end) / 2; - if (start <= idx && idx <= mid) { - update(2 * node + 1, start, mid, idx, val); - } else { - update(2 * node + 2, mid + 1, end, idx, val); - } - tree[node] = tree[2 * node + 1] + tree[2 * node + 2]; // Update parent - } - } -}; -``` -### Java -```java -class SegmentTree { - private int[] tree; - private int n; - - public SegmentTree(int[] arr) { - n = arr.length; - tree = new int[4 * n]; - buildTree(arr, 0, 0, n - 1); - } - - private void buildTree(int[] arr, int node, int start, int end) { - if (start == end) { - tree[node] = arr[start]; - } else { - int mid = (start + end) / 2; - buildTree(arr, 2 * node + 1, start, mid); - buildTree(arr, 2 * node + 2, mid + 1, end); - tree[node] = tree[2 * node + 1] + tree[2 * node + 2]; - } - } - - public int query(int l, int r) { - return query(0, 0, n - 1, l, r); - } - - private int query(int node, int start, int end, int l, int r) { - if (r < start || end < l) { - return 0; // Out of range - } - if (l <= start && end <= r) { - return tree[node]; // Total overlap - } - int mid = (start + end) / 2; - return query(2 * node + 1, start, mid, l, r) + - query(2 * node + 2, mid + 1, end, l, r); // Partial overlap - } - - public void update(int idx, int val) { - update(0, 0, n - 1, idx, val); - } - - private void update(int node, int start, int end, int idx, int val) { - if (start == end) { - tree[node] = val; // Update leaf node - } else { - int mid = (start + end) / 2; - if (start <= idx && idx <= mid) { - update(2 * node + 1, start, mid, idx, val); - } else { - update(2 * node + 2, mid + 1, end, idx, val); - } - tree[node] = tree[2 * node + 1] + tree[2 * node + 2]; // Update parent - } - } -} -``` -### Python -```python -class SegmentTree: - def __init__(self, arr): - self.n = len(arr) - self.tree = [0] * (4 * self.n) - self.build_tree(arr, 0, 0, self.n - 1) - - def build_tree(self, arr, node, start, end): - if start == end: - self.tree[node] = arr[start] - else: - mid = (start + end) // 2 - self.build_tree(arr, 2 * node + 1, start, mid) - self.build_tree(arr, 2 * node + 2, mid + 1, end) - self.tree[node] = self.tree[2 * node + 1] + self.tree[2 * node + 2] - - def query(self, l, r): - return self.query_recursive(0, 0, self.n - 1, l, r) - - def query_recursive(self, node, start, end, l, r): - if r < start or end < l: - return 0 # Out of range - if l <= start and end <= r: - return self.tree[node] # Total overlap - mid = (start + end) // 2 - return (self.query_recursive(2 * node + 1, start, mid, l, r) + - self.query_recursive(2 * node + 2, mid + 1, end, l, r)) # Partial overlap - - def update(self, idx, val): - self.update_recursive(0, 0, self.n - 1, idx, val) - - def update_recursive(self, node, start, end, idx, val): - if start == end: - self.tree[node] = val # Update leaf node - else: - mid = (start + end) // 2 - if start <= idx <= mid: - self.update_recursive(2 * node + 1, start, mid, idx, val) - else: - self.update_recursive(2 * node + 2, mid + 1, end, idx, val) - self.tree[node] = self.tree[2 * node + 1] + self.tree[2 * node + 2] # Update parent -``` -### Pseudo Code -``` -function buildTree(arr, node, start, end): - if start == end: - tree[node] = arr[start] - else: - mid = (start + end) / 2 - buildTree(arr, 2 * node + 1, start, mid) - buildTree(arr, 2 * node + 2, mid + 1, end) - tree[node] = tree[2 * node + 1] + tree[2 * node + 2] - -function query(node, start, end, l, r): - if r < start or end < l: - return 0 // Out of range - if l <= start and end <= r: - return tree[node] // Total overlap - mid = (start + end) / 2 - return query(2 * node + 1, start, mid, l, r) + - query(2 * node + 2, mid + 1, end, l, r) // Partial overlap - -function update(node, start, end, idx, val): - if start == end: - tree[node] = val // Update leaf node - else: - mid = (start + end) / 2 - if start <= idx <= mid: - update(2 * node + 1, start, mid, idx, val) - -``` -### Conclusion - -Segment Trees are an essential data structure for efficiently handling dynamic array queries and updates. They provide a systematic approach to managing ranges and are widely used in algorithmic competitions and software development. diff --git a/docs/algorithms/ Edmonds-Karp Algorithm/ edmonds-karp-algorithm.md b/docs/algorithms/ Edmonds-Karp Algorithm/ edmonds-karp-algorithm.md deleted file mode 100644 index df021b6eb..000000000 --- a/docs/algorithms/ Edmonds-Karp Algorithm/ edmonds-karp-algorithm.md +++ /dev/null @@ -1,203 +0,0 @@ ---- -id: Edmonds-Karp-Algorithm -sidebar_position: 4 -title: Edmonds-Karp Algorithm -sidebar_label: Edmonds-Karp Algorithm -description: "The Edmonds-Karp algorithm is a flow network algorithm used to compute the maximum flow between a source and a sink in a flow network. It is an implementation of the Ford-Fulkerson method that uses breadth-first search (BFS) to find augmenting paths." -tags: [graph-theory, edmonds-karp, maximum-flow, ford-fulkerson, bfs, network-flow, algorithm] ---- - - - -The **Edmonds-Karp Algorithm** is an implementation of the Ford-Fulkerson method for computing the maximum flow in a flow network. It specifically uses **Breadth-First Search (BFS)** to find augmenting paths and calculate the maximum flow from a source to a sink node in a given network. This algorithm is commonly used in network flow analysis, including applications in transport, logistics, and matching problems. - - -## Definition - -The Edmonds-Karp algorithm finds the maximum flow in a flow network by using the Ford-Fulkerson method with a Breadth-First Search to identify augmenting paths. By repeatedly finding augmenting paths from the source to the sink and updating the flow along these paths, the algorithm determines the maximum amount of flow that can be sent through the network. - -## Characteristics - -- Uses **Breadth-First Search (BFS)** to find the shortest path in terms of the number of edges from the source to the sink. -- Guarantees that each augmenting path found is the shortest possible path available in the residual graph. -- Suitable for networks with integer capacities, as it terminates after a finite number of augmenting paths. -- Deterministic, with a well-defined upper bound on the number of iterations. - -## Time Complexity - -The time complexity of the Edmonds-Karp algorithm is **O(V * E²)**, where: -- **V** is the number of vertices (nodes) in the graph. -- **E** is the number of edges. - -This complexity arises from the BFS operation used to find paths, which takes **O(E)** time, and each augmenting path increases the flow, resulting in at most **O(V * E)** augmenting paths being processed. - -## Space Complexity - -The space complexity of the Edmonds-Karp algorithm is **O(V + E)**, where: -- **V** is the number of vertices (nodes). -- **E** is the number of edges. - -This space complexity accounts for storing the graph (adjacency list or matrix), residual capacities, and the BFS queue. - -## Approach - -1. **Initialize the Flow Network**: Set the initial flow to 0 for all edges in the network. -2. **Create the Residual Graph**: This graph represents the remaining capacity of each edge after considering the current flow. -3. **BFS to Find Augmenting Path**: Using BFS, find an augmenting path from the source to the sink in the residual graph. -4. **Determine Bottleneck Capacity**: For the found path, determine the maximum flow (bottleneck) that can be added without violating the capacity constraints. -5. **Update Flows and Residual Capacities**: Increase the flow along the path by the bottleneck capacity and update the residual capacities. -6. **Repeat**: Repeat the BFS and path augmentation process until no more augmenting paths can be found from the source to the sink. -7. **Return Maximum Flow**: When no more paths are available, the sum of the flows from the source node to all other connected nodes is the maximum flow. - -## C++ Implementation - -```cpp -#include -#include -#include -#include -using namespace std; - -bool bfs(vector>& residualGraph, int source, int sink, vector& parent) { - int n = residualGraph.size(); - vector visited(n, false); - queue q; - q.push(source); - visited[source] = true; - parent[source] = -1; - - while (!q.empty()) { - int u = q.front(); - q.pop(); - - for (int v = 0; v < n; v++) { - if (!visited[v] && residualGraph[u][v] > 0) { - q.push(v); - parent[v] = u; - visited[v] = true; - if (v == sink) return true; - } - } - } - return false; -} - -int edmondsKarp(vector>& graph, int source, int sink) { - int u, v; - int n = graph.size(); - vector> residualGraph = graph; - vector parent(n); - int maxFlow = 0; - - while (bfs(residualGraph, source, sink, parent)) { - int pathFlow = INT_MAX; - - for (v = sink; v != source; v = parent[v]) { - u = parent[v]; - pathFlow = min(pathFlow, residualGraph[u][v]); - } - - for (v = sink; v != source; v = parent[v]) { - u = parent[v]; - residualGraph[u][v] -= pathFlow; - residualGraph[v][u] += pathFlow; - } - - maxFlow += pathFlow; - } - - return maxFlow; -} - -int main() { - vector> graph = { - {0, 16, 13, 0, 0, 0}, - {0, 0, 10, 12, 0, 0}, - {0, 4, 0, 0, 14, 0}, - {0, 0, 9, 0, 0, 20}, - {0, 0, 0, 7, 0, 4}, - {0, 0, 0, 0, 0, 0} - }; - - cout << "The maximum possible flow is " << edmondsKarp(graph, 0, 5) << endl; - return 0; -} -``` - -## Java Implementation - -```java -import java.util.LinkedList; -import java.util.Queue; - -public class EdmondsKarp { - static final int V = 6; - - boolean bfs(int[][] residualGraph, int source, int sink, int[] parent) { - boolean[] visited = new boolean[V]; - Queue queue = new LinkedList<>(); - queue.add(source); - visited[source] = true; - parent[source] = -1; - - while (!queue.isEmpty()) { - int u = queue.poll(); - - for (int v = 0; v < V; v++) { - if (!visited[v] && residualGraph[u][v] > 0) { - queue.add(v); - parent[v] = u; - visited[v] = true; - if (v == sink) return true; - } - } - } - return false; - } - - int edmondsKarp(int[][] graph, int source, int sink) { - int u, v; - int[][] residualGraph = new int[V][V]; - - for (u = 0; u < V; u++) - for (v = 0; v < V; v++) - residualGraph[u][v] = graph[u][v]; - - int[] parent = new int[V]; - int maxFlow = 0; - - while (bfs(residualGraph, source, sink, parent)) { - int pathFlow = Integer.MAX_VALUE; - - for (v = sink; v != source; v = parent[v]) { - u = parent[v]; - pathFlow = Math.min(pathFlow, residualGraph[u][v]); - } - - for (v = sink; v != source; v = parent[v]) { - u = parent[v]; - residualGraph[u][v] -= pathFlow; - residualGraph[v][u] += pathFlow; - } - - maxFlow += pathFlow; - } - - return maxFlow; - } - - public static void main(String[] args) { - int[][] graph = { - {0, 16, 13, 0, 0, 0}, - {0, 0, 10, 12, 0, 0}, - {0, 4, 0, 0, 14, 0}, - {0, 0, 9, 0, 0, 20}, - {0, 0, 0, 7, 0, 4}, - {0, 0, 0, 0, 0, 0} - }; - - EdmondsKarp ek = new EdmondsKarp(); - System.out.println("The maximum possible flow is " + ek.edmondsKarp(graph, 0, 5)); - } -} -``` diff --git a/docs/algorithms/Application-of-Recursion.md b/docs/algorithms/Application-of-Recursion.md deleted file mode 100644 index 227443a40..000000000 --- a/docs/algorithms/Application-of-Recursion.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: recursion-applications -title: Applications of Recursion -sidebar_label: Applications of Recursion -sidebar_position: 17 -description: "Applications of Recursion in various fields, including algorithm design, problem-solving, and real-world use cases." -tags: [Algorithm, Recursion, Applications, Programming] ---- - -# Applications of Recursion - -Recursion is a powerful programming technique where a function calls itself to solve a problem. It is widely used in many fields such as algorithm design, data structure manipulation, and problem-solving. Recursion simplifies complex problems by breaking them down into smaller, more manageable subproblems. - -## Applications - -### 1. Tree Traversal - - **Description**: Recursion is commonly used to traverse tree-like structures such as binary trees, search trees, and directory structures. - - **Details**: Recursive functions are used to visit each node of the tree (in-order, pre-order, post-order) and perform operations like searching or printing. - - **Real-World Use**: File system directory traversal, decision tree algorithms, and expression evaluation. - -### 2. Sorting Algorithms (QuickSort and MergeSort) - - **Description**: Recursion plays a key role in divide-and-conquer sorting algorithms like QuickSort and MergeSort. - - **Details**: These algorithms recursively divide the data set into smaller partitions or subarrays and then sort them. - - **Real-World Use**: Efficient sorting of large datasets, widely used in databases, and in sorting large-scale data in applications like analytics and data processing. - -### 3. Fibonacci Sequence Calculation - - **Description**: Recursion is a natural fit for computing Fibonacci numbers, where each number is the sum of the previous two numbers. - - **Details**: The recursive formula is simple: `F(n) = F(n-1) + F(n-2)`. Each Fibonacci number can be calculated by solving the problem for smaller values. - - **Real-World Use**: Used in algorithmic problems and as a base case in dynamic programming problems. - -### 4. Solving Puzzles (e.g., N-Queens Problem) - - **Description**: Many combinatorial problems, such as the N-Queens problem, use recursion to explore all possible configurations and find solutions. - - **Details**: Recursion helps in exploring different possibilities and backtracking when an invalid solution is found. - - **Real-World Use**: Solving optimization problems, puzzles, and games like Sudoku. - -### 5. Pathfinding Algorithms (e.g., Depth-First Search) - - **Description**: Recursion is used in graph traversal algorithms like Depth-First Search (DFS) to explore paths in graphs or grids. - - **Details**: DFS visits a node, and recursively explores all its neighbors until a solution or goal is found. - - **Real-World Use**: Pathfinding in mazes, artificial intelligence in games, and network routing algorithms. - -### 6. Factorial Calculation - - **Description**: Recursion is commonly used to calculate the factorial of a number. - - **Details**: The factorial of a number `n` is defined as `n * factorial(n-1)`, with the base case being `factorial(0) = 1`. - - **Real-World Use**: Used in mathematical and statistical calculations, and in algorithmic problem solving. - -### 7. Backtracking Algorithms (e.g., Subset Sum, Permutations) - - **Description**: Recursion is a key component of backtracking algorithms, where a problem is solved by trying out different possibilities and reverting when a path leads to a dead end. - - **Details**: Each recursive call explores one possibility, and if it fails, the algorithm backtracks to try another. - - **Real-World Use**: Solving problems like the Subset Sum, permutations, and generating combinations. - -### 8. Divide and Conquer Algorithms - - **Description**: Divide and conquer algorithms use recursion to break a problem down into smaller subproblems, solve them independently, and then combine their solutions. - - **Details**: Algorithms like MergeSort, QuickSort, and Binary Search use recursion to divide the problem space. - - **Real-World Use**: Used in sorting, searching, and optimization problems where a large problem can be divided into smaller, easier-to-solve problems. - -Recursion is a versatile technique that simplifies complex problems and enhances problem-solving capabilities. It is fundamental in algorithm design and is widely used in various real-world applications, including sorting, searching, and puzzle solving. diff --git a/docs/algorithms/Application-of-linked-list.md b/docs/algorithms/Application-of-linked-list.md deleted file mode 100644 index 817de710f..000000000 --- a/docs/algorithms/Application-of-linked-list.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -id: linked-list-applications -title: Applications of Linked List -sidebar_label: Applications of Linked List -sidebar_position: 16 -description: "Applications of Linked List in various fields including data structures, operating systems, and dynamic memory allocation." -tags: [Data Structure, Linked List, Applications, Programming] ---- - -# Applications of Linked List - -Linked lists are a fundamental data structure widely used in various fields such as data management, operating systems, and memory allocation. Their ability to dynamically manage memory and facilitate efficient insertions and deletions makes them ideal for numerous applications. - -## Applications - -### 1. Implementing Stacks and Queues - - **Description**: Linked lists are used to create stack (LIFO) and queue (FIFO) data structures. - - **Details**: - - In stacks, nodes are added or removed only from the top, enabling `push` and `pop` operations. - - In queues, nodes are added at the tail and removed from the head. - - **Real-World Use**: Call stacks, task scheduling, and handling job queues in software systems. - -### 2. Browser History Management - - **Description**: Doubly linked lists are used to store browsing history. - - **Details**: Each visited page is a node, with links to the previous and next pages for easy navigation. - - **Real-World Use**: The "back" and "forward" functions in web browsers work by moving between nodes in a linked list. - -### 3. Undo/Redo Functionality in Text Editors - - **Description**: Linked lists store sequences of actions for undo/redo features. - - **Details**: Each action is saved as a node, allowing reversal (undo) or reapplication (redo) of changes. - - **Real-World Use**: Code editors and word processors like Microsoft Word use this for user actions. - -### 4. Dynamic Memory Allocation - - **Description**: Linked lists are used in memory management to track free and allocated memory blocks. - - **Details**: Each memory block points to the next, allowing programs to efficiently request and release memory. - - **Real-World Use**: Memory management functions in C, such as `malloc` and `free`, rely on linked lists. - -### 5. Polynomial Manipulation - - **Description**: Linked lists represent polynomials for efficient operations. - - **Details**: Each term of a polynomial is a node, making addition, subtraction, and multiplication easy. - - **Real-World Use**: Scientific computing applications and symbolic math tools rely on this for polynomial operations. - -### 6. File Allocation Table (FAT) in File Systems - - **Description**: Linked lists manage non-contiguous storage in the FAT file system. - - **Details**: Each block in a file points to the next, allowing fragmented files to be stored on disk. - - **Real-World Use**: USB drives and SD cards use FAT, especially in non-contiguous storage situations. - -### 7. Operating System Process Scheduling - - **Description**: Linked lists manage the queue of processes waiting for CPU time. - - **Details**: Each process in the queue is a node, enabling efficient process addition and removal. - - **Real-World Use**: Linux and Windows use linked lists for managing process scheduling. - -### 8. Sparse Matrix Representation - - **Description**: Linked lists efficiently store sparse matrices by holding only non-zero elements. - - **Details**: Each non-zero element is stored as a node with its row, column, and value. - - **Real-World Use**: Used in scientific computing and machine learning applications for sparse data. - -Linked lists provide efficient ways to manage data dynamically, making them indispensable for data structure implementations, memory management, and various software applications. diff --git a/docs/algorithms/Bentley-Ottmann-Algorithm/bentley-ottmann-algo.md b/docs/algorithms/Bentley-Ottmann-Algorithm/bentley-ottmann-algo.md deleted file mode 100644 index e31901809..000000000 --- a/docs/algorithms/Bentley-Ottmann-Algorithm/bentley-ottmann-algo.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: Bentley-Ottmann-Algorithm -sidebar_position: 17 -title: "Bentley-Ottmann Algorithm" -sidebar_label: Bentley-Ottmann Algorithm ---- -### Definition - -The **Bentley-Ottmann Algorithm** is a sweep line algorithm designed to detect all intersections within a set of line segments in 2D space. By maintaining a global event-driven structure, it optimally processes line segments to efficiently find intersections in \( O((n + k) \log n) \) time, where \( n \) is the number of line segments and \( k \) is the number of intersections. - - -### Characteristics - -- **Algorithm Type**: Sweep line -- **Event-driven**: Uses events for segment endpoints and intersection points. -- **Data Structures**: Priority queue (for event management) and a balanced binary search tree (for active segment management). -- **Output**: Reports all intersection points in the input set of line segments. - -### Time Complexity - -- **Average Case**: \( O((n + k) \log n) \), where \( n \) is the number of line segments and \( k \) is the number of intersections found. -- **Worst Case**: \( O(n^2 \log n) \) if \( k \) approaches \( n^2 \) (as in the case of nearly all segments intersecting each other). - - -### Space Complexity - -- **Space Complexity**: \( O(n + k) \), due to storage for the event queue and the active segments. - - -### Approach - -1. **Initialize Events**: Create an event queue with two types of events—**start** and **end** events for each segment, and **intersection** events when they are detected. - -2. **Process Events in Order**: - - **Start Event**: When a segment’s starting point is reached, add the segment to the active segments list (a balanced binary search tree). - - **End Event**: When a segment’s end point is reached, remove the segment from the active list. - - **Intersection Event**: When two segments intersect, create an intersection event, add it to the event queue if not already present, and report the intersection. - -3. **Update Active Segments**: For each new intersection, update the order of active segments to ensure subsequent intersections are detected. - -4. **Output Intersections**: Report intersections when they occur, along with the coordinates. - ---- - -### C++ Implementation - -```cpp -#include -#include -#include -#include - -struct Point { - double x, y; - bool operator<(const Point &p) const { - return x < p.x || (x == p.x && y < p.y); - } -}; - -struct Segment { - Point start, end; - bool operator<(const Segment &s) const { - return start < s.start || (start == s.start && end < s.end); - } -}; - -// Comparator for events -struct Event { - Point point; - Segment* segment; - enum Type { START, END, INTERSECTION } type; - - bool operator<(const Event &e) const { - return point < e.point; - } -}; - -std::vector findIntersections(std::vector &segments) { - std::priority_queue eventQueue; - std::set activeSegments; - std::vector intersections; - - // Add start and end events for all segments - for (Segment &segment : segments) { - eventQueue.push({segment.start, &segment, Event::START}); - eventQueue.push({segment.end, &segment, Event::END}); - } - - while (!eventQueue.empty()) { - Event event = eventQueue.top(); - eventQueue.pop(); - - if (event.type == Event::START) { - activeSegments.insert(*event.segment); - // Check for intersections with neighboring segments - } else if (event.type == Event::END) { - activeSegments.erase(*event.segment); - } - } - - return intersections; -} -``` - - ---- - -### Java Implementation - -```java -import java.util.*; - -class Point implements Comparable { - double x, y; - Point(double x, double y) { - this.x = x; - this.y = y; - } - public int compareTo(Point other) { - if (this.x != other.x) return Double.compare(this.x, other.x); - return Double.compare(this.y, other.y); - } -} - -class Segment implements Comparable { - Point start, end; - Segment(Point start, Point end) { - this.start = start; - this.end = end; - } - public int compareTo(Segment other) { - return this.start.compareTo(other.start); - } -} - -class Event implements Comparable { - Point point; - Segment segment; - enum Type { START, END, INTERSECTION } - Type type; - - Event(Point point, Segment segment, Type type) { - this.point = point; - this.segment = segment; - this.type = type; - } - - public int compareTo(Event other) { - return this.point.compareTo(other.point); - } -} - -public class BentleyOttmann { - public static List findIntersections(List segments) { - PriorityQueue eventQueue = new PriorityQueue<>(); - TreeSet activeSegments = new TreeSet<>(); - List intersections = new ArrayList<>(); - - for (Segment segment : segments) { - eventQueue.add(new Event(segment.start, segment, Event.Type.START)); - eventQueue.add(new Event(segment.end, segment, Event.Type.END)); - } - - while (!eventQueue.isEmpty()) { - Event event = eventQueue.poll(); - if (event.type == Event.Type.START) { - activeSegments.add(event.segment); - // Check for intersections with neighboring segments - } else if (event.type == Event.Type.END) { - activeSegments.remove(event.segment); - } - } - - return intersections; - } - - public static void main(String[] args) { - List segments = Arrays.asList( - new Segment(new Point(1, 1), new Point(4, 4)), - new Segment(new Point(1, 4), new Point(4, 1)) - ); - List intersections = findIntersections(segments); - intersections.forEach(p -> System.out.println("(" + p.x + ", " + p.y + ")")); - } -} -``` diff --git a/docs/algorithms/CNN-deep-learning-algorithm.md b/docs/algorithms/CNN-deep-learning-algorithm.md deleted file mode 100644 index a2c4c294b..000000000 --- a/docs/algorithms/CNN-deep-learning-algorithm.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -id: cnn-deep-learning-algorithm -title: CNN Deep Learning Algorithm -sidebar_label: CNN Deep Learning Algorithm -sidebar_position: 16 -description: "Convolutional Neural Networks (CNNs) are specialized deep learning architectures that are particularly effective for image processing tasks due to their ability to capture spatial hierarchies in data." -tags: [Deep Learning, Convolutional Neural Networks, CNN, Image Processing] ---- - -# CNN Deep Learning Algorithm - -## Overview -**Convolutional Neural Networks (CNNs)** are a class of deep learning models that are highly effective for image processing tasks. By leveraging convolutional layers, CNNs capture spatial features, making them ideal for applications like image classification, object detection, and segmentation. - -## Problem Description -- **Input**: An image or batch of images. - - The model aims to recognize specific features within the image, such as edges, textures, or objects, depending on the application. -- **Output**: A set of class predictions, feature maps, or bounding boxes (in the case of object detection). -- **Challenges**: The model must detect and represent spatial hierarchies effectively, handling large amounts of data without significant performance degradation. - -## Solution Approach -CNNs are composed of multiple layers, including convolutional layers, pooling layers, and fully connected layers, each serving a distinct purpose in feature extraction and classification. - -### Key Steps -1. **Convolutional Layer**: Applies a set of filters (kernels) across the image to extract features, such as edges or textures. -2. **Activation Function**: A non-linear function (usually ReLU) is applied after each convolution to introduce non-linearity, allowing the model to learn complex patterns. -3. **Pooling Layer**: Downsamples the feature maps, reducing dimensionality and retaining the most prominent features, making the model less sensitive to spatial translations. -4. **Fully Connected Layer**: Transforms the extracted features into a classification output by connecting each neuron to all neurons in the previous layer. -5. **Softmax/Output Layer**: Outputs the final classification probabilities or other predictions. - -## Code Example (CNN for Image Classification in PyTorch) -Below is a sample implementation of a CNN for image classification in PyTorch. - -```python -import torch -import torch.nn as nn -import torch.optim as optim -import torchvision.transforms as transforms -import torchvision.datasets as datasets - -class SimpleCNN(nn.Module): - def __init__(self, num_classes=10): - super(SimpleCNN, self).__init__() - self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1) - self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) - self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0) - self.fc1 = nn.Linear(64 * 8 * 8, 512) - self.fc2 = nn.Linear(512, num_classes) - - def forward(self, x): - x = self.pool(torch.relu(self.conv1(x))) - x = self.pool(torch.relu(self.conv2(x))) - x = x.view(-1, 64 * 8 * 8) - x = torch.relu(self.fc1(x)) - x = self.fc2(x) - return x - -# Example usage -model = SimpleCNN(num_classes=10) # CIFAR-10 dataset -transform = transforms.Compose([transforms.Resize((32, 32)), transforms.ToTensor()]) -train_dataset = datasets.CIFAR10(root='./data', train=True, transform=transform, download=True) -train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True) - -# Training Loop -criterion = nn.CrossEntropyLoss() -optimizer = optim.Adam(model.parameters(), lr=0.001) -for images, labels in train_loader: - outputs = model(images) - loss = criterion(outputs, labels) - optimizer.zero_grad() - loss.backward() - optimizer.step() -``` -## Time Complexity -The complexity of a CNN is determined by the size of the input image, the number of filters, and the number of layers. - -- **Time Complexity**: O(N × K × F × F) - where `N` is the number of images, `K` is the number of filters, and `F` is the filter size. The convolutional and fully connected layers contribute to the overall complexity. - -## Space Complexity -- **Space Complexity**: O(N × D × D × K) - where `N` is the number of images, `D` is the spatial dimension of the image, and `K` is the number of filters. CNNs require storage for the learned filter weights and feature maps at each layer. - -## Applications -- **Image Classification**: Used for recognizing objects, scenes, or other features within an image. -- **Object Detection**: Identifies and localizes objects within images, often used in security and autonomous systems. -- **Medical Imaging**: Detects patterns in medical scans for diagnostics, such as identifying tumors or fractures. -- **Natural Language Processing**: Used for text classification tasks, such as sentiment analysis, by treating text as images or feature matrices. - -## Conclusion -CNNs are a powerful class of models for image processing tasks, effectively capturing spatial hierarchies in data through their layered structure. With the capability to detect and classify objects with high accuracy, CNNs are widely used in diverse applications, from medical imaging to autonomous vehicles. diff --git "a/docs/algorithms/Dijkstra\342\200\231s Algorithm.md" "b/docs/algorithms/Dijkstra\342\200\231s Algorithm.md" deleted file mode 100644 index 79eaa27ad..000000000 --- "a/docs/algorithms/Dijkstra\342\200\231s Algorithm.md" +++ /dev/null @@ -1,143 +0,0 @@ ---- -id: dijkstra-algorithm -sidebar_position: 14 -title: Dijkstra's Algorithm -sidebar_label: Dijkstra's Algorithm -description: "This post covers Dijkstra's Algorithm for finding the shortest paths in a graph, with code examples and explanations." -tags: [dsa, graph, dijkstra, shortest path, c++] ---- - - -# Dijkstra’s Algorithm in C++ - -This project contains a C program that implements Dijkstra’s Algorithm to find the shortest path from a source vertex to all other vertices in a weighted graph. The program takes the number of vertices, edges, and their weights as input, and outputs the shortest distance from the source vertex to each vertex in the graph. - ---- - -## Problem Definition - -**Dijkstra's Algorithm** solves the single-source shortest path problem for graphs with non-negative edge weights. It efficiently finds the shortest path from a starting node to all other nodes in the graph. - -### Example Use Case -Consider a map of cities connected by roads with different distances. Dijkstra's Algorithm can be used to find the shortest path from one city to all others. - ---- - -## Approach - -The algorithm maintains a priority queue to explore the nearest unvisited node at each step, updating the shortest path estimates for neighboring nodes. - -### Key Characteristics: - -1. **Greedy Strategy:** Chooses the node with the smallest tentative distance. -2. **Priority Queue:** Utilizes a min-heap for efficient extraction of the minimum distance node. -3. **Non-negative Weights:** Assumes all edge weights are non-negative. - - --- - -## Dijkstra's Algorithm Operations - -### Graph Representation - -We can represent the graph using an adjacency list. Each entry contains pairs of neighboring nodes and their corresponding edge weights. - -```cpp -#include -#include -#include -#include -#include -using namespace std; -const int INF = numeric_limits::max(); // Represents infinity -using pii = pair; // Pair to represent (weight, vertex) -void dijkstra(int source, const vector>& graph, vector& dist) { - priority_queue, greater> pq; // Min-heap - dist[source] = 0; - pq.push({0, source}); - while (!pq.empty()) { - int d = pq.top().first; // Distance - int u = pq.top().second; // Current node - pq.pop(); - if (d > dist[u]) continue; // Ignore outdated distance - for (const auto& edge : graph[u]) { - int v = edge.first; - int weight = edge.second; - if (dist[u] + weight < dist[v]) { - dist[v] = dist[u] + weight; // Update distance - pq.push({dist[v], v}); // Push new distance to the queue - } - } - } -} -``` ---- - -## Example Usage: - -``` -int main() { - int n = 5; // Number of nodes - vector> graph(n); // Adjacency list - // Add edges: (source, destination, weight) - graph[0].push_back({1, 10}); - graph[0].push_back({2, 3}); - graph[1].push_back({2, 1}); - graph[1].push_back({3, 2}); - graph[2].push_back({1, 4}); - graph[2].push_back({3, 8}); - graph[2].push_back({4, 2}); - graph[3].push_back({4, 7}); - graph[4].push_back({3, 9}); - vector dist(n, INF); // Initialize distances to infinity - dijkstra(0, graph, dist); // Run Dijkstra's from source node 0 - // Print distances from source - for (int i = 0; i < n; ++i) { - cout << "Distance from 0 to " << i << " is " << dist[i] << endl; - } - return 0; -} -``` ---- - -### Output - -``` -Distance from 0 to 0 is 0 -Distance from 0 to 1 is 7 -Distance from 0 to 2 is 3 -Distance from 0 to 3 is 15 -Distance from 0 to 4 is 5 -``` ---- - -## Complexity Analysis - -### Time Complexity - -Worst Case: (O(V^2)), where V is the number of vertices in the graph. -This is because, in the simplest implementation using an array, each vertex is checked against all others to find the minimum distance. - -### Space Complexity - -Space Complexity: (O(V)), where V is the number of vertices. -The program uses an array to store the shortest distances from the source vertex to all other vertices. - -### Assumptions - -The program assumes the graph is connected and contains non-negative weights. -It does not handle negative weight cycles, as Dijkstra's Algorithm is not suitable for graphs with negative weights. - -## When to Use Dijkstra's Algorithm - -**Non-negative weights:** When the graph has non-negative edge weights. -**Single-source shortest path:** When you need the shortest path from one source to all other vertices. -**Real-time applications:** Ideal for applications like GPS navigation systems and network routing. - -## Conclusion - -Dijkstra's Algorithm is a fundamental algorithm in computer science for finding the shortest paths in a weighted graph. Its efficiency and effectiveness make it applicable in various real-world scenarios where optimization is required. - - - - - diff --git a/docs/algorithms/DutchNationalFlag-algorithm/DutchNationalFlag.md b/docs/algorithms/DutchNationalFlag-algorithm/DutchNationalFlag.md deleted file mode 100644 index 0f9eb9abc..000000000 --- a/docs/algorithms/DutchNationalFlag-algorithm/DutchNationalFlag.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: sort-012-dutch-flag -sidebar_position: 14 -title: Sorting 0s, 1s, and 2s with the Dutch National Flag Algorithm -sidebar_label: Dutch National Flag Sorting ---- - -### Overview: - -The **Dutch National Flag Algorithm** is a highly efficient technique to sort an array containing only the elements 0, 1, and 2 in linear time. It utilizes a three-pointer strategy and performs sorting directly on the array, optimizing both time and space. - -### Key Features: - -- **Three Pointers Strategy**: - The algorithm operates using three pointers (`low`, `mid`, and `high`), each having a specific role: - - `low` for positioning 0s - - `mid` for traversal - - `high` for positioning 2s - -- **In-Place Sorting**: - This approach does not require additional memory for sorting, making it space-efficient as the array is sorted in-place. - -- **Optimized for Specific Data**: - Designed specifically for arrays with three distinct elements (0, 1, and 2), the algorithm runs in linear time, making it optimal for such cases. - -### Time Complexity: - -- **Best Case: $O(N)$** - The array is traversed once using the `mid` pointer, providing a linear runtime. - -- **Average Case: $O(N)$** - Even in random input order, the algorithm processes each element a maximum of one time, maintaining linear time. - -- **Worst Case: $O(N)$** - Although multiple swaps may be needed, the time complexity remains linear at $O(N)$, where $N$ is the array length. - -### Space Complexity: - -- **Space Efficiency: $O(1)$** - The algorithm uses constant extra space as it sorts the array in-place without requiring any auxiliary data structures. - -### Algorithm Steps: - -The algorithm follows these steps to partition the array using three pointers (`low`, `mid`, `high`): - -- The range `nums[0]` to `nums[low-1]` holds 0s. -- The range `nums[low]` to `nums[mid-1]` holds 1s. -- The range `nums[high+1]` to `nums[n-1]` holds 2s. - -**Process**: -1. Initialize `low` and `mid` at index 0 and `high` at the last index of the array. -2. While `mid` is less than or equal to `high`, follow these rules: - - If `nums[mid] == 0`, swap it with `nums[low]`, increment both `low` and `mid`. - - If `nums[mid] == 1`, increment `mid` only. - - If `nums[mid] == 2`, swap it with `nums[high]` and decrement `high` without changing `mid`. - -### C++ Code Implementation: - -```cpp -#include -using namespace std; - -class Solution { -public: - // Function to sort an array with only 0s, 1s, and 2s - void sortZeroOneTwo(vector& nums) { - int low = 0, mid = 0, high = nums.size() - 1; - - while (mid <= high) { - if (nums[mid] == 0) { - swap(nums[low], nums[mid]); - low++; - mid++; - } else if (nums[mid] == 1) { - mid++; - } else { - swap(nums[mid], nums[high]); - high--; - } - } - } -}; - - -int main() { - vector nums = {0, 2, 1, 2, 0, 1}; - Solution sol; - sol.sortZeroOneTwo(nums); - - cout << "After sorting: "; - for (int i = 0; i < nums.size(); i++) { - cout << nums[i] << " "; - } - cout << endl; - - return 0; -} -``` \ No newline at end of file diff --git a/docs/algorithms/DutchNationalFlag-algorithm/_category_.json b/docs/algorithms/DutchNationalFlag-algorithm/_category_.json deleted file mode 100644 index 3ee55acc3..000000000 --- a/docs/algorithms/DutchNationalFlag-algorithm/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Dutch National Flag Algorithm", - "position": 5, - "link": { - "type": "generated-index", - "description": "Learn Dutch National Flag Algorithm." - } - } \ No newline at end of file diff --git a/docs/algorithms/Encryption algorithms/Caesar Cipher.md b/docs/algorithms/Encryption algorithms/Caesar Cipher.md deleted file mode 100644 index f39f5f1ab..000000000 --- a/docs/algorithms/Encryption algorithms/Caesar Cipher.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -id: caesar-cipher-implementation -title: Caesar Cipher Implementation -sidebar_label: Caesar Cipher -tags: [Cipher, Encryption, String Manipulation, DSA] -description: A Caesar Cipher shifts each letter in the input string by a given number of positions down or up the alphabet, with non-alphabetic characters remaining unchanged. ---- - -# Caesar Cipher Implementation - -## Description -The Caesar Cipher is a type of substitution cipher where each letter in the plaintext is shifted by a certain number of positions down or up the alphabet. It is one of the simplest and most widely known encryption techniques. - -## Problem Definition -- **Input**: A string `text` and an integer `shift` representing the number of positions each letter should be shifted. -- **Output**: Return the encrypted string by shifting each letter in the input string by the given shift value. Non-alphabetic characters should remain unchanged. - -## Example -- **Input**: - - `text = "HELLO"` - - `shift = 3` - -- **Output**: - - `"KHOOR"` - -- **Input**: - - `text = "caesar cipher"` - - `shift = 2` - -- **Output**: - - `"ecguct ekrjgt"` - -## Algorithm Overview -1. Traverse each character in the input string. -2. If the character is a letter, shift it by the given `shift` value. - - For lowercase letters, ensure it wraps around 'z' to 'a'. - - For uppercase letters, ensure it wraps around 'Z' to 'A'. -3. If the character is non-alphabetic (e.g., spaces, punctuation), leave it unchanged. -4. Return the encrypted string. - -## Time Complexity -- **O(n)** where `n` is the length of the input string. Each character in the string is processed once. - -## C++ Implementation - -```cpp -#include -#include -using namespace std; - -string caesarCipher(string text, int shift) { - string result = ""; - - // Traverse each character in the input string - for (int i = 0; i < text.length(); i++) { - char c = text[i]; - - // Encrypt uppercase letters - if (isupper(c)) { - result += char(int(c + shift - 'A') % 26 + 'A'); - } - // Encrypt lowercase letters - else if (islower(c)) { - result += char(int(c + shift - 'a') % 26 + 'a'); - } - // Leave non-alphabetic characters unchanged - else { - result += c; - } - } - return result; -} - -int main() { - string text = "HELLO"; - int shift = 3; - - cout << "Original text: " << text << endl; - cout << "Encrypted text: " << caesarCipher(text, shift) << endl; - - return 0; -} -``` \ No newline at end of file diff --git a/docs/algorithms/Encryption algorithms/advanced_encryption_standard.md b/docs/algorithms/Encryption algorithms/advanced_encryption_standard.md deleted file mode 100644 index cad2c575d..000000000 --- a/docs/algorithms/Encryption algorithms/advanced_encryption_standard.md +++ /dev/null @@ -1,98 +0,0 @@ ---- - -id: advanced-encryption-standard -sidebar_position: 4 -title: Advanced Encryption Standard (AES) -sidebar_label: Advanced Encryption Standard - ---- - -### Definition: - -The Advanced Encryption Standard (AES) is a symmetric encryption algorithm established by the U.S. National Institute of Standards and Technology (NIST) in 2001. AES is widely used for secure data transmission and is recognized for its strength and efficiency. - -### Characteristics: - -- **Symmetric Key Algorithm**: - - AES uses the same key for both encryption and decryption, making key management essential. The security of AES relies on the secrecy of the key. - -- **Block Cipher**: - - AES operates on fixed-size blocks of data. It encrypts data in 128-bit blocks, using keys of 128, 192, or 256 bits, offering different levels of security. - -- **Efficient Performance**: - - AES is designed for efficiency on both hardware and software platforms, making it suitable for a wide range of applications, from small devices to large-scale data centers. - -- **Strong Security**: - - AES is considered secure against all known practical attacks, including brute force, making it a standard choice for sensitive data encryption. - -### Time Complexity: - -- **Encryption/Decryption Time**: $O(n)$ - The time complexity for AES operations is linear in relation to the number of blocks being processed. - -### Space Complexity: - -- **Space Complexity**: $O(n)$ - AES requires space proportional to the block size (128 bits) and additional space for key management, depending on the implementation. - -### AES Modes of Operation: - -1. **ECB (Electronic Codebook)**: - - The simplest mode, where each block is encrypted independently. It is not recommended for encrypting large amounts of data due to patterns in identical plaintext blocks. - -2. **CBC (Cipher Block Chaining)**: - - Each block of plaintext is XORed with the previous ciphertext block before being encrypted. It enhances security by making identical plaintext blocks encrypt to different ciphertexts. - -3. **CFB (Cipher Feedback)**: - - Similar to CBC, but it allows encryption of data in smaller increments (e.g., bytes). It is suitable for streaming applications. - -4. **GCM (Galois/Counter Mode)**: - - A mode that combines counter mode encryption with Galois mode authentication, providing both confidentiality and integrity. - -### C++ Implementation of AES (Using OpenSSL): - -```cpp -#include -#include -#include -#include - -void aesEncrypt(const unsigned char *key, const unsigned char *plaintext, unsigned char *ciphertext) { - AES_KEY encryptKey; - AES_set_encrypt_key(key, 128, &encryptKey); - AES_encrypt(plaintext, ciphertext, &encryptKey); -} - -void aesDecrypt(const unsigned char *key, const unsigned char *ciphertext, unsigned char *plaintext) { - AES_KEY decryptKey; - AES_set_decrypt_key(key, 128, &decryptKey); - AES_decrypt(ciphertext, plaintext, &decryptKey); -} - -int main() { - unsigned char key[16]; // AES key size is 128 bits (16 bytes) - unsigned char plaintext[16] = "Hello, World!!!"; // Must be 16 bytes for AES - unsigned char ciphertext[16], decryptedtext[16]; - - // Generate random AES key - RAND_bytes(key, sizeof(key)); - - // Encrypt - aesEncrypt(key, plaintext, ciphertext); - std::cout << "Ciphertext: "; - for (int i = 0; i < 16; ++i) { - std::cout << std::hex << static_cast(ciphertext[i]); - } - std::cout << std::endl; - - // Decrypt - aesDecrypt(key, ciphertext, decryptedtext); - std::cout << "Decrypted text: " << decryptedtext << std::endl; - - return 0; -} -``` - -### Summary: - -The Advanced Encryption Standard (AES) is a robust and efficient symmetric encryption algorithm widely used across various applications for secure data transmission. With support for different key lengths and various modes of operation, AES provides a flexible solution for protecting sensitive information against unauthorized access. Its strong security and performance characteristics make it a standard choice in the field of cryptography. diff --git a/docs/algorithms/Encryption algorithms/asymmetric_encryption.md b/docs/algorithms/Encryption algorithms/asymmetric_encryption.md deleted file mode 100644 index f87b3d672..000000000 --- a/docs/algorithms/Encryption algorithms/asymmetric_encryption.md +++ /dev/null @@ -1,78 +0,0 @@ ---- - -id: asymmetric-encryption-algo -sidebar_position: 2 -title: Asymmetric Encryption -sidebar_label: Asymmetric Encryption - ---- - -### Definition: - -Asymmetric encryption, also known as public-key cryptography, is a type of encryption that uses a pair of keys: a public key and a private key. The public key is used for encryption, while the private key is used for decryption. This allows secure communication without the need to share a secret key. - -### Characteristics: - -- **Key Pair**: - - Asymmetric encryption uses two keys: a public key, which can be shared openly, and a private key, which must be kept secret. This separation enhances security. - -- **Security**: - - The security of asymmetric encryption relies on mathematical problems, such as factoring large integers or solving discrete logarithms, which are computationally difficult to solve. - -- **Digital Signatures**: - - Asymmetric encryption enables the creation of digital signatures, allowing a sender to verify their identity and the integrity of the message. - -- **Slower Performance**: - - Asymmetric algorithms are generally slower than symmetric algorithms, making them less suitable for encrypting large amounts of data. They are often used to encrypt a symmetric key, which is then used for bulk encryption. - -### Time Complexity: - -- **Encryption/Decryption Time**: $O(n²)$ - The time complexity for asymmetric encryption and decryption can vary significantly based on the algorithm and the key size. Generally, it is slower than symmetric encryption. - -### Space Complexity: - -- **Space Complexity**: $O(n)$ - Asymmetric encryption requires additional space for storing both keys (public and private), which can be proportional to the size of the data being encrypted. - -### Common Asymmetric Encryption Algorithms: - -1. **RSA (Rivest-Shamir-Adleman)**: - - A widely used asymmetric algorithm that relies on the difficulty of factoring the product of two large prime numbers. RSA is commonly used for secure data transmission and digital signatures. - -2. **DSA (Digital Signature Algorithm)**: - - An algorithm used for digital signatures that relies on the mathematical concept of discrete logarithms. DSA is used in various security protocols. - -3. **Elliptic Curve Cryptography (ECC)**: - - A form of public-key cryptography based on the algebraic structure of elliptic curves over finite fields. ECC provides similar security to RSA with smaller key sizes, making it efficient for mobile and embedded systems. - -### C++ Implementation of Asymmetric Encryption (RSA Example): - -```cpp -#include -#include -#include - -void generateKeyPair() { - RSA *rsa = RSA_generate_key(2048, RSA_F4, nullptr, nullptr); - BIO *bpPublic = BIO_new_file("public.pem", "w+"); - BIO *bpPrivate = BIO_new_file("private.pem", "w+"); - - PEM_write_bio_RSAPublicKey(bpPublic, rsa); - PEM_write_bio_RSAPrivateKey(bpPrivate, rsa, nullptr, nullptr, 0, nullptr, nullptr); - - BIO_free_all(bpPublic); - BIO_free_all(bpPrivate); - RSA_free(rsa); -} - -int main() { - generateKeyPair(); - std::cout << "RSA key pair generated and saved to public.pem and private.pem." << std::endl; - return 0; -} -``` - -### Summary: - -Asymmetric encryption is a fundamental concept in modern cryptography, enabling secure communication and data integrity without the need to share a secret key. By leveraging a public-private key pair, asymmetric algorithms like RSA, DSA, and ECC provide strong security, though they are typically slower than symmetric algorithms. Asymmetric encryption plays a crucial role in various security protocols, including SSL/TLS for secure web communications. diff --git a/docs/algorithms/Encryption algorithms/blockchain_encryption.md b/docs/algorithms/Encryption algorithms/blockchain_encryption.md deleted file mode 100644 index a1352d6c6..000000000 --- a/docs/algorithms/Encryption algorithms/blockchain_encryption.md +++ /dev/null @@ -1,99 +0,0 @@ ---- - -id: blockchain-cryptography-algo -sidebar_position: 8 -title: Blockchain Cryptography -sidebar_label: Blockchain Cryptography - ---- - -### Definition: - -Blockchain cryptography refers to the cryptographic algorithms and techniques used to secure and verify the integrity of transactions in blockchain systems. These cryptographic methods ensure that data within the blockchain is tamper-proof, decentralized, and transparent, enabling trust between parties without the need for intermediaries. - -### Characteristics: - -- **Immutable Ledger**: - - Cryptography ensures that once data is added to the blockchain, it cannot be altered or deleted without consensus, maintaining an immutable and transparent ledger. - -- **Decentralization**: - - Blockchain cryptography allows for decentralized trust, eliminating the need for central authorities or intermediaries to verify transactions. - -- **Hash Functions**: - - Cryptographic hash functions are essential in blockchain to secure block information, verify data integrity, and create unique digital fingerprints for each block. - -- **Digital Signatures**: - - Digital signatures using asymmetric cryptography ensure the authenticity of transactions, allowing users to sign transactions with their private keys, which can be verified with their public keys. - -- **Common Algorithms**: - - Algorithms like SHA-256 (used in Bitcoin), ECDSA (Elliptic Curve Digital Signature Algorithm), and other cryptographic techniques are commonly used in blockchain systems to secure data and transactions. - -### Time Complexity: - -- **Hashing Time**: $O(n)$ - The time complexity of hashing in blockchain is linear in relation to the size of the data being hashed. SHA-256, for example, processes blocks of data in constant time per block. - -- **Verification Time**: $O(1)$ - Verifying digital signatures or hashes is generally constant-time, making it efficient for validating transactions and data integrity in blockchain systems. - -### Space Complexity: - -- **Space Complexity**: $O(n)$ - Blockchain systems store hashed data, transaction signatures, and block information. The space complexity is proportional to the number of blocks, transactions, and data stored. - -### Cryptographic Algorithms in Blockchain: - -1. **SHA-256 (Secure Hash Algorithm 256-bit)**: - - SHA-256 is a cryptographic hash function used to secure and link blocks in Bitcoin and other blockchains. It produces a 256-bit hash, ensuring data integrity and tamper-resistance. - -2. **ECDSA (Elliptic Curve Digital Signature Algorithm)**: - - ECDSA is a public key cryptographic algorithm used for generating and verifying digital signatures in blockchain networks, offering security with smaller key sizes than RSA. - -3. **Merkle Trees**: - - Merkle trees use hashing to efficiently verify large amounts of data in a blockchain. Each leaf node is hashed, and then their hashes are combined pairwise to form parent hashes, creating a single root hash that represents all transactions. - -4. **Public/Private Key Cryptography**: - - In blockchain, a public-private key pair is used for authentication. Users sign transactions with their private keys, and the network verifies these transactions using the public key, ensuring data authenticity. - -### C++ Implementation of Blockchain Cryptography (SHA-256 Example): - -```cpp -#include -#include -#include -#include -#include - -// Function to calculate the SHA-256 hash of a given input string -std::string sha256(const std::string& input) { - unsigned char hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha256; - SHA256_Init(&sha256); - SHA256_Update(&sha256, input.c_str(), input.size()); - SHA256_Final(hash, &sha256); - - std::stringstream ss; - for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) { - ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i]; - } - return ss.str(); -} - -int main() { - std::string input = "Blockchain Example"; - std::string output = sha256(input); - - std::cout << "Input: " << input << std::endl; - std::cout << "SHA-256 Hash: " << output << std::endl; - - return 0; -} -``` - -### Explanation: - -- **SHA-256 Hashing**: This C++ implementation demonstrates how to use the OpenSSL library to calculate the SHA-256 hash of a given input string. Hashing is a fundamental part of blockchain cryptography, securing the integrity of each block's data. - -### Summary: - -Blockchain cryptography is the backbone of blockchain technology, ensuring the security, integrity, and decentralization of the system. By employing techniques like hash functions, digital signatures, and public/private key cryptography, blockchain creates an immutable and transparent ledger for secure data storage and transactions. Cryptographic algorithms like SHA-256 and ECDSA are foundational in enabling the trustless and decentralized nature of blockchain systems. As blockchain continues to evolve, cryptographic methods will remain crucial for maintaining its security and resilience against attacks. \ No newline at end of file diff --git a/docs/algorithms/Encryption algorithms/elliptic_curve_cryptography.md b/docs/algorithms/Encryption algorithms/elliptic_curve_cryptography.md deleted file mode 100644 index 54e6328b2..000000000 --- a/docs/algorithms/Encryption algorithms/elliptic_curve_cryptography.md +++ /dev/null @@ -1,83 +0,0 @@ ---- - -id: elliptic-curve-cryptography -sidebar_position: 3 -title: Elliptic Curve Cryptography (ECC) -sidebar_label: Elliptic Curve Cryptography - ---- - -### Definition: - -Elliptic Curve Cryptography (ECC) is a form of public-key cryptography based on the algebraic structure of elliptic curves over finite fields. ECC provides a high level of security with smaller key sizes compared to other asymmetric encryption methods, making it efficient for use in various applications, particularly in mobile and embedded systems. - -### Characteristics: - -- **Key Size Efficiency**: - - ECC offers the same level of security as other public-key algorithms (like RSA) with significantly smaller key sizes. For example, a 256-bit key in ECC is considered equivalent in security to a 3072-bit RSA key. - -- **Mathematical Foundation**: - - ECC is based on the properties of elliptic curves and finite fields. The difficulty of solving the Elliptic Curve Discrete Logarithm Problem (ECDLP) underpins its security. - -- **Performance**: - - Due to smaller key sizes, ECC is faster in both encryption and decryption processes compared to traditional methods, making it suitable for environments with limited processing power and storage. - -- **Digital Signatures**: - - ECC can be used for creating digital signatures through algorithms like ECDSA (Elliptic Curve Digital Signature Algorithm), which is widely used in various security protocols. - -### Time Complexity: - -- **Encryption/Decryption Time**: $O(n)$ - The time complexity for ECC operations can vary based on the implementation and the curve used. Generally, ECC operations are more efficient than those of RSA for equivalent security levels. - -### Space Complexity: - -- **Space Complexity**: $O(n)$ - ECC requires space for storing the private key, public key, and the elliptic curve parameters, typically proportional to the key size. - -### Common Elliptic Curve Cryptography Algorithms: - -1. **ECDSA (Elliptic Curve Digital Signature Algorithm)**: - - A variant of the Digital Signature Algorithm (DSA) that uses elliptic curves for signing and verifying messages. - -2. **ECDH (Elliptic Curve Diffie-Hellman)**: - - A key exchange protocol that allows two parties to generate a shared secret over an insecure channel using elliptic curves. - -3. **ECIES (Elliptic Curve Integrated Encryption Scheme)**: - - A hybrid encryption scheme that combines the security of ECC with symmetric encryption, providing confidentiality and integrity. - -### C++ Implementation of ECC (Using OpenSSL for ECDSA): - -```cpp -#include -#include -#include -#include - -void generateKeyPair() { - EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp256k1); - EC_KEY_generate_key(key); - - // Save private key to file - FILE *privateKeyFile = fopen("private_key.pem", "wb"); - PEM_write_ECPrivateKey(privateKeyFile, key, nullptr, nullptr, 0, nullptr, nullptr); - fclose(privateKeyFile); - - // Save public key to file - FILE *publicKeyFile = fopen("public_key.pem", "wb"); - PEM_write_ECPublicKey(publicKeyFile, key); - fclose(publicKeyFile); - - EC_KEY_free(key); -} - -int main() { - generateKeyPair(); - std::cout << "ECC key pair generated and saved to private_key.pem and public_key.pem." << std::endl; - return 0; -} -``` - -### Summary: - -Elliptic Curve Cryptography (ECC) represents a powerful advancement in the field of public-key cryptography, providing strong security with reduced key sizes and enhanced performance. Its efficiency makes it particularly suitable for constrained environments, and it is widely adopted in modern security protocols. With applications in digital signatures and key exchange, ECC continues to gain popularity as a secure alternative to traditional asymmetric algorithms like RSA. diff --git a/docs/algorithms/Encryption algorithms/hashing.md b/docs/algorithms/Encryption algorithms/hashing.md deleted file mode 100644 index 3df630316..000000000 --- a/docs/algorithms/Encryption algorithms/hashing.md +++ /dev/null @@ -1,87 +0,0 @@ ---- - -id: hashing -sidebar_position: 5 -title: Hashing -sidebar_label: Hashing - ---- - -### Definition: - -Hashing is a process that transforms input data (or a message) into a fixed-size string of characters, which is typically a sequence of numbers and letters. The output, known as the hash value or hash code, is generated by a hash function. Hashing is widely used in various applications, including data integrity verification, password storage, and digital signatures. - -### Characteristics: - -- **Deterministic**: - - The same input will always produce the same hash output. This property allows for consistent verification of data integrity. - -- **Fixed Size**: - - Regardless of the size of the input data, the output hash will always be of a fixed length, making it easier to handle and compare. - -- **Fast Computation**: - - Hash functions are designed to compute hash values quickly, allowing for efficient data processing. - -- **Pre-image Resistance**: - - Given a hash output, it should be computationally infeasible to reverse-engineer the original input, ensuring data confidentiality. - -- **Collision Resistance**: - - It should be difficult to find two different inputs that produce the same hash output, preventing data tampering. - -### Common Hashing Algorithms: - -1. **MD5 (Message Digest 5)**: - - Produces a 128-bit hash value and is widely used for checksums and data integrity. However, it is no longer considered secure against collision attacks. - -2. **SHA-1 (Secure Hash Algorithm 1)**: - - Produces a 160-bit hash value. Like MD5, SHA-1 has vulnerabilities and is not recommended for security-sensitive applications. - -3. **SHA-256**: - - Part of the SHA-2 family, it produces a 256-bit hash value and is widely used in security applications and protocols, including SSL/TLS and Bitcoin. - -4. **bcrypt**: - - A hashing function designed specifically for hashing passwords, incorporating a salt to protect against rainbow table attacks. - -### Time Complexity: - -- **Hash Computation Time**: $O(n)$ - The time complexity for computing a hash value depends on the input size, with most hashing algorithms running in linear time relative to the input length. - -### Space Complexity: - -- **Space Complexity**: $O(1)$ - The output size of a hash function is constant (fixed size), independent of the input size, leading to constant space complexity for storing hash values. - -### C++ Implementation of Hashing (Using SHA-256): - -```cpp -#include -#include -#include -#include - -std::string sha256(const std::string &data) { - unsigned char hash[SHA256_DIGEST_LENGTH]; - SHA256(reinterpret_cast(data.c_str()), data.size(), hash); - - std::ostringstream oss; - for (const auto &byte : hash) { - oss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte); - } - return oss.str(); -} - -int main() { - std::string data = "Hello, World!"; - std::string hashValue = sha256(data); - - std::cout << "Data: " << data << std::endl; - std::cout << "SHA-256 Hash: " << hashValue << std::endl; - - return 0; -} -``` - -### Summary: - -Hashing is a fundamental technique used in computer science and cryptography for data integrity verification, password management, and digital signatures. The use of secure hash functions, such as SHA-256, provides strong security guarantees against common attacks. Understanding hashing and its properties is essential for implementing secure systems and applications. diff --git a/docs/algorithms/Encryption algorithms/homomorphic-encryption.md b/docs/algorithms/Encryption algorithms/homomorphic-encryption.md deleted file mode 100644 index 0f08b6045..000000000 --- a/docs/algorithms/Encryption algorithms/homomorphic-encryption.md +++ /dev/null @@ -1,142 +0,0 @@ ---- - -id: homomorphic-encryption-algo -sidebar_position: 6 -title: Homomorphic Encryption -sidebar_label: Homomorphic Encryption - ---- - -### Definition: - -Homomorphic encryption is an encryption scheme that allows computations to be performed on ciphertext without needing to decrypt it first. This enables data to remain encrypted while still allowing operations such as addition or multiplication to be executed. Once the encrypted result is decrypted, it matches the result of operations as if they were performed on the plaintext. - -### Characteristics: - -- **Computation on Encrypted Data**: - - Homomorphic encryption allows specific operations (such as addition or multiplication) to be performed directly on encrypted data without decrypting it. - -- **Privacy-Preserving**: - - It enables secure data processing by third parties without exposing the actual data. This is especially useful in cloud computing and privacy-preserving machine learning. - -- **Performance Overhead**: - - Homomorphic encryption tends to be slower and more resource-intensive compared to traditional encryption methods like symmetric or asymmetric encryption due to its complex mathematical operations. - -- **Common Algorithms**: - - Popular homomorphic encryption schemes include Paillier encryption (supporting additive homomorphism) and the Brakerski-Gentry-Vaikuntanathan (BGV) scheme (supporting both addition and multiplication). - -### Time Complexity: - -- **Encryption/Decryption Time**: $O(n^2)$ - The time complexity for homomorphic encryption depends on the specific algorithm and the complexity of the homomorphic operations, often quadratic or higher. - -- **Computation Time**: $O(n^2)$ or higher - The time required to perform operations on ciphertexts is typically more complex than plaintext operations due to the need for special encryption techniques. - -### Space Complexity: - -- **Space Complexity**: $O(n)$ to $O(n^2)$ - Homomorphic encryption schemes often require larger ciphertexts, leading to greater space complexity than standard encryption methods. - -### Types of Homomorphic Encryption: - -1. **Paillier Encryption**: - - Paillier encryption is a probabilistic asymmetric algorithm that supports homomorphic addition, where multiplying two ciphertexts results in the encrypted sum of the plaintexts. - -2. **BFV and BGV Schemes**: - - Brakerski-Fan-Vercauteren (BFV) and Brakerski-Gentry-Vaikuntanathan (BGV) schemes support both additive and multiplicative homomorphisms, making them fully homomorphic encryption (FHE) schemes. - -3. **CKKS (Cheon-Kim-Kim-Song)**: - - CKKS is a leveled homomorphic encryption scheme designed for approximate arithmetic, allowing computations over encrypted real numbers. - -### C++ Implementation of Homomorphic Encryption (Paillier Example): - -```cpp -#include -#include // GMP library for large integers -#include - -class Paillier { -public: - mpz_class n, nsquared, g, lambda, mu; - - Paillier() { - // Set up values for Paillier encryption (key generation) - mpz_class p, q; - generate_primes(p, q); - n = p * q; - nsquared = n * n; - g = n + 1; // Simple choice for g - lambda = (p - 1) * (q - 1); - mu = invert(lambda, n); - } - - mpz_class encrypt(mpz_class m) { - mpz_class r; - mpz_urandomm(r.get_mpz_t(), state, n.get_mpz_t()); // Random r < n - mpz_class c = (powmod(g, m, nsquared) * powmod(r, n, nsquared)) % nsquared; - return c; - } - - mpz_class decrypt(mpz_class c) { - mpz_class l = (powmod(c, lambda, nsquared) - 1) / n; - mpz_class m = (l * mu) % n; - return m; - } - - // Add two encrypted values - mpz_class add(mpz_class c1, mpz_class c2) { - return (c1 * c2) % nsquared; - } - -private: - gmp_randstate_t state; - - void generate_primes(mpz_class &p, mpz_class &q) { - gmp_randinit_default(state); - mpz_urandomb(p.get_mpz_t(), state, 512); // Generate random prime p - mpz_urandomb(q.get_mpz_t(), state, 512); // Generate random prime q - mpz_nextprime(p.get_mpz_t(), p.get_mpz_t()); - mpz_nextprime(q.get_mpz_t(), q.get_mpz_t()); - } - - mpz_class powmod(mpz_class base, mpz_class exp, mpz_class mod) { - mpz_class result; - mpz_powm(result.get_mpz_t(), base.get_mpz_t(), exp.get_mpz_t(), mod.get_mpz_t()); - return result; - } - - mpz_class invert(mpz_class a, mpz_class mod) { - mpz_class inv; - mpz_invert(inv.get_mpz_t(), a.get_mpz_t(), mod.get_mpz_t()); - return inv; - } -}; - -int main() { - Paillier paillier; - - mpz_class m1 = 12345; // Plaintext message 1 - mpz_class m2 = 67890; // Plaintext message 2 - - // Encrypt both messages - mpz_class c1 = paillier.encrypt(m1); - mpz_class c2 = paillier.encrypt(m2); - - // Add encrypted values - mpz_class c_sum = paillier.add(c1, c2); - - // Decrypt result - mpz_class m_sum = paillier.decrypt(c_sum); - - std::cout << "Decrypted sum: " << m_sum << std::endl; // Output: 80235 - - return 0; -} -``` - -### Summary: - -Homomorphic encryption is an advanced cryptographic method that allows computation on encrypted data, enabling privacy-preserving applications such as secure cloud computing and confidential machine learning. Although it incurs higher computational and space costs than symmetric or asymmetric encryption, its ability to process data without decryption makes it a powerful tool in modern cryptography. - -Common homomorphic encryption algorithms like Paillier and BGV provide flexibility for secure data processing, offering solutions to data privacy challenges in various industries. \ No newline at end of file diff --git a/docs/algorithms/Encryption algorithms/post-quantum-encryption.md b/docs/algorithms/Encryption algorithms/post-quantum-encryption.md deleted file mode 100644 index fb56e43cc..000000000 --- a/docs/algorithms/Encryption algorithms/post-quantum-encryption.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: post-quantum-encryption-algo -sidebar_position: 7 -title: Post-Quantum Encryption -sidebar_label: Post-Quantum Encryption ---- - -### Definition: - -Post-quantum encryption (PQE) refers to cryptographic algorithms designed to withstand the threat posed by quantum computers. Quantum computers can potentially break current encryption methods (e.g., RSA and ECC) using quantum algorithms like Shor's algorithm. PQE ensures data remains secure in a future where quantum computers are powerful enough to compromise existing cryptography. - -### Characteristics: - -- *Quantum-Resistant*: - - Post-quantum encryption algorithms are developed to be secure against quantum attacks, unlike traditional cryptographic algorithms, which can be easily broken by quantum computers. - -- *Mathematical Complexity*: - - These algorithms rely on mathematical problems that are hard for both classical and quantum computers, such as lattice-based problems, multivariate polynomial problems, and code-based problems. - -- *Larger Key Sizes*: - - To ensure quantum resistance, post-quantum cryptographic algorithms typically require larger key sizes, which increase both storage and computational costs. - -- *Common Algorithms*: - - Algorithms like lattice-based cryptography (e.g., NTRU, Kyber), code-based cryptography (e.g., McEliece), and hash-based cryptography (e.g., SPHINCS+) are popular candidates for post-quantum encryption. - -### Time Complexity: - -- *Encryption/Decryption Time*: $O(n^k)$ - The time complexity for post-quantum encryption can vary depending on the algorithm used. Most post-quantum algorithms have a higher time complexity compared to classical algorithms due to the need for complex operations and larger key sizes. - -### Space Complexity: - -- *Space Complexity*: $O(n)$ to $O(n^2)$ - Post-quantum encryption requires more storage due to larger key sizes and ciphertexts. Some algorithms, especially lattice-based ones, can significantly increase space requirements compared to traditional cryptography. - -### Types of Post-Quantum Encryption Algorithms: - -1. *Lattice-Based Cryptography*: - - Lattice-based encryption is one of the most promising post-quantum encryption methods. Algorithms like *Kyber* and *NTRU* rely on the hardness of lattice problems, offering security against quantum attacks. - -2. *Code-Based Cryptography*: - - *McEliece* is a well-known example of code-based encryption that uses error-correcting codes to encrypt messages, offering resistance to quantum attacks. - -3. *Hash-Based Cryptography*: - - *SPHINCS+* is a quantum-resistant signature scheme that uses hash functions and is secure against both classical and quantum attacks. - -4. *Multivariate Quadratic Equations (MQ)*: - - Cryptosystems based on the hardness of solving systems of multivariate quadratic equations over finite fields. Examples include the *HFE* (Hidden Field Equations) family of cryptosystems. - -### C++ Example of Post-Quantum Encryption (Kyber Example): - -```cpp -#include -#include - -int main() { - if (!OQS_KEM_alg_is_enabled(OQS_KEM_alg_kyber_512)) { - std::cerr << "Kyber-512 is not enabled in this build." << std::endl; - return 1; - } - - OQS_KEM *kem = OQS_KEM_new(OQS_KEM_alg_kyber_512); - if (kem == nullptr) { - std::cerr << "Failed to initialize Kyber-512." << std::endl; - return 1; - } - - // Key generation - uint8_t public_key[OQS_KEM_public_key_length(kem)]; - uint8_t secret_key[OQS_KEM_secret_key_length(kem)]; - OQS_KEM_keypair(kem, public_key, secret_key); - - std::cout << "Key pair generated successfully!" << std::endl; - - // Message encryption - uint8_t ciphertext[OQS_KEM_ciphertext_length(kem)]; - uint8_t shared_secret_enc[OQS_KEM_shared_secret_length(kem)]; - OQS_KEM_encaps(kem, ciphertext, shared_secret_enc, public_key); - - std::cout << "Message encrypted successfully!" << std::endl; - - // Message decryption - uint8_t shared_secret_dec[OQS_KEM_shared_secret_length(kem)]; - OQS_KEM_decaps(kem, shared_secret_dec, ciphertext, secret_key); - - std::cout << "Message decrypted successfully!" << std::endl; - - OQS_KEM_free(kem); - - return 0; -} -``` - -:::note -This example uses the *liboqs* library, which implements several quantum-safe cryptographic algorithms. You need to install the library and set up your C++ environment to compile and run the code. -::: - -### Summary: - -Post-quantum encryption represents the future of cryptography in a quantum computing world. With quantum computers potentially capable of breaking traditional encryption schemes, post-quantum cryptographic algorithms like lattice-based, code-based, and hash-based cryptography provide the necessary security. While post-quantum encryption algorithms may require larger keys and more computational resources, their importance in protecting sensitive information against future quantum attacks cannot be overstated. diff --git a/docs/algorithms/Encryption algorithms/steganography-algo.md b/docs/algorithms/Encryption algorithms/steganography-algo.md deleted file mode 100644 index f2c5f4808..000000000 --- a/docs/algorithms/Encryption algorithms/steganography-algo.md +++ /dev/null @@ -1,107 +0,0 @@ ---- - -id: steganography-algo -sidebar_position: 9 -title: Steganography -sidebar_label: Steganography - ---- - -### Definition: - -Steganography is the practice of hiding secret data within a non-secret file or message in such a way that only the intended recipient can detect the presence of the hidden data. The most common use of steganography is concealing information within digital media, such as images, audio, or video files. - -### Characteristics: - -- **Hidden Information**: - - Steganography conceals the presence of data by embedding it within an existing medium (image, audio, video), which appears unchanged to casual observers. - -- **Security by Obscurity**: - - Unlike cryptography, where the goal is to make data unreadable to unauthorized users, steganography aims to hide the existence of the data entirely. - -- **Payload Capacity**: - - The amount of data that can be hidden in a cover medium depends on the size of the medium and the method used. Larger files like images or audio files can hide more data. - -- **Common Techniques**: - - Popular methods of steganography include Least Significant Bit (LSB) embedding in images, where the secret data is embedded into the least important bits of each pixel. - -### Time Complexity: - -- **Embedding Time**: $O(n)$ - Embedding data into a medium takes linear time with respect to the size of the data being embedded and the cover medium. - -- **Extraction Time**: $O(n)$ - The time to extract hidden information is also linear, depending on the size of the medium and the hidden data. - -### Space Complexity: - -- **Space Complexity**: $O(n)$ - The space complexity is dependent on the cover medium, as the hidden data is stored within the existing space, usually with minimal increase in file size. - -### Common Steganography Techniques: - -1. **Least Significant Bit (LSB) Embedding**: - - This method embeds secret data in the least significant bits of image pixels or audio samples. The human eye or ear cannot detect these minor changes, making it a widely used technique. - -2. **Frequency Domain Embedding**: - - In this technique, data is hidden in the frequency domain of an image or audio file, often using transformations like DCT (Discrete Cosine Transform) or FFT (Fast Fourier Transform). - -3. **Spread Spectrum Techniques**: - - Secret data is spread across multiple frequencies of the cover medium, making it more resistant to detection and tampering. - -### C++ Implementation of Steganography (LSB Embedding Example in an Image): - -```cpp -#include -#include - -void embedData(cv::Mat &image, const std::string &data) { - int dataIdx = 0; - for (int i = 0; i < image.rows; ++i) { - for (int j = 0; j < image.cols; ++j) { - if (dataIdx < data.size()) { - // Embed one bit of data into the least significant bit of the pixel - uchar &pixel = image.at(i, j); - pixel = (pixel & 0xFE) | (data[dataIdx++] & 0x01); - } - } - } -} - -int main() { - cv::Mat image = cv::imread("cover_image.png", cv::IMREAD_GRAYSCALE); - if (image.empty()) { - std::cout << "Image not found!" << std::endl; - return -1; - } - - std::string secretData = "Hello"; - embedData(image, secretData); - - cv::imwrite("stego_image.png", image); - std::cout << "Secret data embedded!" << std::endl; - - return 0; -} -``` - -### Explanation: - -- **LSB Embedding**: This code demonstrates a simple form of steganography using Least Significant Bit (LSB) embedding. It hides a secret string (`Hello`) into the least significant bits of an image's pixel values. - ---- - -### Graphical Representation of Steganography (LSB in Images): - -A steganography graph visualizes the changes in pixel intensity before and after embedding secret data. The graph compares the pixel values of the cover image with the stego image (the image with hidden data). - -### Steganography Graph Explanation: - -- **X-Axis**: Represents the pixel positions in the image (e.g., the index of each pixel in a row of the image). -- **Y-Axis**: Represents the intensity or value of the pixels (ranging from 0 to 255 for grayscale images). -- **Cover Image**: Shows the original pixel intensity of the image. -- **Stego Image**: Displays the slight changes in pixel intensity after embedding the secret data using LSB. - ---- - -This graph will show the subtle alterations in pixel values (typically the least significant bits), which would be imperceptible to the naked eye but are visible when viewed at a binary level. diff --git a/docs/algorithms/Encryption algorithms/symmetric_encryption.md b/docs/algorithms/Encryption algorithms/symmetric_encryption.md deleted file mode 100644 index 488e0446d..000000000 --- a/docs/algorithms/Encryption algorithms/symmetric_encryption.md +++ /dev/null @@ -1,81 +0,0 @@ ---- - -id: symmetric-encryption-algo -sidebar_position: 1 -title: Symmetric Encryption -sidebar_label: Symmetric Encryption - ---- - -### Definition: - -Symmetric encryption is a type of encryption where the same key is used for both encryption and decryption. This means that the sender and the receiver must both possess the secret key and keep it secure. Symmetric encryption is widely used for data confidentiality in various applications. - -### Characteristics: - -- **Single Key**: - - Both the encryption and decryption processes use the same key, which must be kept secret. This key is crucial for ensuring the security of the encrypted data. - -- **Speed**: - - Symmetric encryption algorithms are generally faster than asymmetric algorithms, making them suitable for encrypting large amounts of data. - -- **In-Place**: - - Some symmetric algorithms can operate directly on the data without requiring additional memory for storing the ciphertext. - -- **Common Algorithms**: - - Well-known symmetric encryption algorithms include Advanced Encryption Standard (AES), Data Encryption Standard (DES), and Triple DES (3DES). - -### Time Complexity: - -- **Encryption/Decryption Time**: $O(n)$ - The time complexity for symmetric encryption and decryption is generally linear, dependent on the length of the data being processed. However, it may vary based on the algorithm and implementation. - -### Space Complexity: - -- **Space Complexity**: $O(1)$ - Symmetric encryption typically requires a constant amount of additional space, as the same key is used for both encryption and decryption, and the input data is transformed into ciphertext in place. - -### Common Symmetric Encryption Algorithms: - -1. **Advanced Encryption Standard (AES)**: - - A widely used symmetric encryption standard, AES supports key sizes of 128, 192, and 256 bits and operates on fixed-size blocks of 128 bits. - -2. **Data Encryption Standard (DES)**: - - An older symmetric encryption standard that uses a 56-bit key and operates on 64-bit blocks. DES is considered insecure due to its small key size. - -3. **Triple DES (3DES)**: - - An enhancement of DES that applies the DES algorithm three times to each data block, providing a stronger level of security. - -### C++ Implementation of Symmetric Encryption (AES Example): - -```cpp -#include -#include -#include - -void encrypt(const unsigned char *input, unsigned char *output, const unsigned char *key) { - AES_KEY encryptKey; - AES_set_encrypt_key(key, 128, &encryptKey); - AES_encrypt(input, output, &encryptKey); -} - -int main() { - unsigned char key[16] = "0123456789abcdef"; // 128-bit key - unsigned char input[16] = "Hello, World!123"; // 128-bit block - unsigned char output[16]; - - encrypt(input, output, key); - - std::cout << "Encrypted Output: "; - for (int i = 0; i < 16; i++) { - std::cout << std::hex << (int)output[i]; - } - std::cout << std::endl; - - return 0; -} -``` - -### Summary: - -Symmetric encryption is a crucial aspect of modern cryptography, providing a fast and efficient means of securing data. While it requires both the sender and receiver to share the same secret key, its performance advantages make it ideal for encrypting large datasets. Common algorithms like AES offer robust security features, making symmetric encryption a foundational technology in data protection. diff --git a/docs/algorithms/Gale-Shapley-Algorithm/GaleShapley.md b/docs/algorithms/Gale-Shapley-Algorithm/GaleShapley.md deleted file mode 100644 index 4903599b1..000000000 --- a/docs/algorithms/Gale-Shapley-Algorithm/GaleShapley.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -id: gale-shapley-algorithm -sidebar_position: 15 -title: Gale-Shapley Algorithm -sidebar_label: Gale-Shapley Algorithm ---- - -## Overview: -The Gale-Shapley algorithm, also known as the **Deferred Acceptance Algorithm** or **Stable Marriage Problem** algorithm, is used to find a stable matching between two sets of participants, ensuring no pair would rather be matched with each other than their current partners. - -This algorithm is widely applied in real-world scenarios such as college admissions, job matching, and organ donation systems. - -## Key Features: -- **Stable Pairing**: Ensures no unmatched pair would prefer to be matched together rather than their current partners. -- **Deferred Acceptance**: Matching is based on proposals made by one side (e.g., men proposing to women) and acceptance is deferred until a stable match is found. -- **Two-sided Matching**: Matches two distinct sets of participants (e.g., applicants and schools). - -## Time Complexity: -- **O(n²)** - The time complexity of the Gale-Shapley algorithm is O(n²), where n is the number of participants on either side of the matching. This is because in the worst case, each participant can be rejected by every member of the opposite set before a stable match is found. - - - -### Space Complexity: -- **O(n)** - The space complexity is linear because the algorithm only needs to store the current matches and the free participants, which takes up space proportional to the number of participants, `n`. - -## Algorithm Steps: - -1. **Initialization**: - - Each participant on one side proposes to their top choice from the other side. - - The other side maintains a list of tentative matches. - -2. **Proposals and Tentative Engagements**: - - Unengaged participants propose to their top choice. - - The participants being proposed to tentatively accept the best proposal they receive but may switch if a better proposal arrives. - -3. **Rejections**: - - If a better proposal is received, the current engagement is rejected, and the rejected participant moves to the next preference on their list. - -4. **Termination**: - - The process continues until all participants are engaged. No participant would prefer another partner over their current match, resulting in a stable pairing. - -## C++ Code Implementation: - -```cpp -#include -#include -#include -using namespace std; - -#define N 5 - -bool wPrefersM1OverM(int prefer[2 * N][N], int w, int m, int m1) { - for (int i = 0; i < N; i++) { - if (prefer[w][i] == m1) - return true; - if (prefer[w][i] == m) - return false; - } - return false; -} - -void stableMarriage(int prefer[2 * N][N]) { - int wPartner[N]; - bool mFree[N]; - memset(wPartner, -1, sizeof(wPartner)); - memset(mFree, false, sizeof(mFree)); - int freeCount = N; - - while (freeCount > 0) { - int m; - for (m = 0; m < N; m++) - if (mFree[m] == false) - break; - - for (int i = 0; i < N && mFree[m] == false; i++) { - int w = prefer[m][i]; - - if (wPartner[w - N] == -1) { - wPartner[w - N] = m; - mFree[m] = true; - freeCount--; - } else { - int m1 = wPartner[w - N]; - if (!wPrefersM1OverM(prefer, w, m, m1)) { - wPartner[w - N] = m; - mFree[m] = true; - mFree[m1] = false; - } - } - } - } - - cout << "Woman Man" << endl; - for (int i = 0; i < N; i++) - cout << " " << i + N << "\t" << wPartner[i] << endl; -} - -int main() { - int prefer[2 * N][N] = { - {6, 5, 8, 9, 7}, {8, 6, 5, 7, 9}, {6, 9, 7, 8, 5}, - {5, 8, 7, 6, 9}, {6, 8, 5, 9, 7}, {4, 0, 1, 3, 2}, - {2, 1, 3, 0, 4}, {1, 2, 3, 4, 0}, {0, 4, 3, 2, 1}, - {3, 1, 0, 2, 4}}; - - stableMarriage(prefer); - return 0; -} -``` - -## Java Implementation: - -```java -import java.util.Arrays; - -public class StableMarriage { - static final int N = 5; - - boolean wPrefersM1OverM(int prefer[][], int w, int m, int m1) { - for (int i = 0; i < N; i++) { - if (prefer[w][i] == m1) - return true; - if (prefer[w][i] == m) - return false; - } - return false; - } - - void stableMarriage(int prefer[][]) { - int[] wPartner = new int[N]; - boolean[] mFree = new boolean[N]; - - Arrays.fill(wPartner, -1); - int freeCount = N; - - while (freeCount > 0) { - int m; - for (m = 0; m < N; m++) - if (!mFree[m]) - break; - - for (int i = 0; i < N && !mFree[m]; i++) { - int w = prefer[m][i]; - - if (wPartner[w - N] == -1) { - wPartner[w - N] = m; - mFree[m] = true; - freeCount--; - } else { - int m1 = wPartner[w - N]; - if (!wPrefersM1OverM(prefer, w, m, m1)) { - wPartner[w - N] = m; - mFree[m] = true; - mFree[m1] = false; - } - } - } - } - - System.out.println("Woman Man"); - for (int i = 0; i < N; i++) - System.out.println(" " + (i + N) + "\t" + wPartner[i]); - } - - public static void main(String[] args) { - int prefer[][] = { - {6, 5, 8, 9, 7}, {8, 6, 5, 7, 9}, {6, 9, 7, 8, 5}, - {5, 8, 7, 6, 9}, {6, 8, 5, 9, 7}, {4, 0, 1, 3, 2}, - {2, 1, 3, 0, 4}, {1, 2, 3, 4, 0}, {0, 4, 3, 2, 1}, - {3, 1, 0, 2, 4} - }; - - new StableMarriage().stableMarriage(prefer); - } -} -``` \ No newline at end of file diff --git a/docs/algorithms/Hashing-algorithm.md b/docs/algorithms/Hashing-algorithm.md deleted file mode 100644 index ec5b82e13..000000000 --- a/docs/algorithms/Hashing-algorithm.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -id: hashing-algorithm -title: Hashing Algorithm -sidebar_label: Hashing Algorithm -sidebar_position: 8 -description: "Hashing is a technique used to uniquely identify a specific object from a group of similar objects. It involves mapping large data to fixed-size values." -tags: [Data Structures, Hashing, Hash Functions, Hash Tables, Algorithms] ---- - -# Hashing Theory - -## Overview -**Hashing** is a widely used technique in computer science for mapping large data of variable length into smaller, fixed-size values. This process is performed using a **hash function** that converts data (like strings or integers) into a hash value, typically an integer. Hashing is fundamental in **hash tables**, a popular data structure used in algorithms for fast data retrieval, insertion, and deletion. - -## Introduction -At the core of hashing is the **hash function**, which transforms input data into a hash value. This value corresponds to a location in a **hash table** where the actual data is stored. Hashing is efficient for operations such as **lookup**, **insert**, and **delete**, making it crucial in areas like databases, caches, and cryptography. - -## Characteristics of Hashing Theory -- **Efficiency**: Provides constant-time complexity, O(1), for data retrieval, insertion, and deletion in an average-case scenario. -- **Collision Handling**: When two distinct inputs produce the same hash value, collisions occur, which are handled using techniques such as **chaining** and **open addressing**. -- **Deterministic**: The same input will always yield the same hash value for a given hash function. - -## How Hashing Works -1. **Input Data**: Hash functions take an input (e.g., a string, integer, or object). -2. **Apply Hash Function**: The input is processed through a hash function that generates a hash value. -3. **Store in Hash Table**: The generated hash value determines the index in the hash table where the original data is stored. -4. **Handle Collisions**: If two inputs produce the same hash value (collision), methods like chaining or probing are used to resolve them. - -## Common Hash Functions -- **Division Method**: The hash value is obtained by taking the remainder of the division of the input by the hash table size: `h(x) = x % table_size`. -- **Multiplication Method**: Uses a constant multiplier `A` to generate the hash value: `h(x) = floor(table_size * (x * A % 1))`. -- **Cryptographic Hash Functions**: Secure hash functions like **SHA-256** or **MD5** are used in cryptography for data integrity and security. - - -### Example Hash Function -```python -def hash_function(key, table_size): - return key % table_size -``` -## Time Complexity - -Hashing provides efficient time complexity for common operations on average. However, the complexity can vary based on the collision handling method and the distribution of hash values. - -### Time Complexity Overview -- **Search, Insert, Delete (Average Case)**: O(1) - - Hashing provides constant-time operations for inserting, searching, and deleting elements in a hash table due to direct indexing. -- **Search, Insert, Delete (Worst Case)**: O(n) - - In the worst case, where there are many collisions (e.g., all elements hash to the same index), the hash table can degrade into a linked list or chain, and the time complexity becomes O(n), where `n` is the number of elements. - -### Collision Handling Methods and Complexity - -1. **Chaining**: - - **Average Case**: O(1) for search, insert, and delete operations, assuming the hash function distributes elements evenly. - - **Worst Case**: O(n), where all elements are placed in the same linked list due to collisions. - -2. **Open Addressing (Linear Probing, Quadratic Probing, Double Hashing)**: - - **Average Case**: O(1) for search, insert, and delete. - - **Worst Case**: O(n), where the table is nearly full, and many collisions occur, requiring multiple probes to find an empty slot. - -### Space Complexity -- The space complexity of a hash table is O(n), where `n` is the number of elements stored. -- Additional space may be required for collision handling: - - **Chaining**: Requires extra space for linked lists. - - **Open Addressing**: No additional space is required, but the load factor of the hash table must be managed to prevent excessive collisions. - -## Conclusion - -Hashing is an essential technique in computer science that allows for fast and efficient data retrieval, making it a key component in various applications like caching, databases, and cryptography. By converting data into a fixed-size hash code, hashing enables constant time complexity for search, insert, and delete operations on average. However, its efficiency depends on selecting an appropriate hash function and collision resolution strategy. With proper implementation, hashing can significantly optimize performance in systems that require rapid access to large datasets. - - diff --git a/docs/algorithms/N-Queens-Dynamic-programming-algorithm.md b/docs/algorithms/N-Queens-Dynamic-programming-algorithm.md deleted file mode 100644 index bb6e6c28b..000000000 --- a/docs/algorithms/N-Queens-Dynamic-programming-algorithm.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -id: n-queens-problem -title: N-Queens Problem -sidebar_label: N-Queens Problem -sidebar_position: 9 -description: "The N-Queens problem is a classic backtracking problem where the objective is to place N queens on an N×N chessboard such that no two queens threaten each other." -tags: [Backtracking, N-Queens, Algorithms, Recursion, Combinatorics] ---- - -# N-Queens Problem - -## Overview -The **N-Queens problem** is a classic combinatorial problem where the objective is to place `N` queens on an `N×N` chessboard so that no two queens can attack each other. In chess, a queen can attack another queen if it is on the same row, column, or diagonal. The challenge is to place all queens in a way that none of them threaten each other. - -## Problem Description -- **Input**: An integer `N` representing the size of the chessboard and the number of queens. -- **Output**: All possible ways to place `N` queens on an `N×N` board such that no two queens threaten each other. -- **Constraints**: No two queens can share the same row, column, or diagonal. - -## Solution Approach -The N-Queens problem is typically solved using **backtracking**, a depth-first search approach that explores all possible configurations of queens on the board. The algorithm places queens row by row and uses recursive calls to check whether the current configuration is valid. If a conflict is detected, the algorithm backtracks to try a different configuration. - -### Key Steps -1. **Start from the first row** and try to place a queen in each column of that row. -2. **Check for conflicts** with queens in previous rows (same column, row, or diagonal). -3. **Place the queen** in a valid position and move to the next row. -4. **Backtrack** if no valid positions are found in the current row, removing the last placed queen and trying a new configuration. -5. **Repeat the process** until all possible configurations have been explored. - -## Code Example - -``` -python -def solve_n_queens(n): - def is_safe(board, row, col): - # Check the column and diagonals for conflicts - for i in range(row): - if board[i] == col or \ - board[i] - i == col - row or \ - board[i] + i == col + row: - return False - return True - - def solve(board, row): - if row == n: - # All queens placed successfully - result.append(board[:]) - return - - for col in range(n): - if is_safe(board, row, col): - board[row] = col - solve(board, row + 1) - board[row] = -1 # Backtrack - - result = [] - solve([-1] * n, 0) # Initialize an empty board - return result - -solutions = solve_n_queens(4) -for solution in solutions: - print(solution) -``` -## Time Complexity - -The time complexity of the N-Queens problem depends on the size of the board (N), as the algorithm explores different possible configurations of queens. - -### Time Complexity Overview -- **Worst Case**: O(N!) (factorial time complexity) - - The algorithm needs to explore all possible placements of queens on the board, and in the worst case, it examines all permutations of queen placements. - - Although backtracking helps prune invalid configurations, the worst case is still factorial in nature. - -## Space Complexity -- **Space Complexity**: O(N) - - The space complexity is linear because we only need to store the position of N queens on the board, as well as auxiliary information for backtracking (e.g., current row and column states). - -## Applications -- **Puzzle Solving**: The N-Queens problem is a classic puzzle that helps in understanding backtracking techniques. -- **Constraint Satisfaction Problems (CSPs)**: The problem serves as a useful example for solving other CSPs, where constraints need to be satisfied. -- **AI and Optimization**: Variants of the N-Queens problem are used in AI to test search algorithms and optimization techniques. - -## Conclusion -The N-Queens problem is a fundamental backtracking problem that illustrates how to explore solution spaces with constraints. The key to solving the problem efficiently is to use backtracking to eliminate invalid configurations early, significantly reducing the number of possibilities. With careful implementation, it is possible to solve the problem for large values of N and explore different approaches to constraint satisfaction and optimization in algorithmic problem-solving. diff --git a/docs/algorithms/Scheduling Algorithms/EarliestDeadlineFirst.md b/docs/algorithms/Scheduling Algorithms/EarliestDeadlineFirst.md deleted file mode 100644 index 5d7333acf..000000000 --- a/docs/algorithms/Scheduling Algorithms/EarliestDeadlineFirst.md +++ /dev/null @@ -1,126 +0,0 @@ ---- - -id: earliest-deadline-first -title: Earliest Deadline First Scheduling Algorithm -sidebar_label: "Earliest Deadline First" -sidebar_position: 9 -description: Earliest Deadline First (EDF) is a dynamic priority scheduling algorithm where processes are scheduled according to their deadlines. The process with the nearest deadline is executed first. -tags: [Scheduling, EDF] - ---- - -# Earliest Deadline First Scheduling Algorithm - -## Introduction - -The **Earliest Deadline First (EDF)** algorithm is a dynamic priority scheduling technique used in real-time operating systems. In EDF, each process is assigned a deadline, and the CPU is allocated to the process with the closest deadline. This approach ensures that time-critical tasks are executed in a timely manner. - -### Example - -Consider three processes with the following burst times and deadlines: -- Process 1: `3 units` (Deadline at time 4) -- Process 2: `2 units` (Deadline at time 2) -- Process 3: `1 unit` (Deadline at time 3) - -Using the EDF algorithm, the processes will be executed in the order of their deadlines: Process 2, Process 3, and then Process 1. - -## Problem Definition - -Given a list of processes along with their burst times and deadlines, calculate the waiting times, turnaround times, average waiting time, and average turnaround time for the processes. - -### Key Concepts - -- **Waiting Time**: The amount of time a process spends waiting in the queue before it starts executing. -- **Turnaround Time**: The total time taken for a process from arrival to completion, which includes both the waiting time and the burst time. - -## EDF Scheduling Approach - -In the Earliest Deadline First algorithm: -- The process with the earliest deadline is selected for execution next. -- The algorithm continuously evaluates the deadlines of all ready processes and adjusts the schedule dynamically. - -## Code Implementation in Python - -Below is the Python implementation for the Earliest Deadline First scheduling algorithm: - -```python -from typing import List, Tuple - -def calculate_wait_times(processes: List[Tuple[int, int, int]]) -> List[int]: - """ - Calculate the waiting times for a list of processes given their burst times and deadlines. - """ - # Sort processes by deadline - processes.sort(key=lambda x: x[2]) # Sort by deadline - n = len(processes) - wait_times = [0] * n - - for i in range(1, n): - wait_times[i] = processes[i - 1][1] + wait_times[i - 1] - - return wait_times - -def calculate_turnaround_times(processes: List[Tuple[int, int, int]], wait_times: List[int]) -> List[int]: - """ - Calculate the turnaround times for a list of processes. - Turnaround time is the sum of waiting time and burst time for each process. - """ - return [processes[i][1] + wait_times[i] for i in range(len(processes))] - -def calculate_avg_turnaround_time(turnaround_times: List[int]) -> float: - """ - Calculate the average turnaround time for a list of processes. - """ - return sum(turnaround_times) / len(turnaround_times) - -def calculate_avg_wait_time(wait_times: List[int]) -> float: - """ - Calculate the average waiting time for a list of processes. - """ - return sum(wait_times) / len(wait_times) - -if __name__ == "__main__": - processes = [(1, 3, 4), (2, 2, 2), (3, 1, 3)] # List of (process_id, burst_time, deadline) - - # Calculate waiting times and turnaround times - wait_times = calculate_wait_times(processes) - turnaround_times = calculate_turnaround_times(processes, wait_times) - - # Calculate average waiting time and average turnaround time - avg_wait_time = calculate_avg_wait_time(wait_times) - avg_turnaround_time = calculate_avg_turnaround_time(turnaround_times) - - # Display process details and calculated times - print("Process ID\tBurst Time\tDeadline\tWaiting Time\tTurnaround Time") - for i, (process_id, burst_time, deadline) in enumerate(processes): - print(f"{process_id}\t\t{burst_time}\t\t{deadline}\t\t{wait_times[i]}\t\t{turnaround_times[i]}") - - # Display averages - print(f"Average waiting time = {avg_wait_time}") - print(f"Average turnaround time = {avg_turnaround_time}") - -``` - -## Explanation of the Code - - Waiting Time Calculation: Processes are sorted by their deadlines, and the waiting time for each process is calculated based on the burst time of the previous processes. - - Turnaround Time Calculation: Turnaround time is computed as the sum of the waiting time and the burst time for each process. - - Average Times: The average waiting time and average turnaround time are calculated by taking the sum of the respective times and dividing by the total number of processes. - -## Example Output -For the input where processes are [(1, 3, 4), (2, 2, 2), (3, 1, 3)], the output is as follows: -```bash -Process ID Burst Time Deadline Waiting Time Turnaround Time -2 2 2 0 2 -3 1 3 2 3 -1 3 4 5 8 - -Average waiting time = 2.33 -Average turnaround time = 4.33 -``` - -## Time and Space Complexity - - Time Complexity: The time complexity is O(n log n) due to the sorting of processes, where n is the number of processes. - - Space Complexity: The space complexity is O(n) due to the storage of waiting times and turnaround times. - -## Conclusion -The Earliest Deadline First scheduling algorithm is an effective approach for real-time systems, ensuring that time-critical tasks are executed before their deadlines. However, it can lead to challenges such as deadline misses if the system is overloaded. diff --git a/docs/algorithms/Scheduling Algorithms/FirstComeFirstServed.md b/docs/algorithms/Scheduling Algorithms/FirstComeFirstServed.md deleted file mode 100644 index cf49ef751..000000000 --- a/docs/algorithms/Scheduling Algorithms/FirstComeFirstServed.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: first-come-first-served-scheduling -title: First Come First Served Scheduling Algorithm -sidebar_label: "First Come First Served Scheduling" -sidebar_position: 5 -description: First Come First Served (FCFS) is a simple scheduling algorithm where processes are handled in the order they arrive, without priority. -tags: [Scheduling, FCFS] ---- - -# First Come First Served (FCFS) Scheduling Algorithm - -## Introduction - -The **First Come First Served (FCFS)** scheduling algorithm is one of the simplest process scheduling techniques used in operating systems. It handles processes in the order they arrive, ensuring that no process is preempted. Once a process starts executing, it runs to completion. - -### Example - -Consider three processes with the following duration times: -- Process 1: `19 units` -- Process 2: `8 units` -- Process 3: `9 units` - -Using the FCFS algorithm, the processes will be executed in the order of their arrival. - -## Problem Definition - -Given a list of processes and their corresponding execution times, calculate the waiting times, turnaround times, average waiting time, and average turnaround time for the processes. - -### Key Concepts - -- **Waiting Time**: The amount of time a process spends waiting before it starts executing. -- **Turnaround Time**: The total time taken for a process from arrival to completion, which includes both the waiting time and the duration time. - -## FCFS Scheduling Approach - -In the FCFS algorithm: -- The waiting time for the first process is `0` because it starts immediately. -- For every subsequent process, its waiting time is the sum of the durations of all preceding processes. - -## Code Implementation in Python - -Below is the Python implementation for the FCFS scheduling algorithm: - -```python -from __future__ import annotations - -def calculate_wait_times(process_durations: list[int]) -> list[int]: - """ - Calculate the waiting times for a list of processes given their duration times. - The waiting time for the first process is 0, and for each subsequent process, - it's the sum of the duration times of all previous processes. - """ - wait_times = [0] * len(process_durations) - for i in range(1, len(process_durations)): - wait_times[i] = process_durations[i - 1] + wait_times[i - 1] - return wait_times - -def calculate_turnaround_times(process_durations: list[int], wait_times: list[int]) -> list[int]: - """ - Calculate the turnaround times for a list of processes. - Turnaround time is the sum of waiting time and duration time for each process. - """ - return [process_durations[i] + wait_times[i] for i in range(len(process_durations))] - -def calculate_avg_turnaround_time(turnaround_times: list[int]) -> float: - """ - Calculate the average turnaround time for a list of processes. - """ - return sum(turnaround_times) / len(turnaround_times) - -def calculate_avg_wait_time(wait_times: list[int]) -> float: - """ - Calculate the average waiting time for a list of processes. - """ - return sum(wait_times) / len(wait_times) - -if __name__ == "__main__": - process_ids = [1, 2, 3] # List of process IDs - - # The duration time for each process - process_durations = [19, 8, 9] - - # Calculate waiting times and turnaround times - wait_times = calculate_wait_times(process_durations) - turnaround_times = calculate_turnaround_times(process_durations, wait_times) - - # Calculate average waiting time and average turnaround time - avg_wait_time = calculate_avg_wait_time(wait_times) - avg_turnaround_time = calculate_avg_turnaround_time(turnaround_times) - - # Display process details and calculated times - print("Process ID\tDuration Time\tWaiting Time\tTurnaround Time") - for i, process_id in enumerate(process_ids): - print(f"{process_id}\t\t{process_durations[i]}\t\t{wait_times[i]}\t\t{turnaround_times[i]}") - - # Display averages - print(f"Average waiting time = {avg_wait_time}") - print(f"Average turnaround time = {avg_turnaround_time}") -``` - -### Explanation of the Code - -1. **Waiting Time Calculation**: - - The first process always has a waiting time of 0. - - For subsequent processes, the waiting time is the sum of the durations of all previous processes. - -2. **Turnaround Time Calculation**: - - Turnaround time is calculated as the sum of the waiting time and the duration of each process. - -3. **Average Times**: - - The average waiting time and average turnaround time are calculated by taking the sum of the respective times and dividing by the total number of processes. - -### Example Output - -For the input where process durations are `[19, 8, 9]`, the output is as follows: - -```plaintext -Process ID Duration Time Waiting Time Turnaround Time -1 19 0 19 -2 8 19 27 -3 9 27 36 - -Average waiting time = 15.33 -Average turnaround time = 27.33 -``` - -### Time and Space Complexity - -- **Time Complexity**: The time complexity is O(n) where n is the number of processes. Each function iterates through the process list once. -- **Space Complexity**: The space complexity is O(n) due to the storage of waiting times and turnaround times. - -### Conclusion - -The **First Come First Served (FCFS)** scheduling algorithm is simple and effective for non-preemptive tasks. While easy to implement, it may lead to long waiting times for processes that arrive later, especially if earlier processes have long durations (known as the convoy effect). \ No newline at end of file diff --git a/docs/algorithms/Scheduling Algorithms/LeastRecentlyUsed.md b/docs/algorithms/Scheduling Algorithms/LeastRecentlyUsed.md deleted file mode 100644 index 32321147f..000000000 --- a/docs/algorithms/Scheduling Algorithms/LeastRecentlyUsed.md +++ /dev/null @@ -1,100 +0,0 @@ ---- - -id: least-recently-used -title: Least Recently Used (LRU) Algorithm -sidebar_label: "Least Recently Used" -sidebar_position: 8 -description: The Least Recently Used (LRU) algorithm is a cache replacement policy that evicts the least recently used items first. -tags: [Cache, LRU, Algorithms] - ---- - -# Least Recently Used (LRU) Algorithm - -## Introduction - -The **Least Recently Used (LRU)** algorithm is a cache replacement strategy that removes the least recently accessed item when the cache reaches its capacity. This algorithm assumes that data that hasn't been used for a while is less likely to be used in the future. - -### Example - -Consider a cache with a capacity of 3 and the following sequence of page requests: -- 1, 2, 3, 1, 4, 2, 5 - -Using the LRU algorithm, the pages will be loaded into the cache as follows: -- Cache: `[1]` → `[1, 2]` → `[1, 2, 3]` → `[1, 2, 3]` (access 1) → `[2, 3, 4]` (remove 1) → `[3, 4, 2]` (remove 5) → `[4, 2, 5]` (remove 3). - -## Problem Definition - -Given a sequence of page requests and a cache size, determine which pages will be evicted using the LRU algorithm. - -### Key Concepts - -- **Cache**: A smaller, faster memory that stores copies of frequently accessed data from the main memory. -- **Page Fault**: Occurs when the requested page is not in the cache, necessitating loading it from a slower storage. - -## LRU Approach - -In the LRU algorithm: -- When a page is accessed, it is moved to the front of the cache. -- If the cache is full, the page that has not been accessed for the longest time is removed. - -## Code Implementation in Python - -Below is the Python implementation for the Least Recently Used (LRU) algorithm: - -```python -from collections import OrderedDict - -class LRUCache: - def __init__(self, capacity: int): - self.cache = OrderedDict() - self.capacity = capacity - - def get(self, key: int) -> int: - if key not in self.cache: - return -1 - else: - self.cache.move_to_end(key) - return self.cache[key] - - def put(self, key: int, value: int) -> None: - if key in self.cache: - self.cache.move_to_end(key) - self.cache[key] = value - if len(self.cache) > self.capacity: - self.cache.popitem(last=False) - -if __name__ == "__main__": - lru_cache = LRUCache(3) # Cache size of 3 - requests = [(1, 'A'), (2, 'B'), (3, 'C'), (1, 'A'), (4, 'D'), (2, 'B'), (5, 'E')] - - for key, value in requests: - if value: - lru_cache.put(key, value) - else: - print(f"Get key {key}: {lru_cache.get(key)}") - -``` - -## Explanation of the Code - - Cache Implementation: - Uses an OrderedDict to maintain the order of insertion. - - The get method checks if a page is in the cache; if it is, it moves the page to the end of the order to mark it as recently used. - - The put method adds a new page to the cache. If the cache exceeds its capacity, it removes the least recently used page (the first item). - -## Example Output -For a cache with requests [(1, 'A'), (2, 'B'), (3, 'C'), (1, 'A'), (4, 'D'), (2, 'B'), (5, 'E')], the pages will be cached as follows: -```bash -Initial Cache: [1: A] -Cache after request 2: [1: A, 2: B] -Cache after request 3: [1: A, 2: B, 3: C] -Cache after request 4 (evict 2): [1: A, 3: C, 4: D] -Cache after request 5 (evict 3): [1: A, 4: D, 5: E] -``` - -## Time and Space Complexity - - Time Complexity: O(1) for both get and put operations on average. - - Space Complexity: O(n) where n is the capacity of the cache, due to storage of cached pages. - -## Conclusion -The Least Recently Used (LRU) algorithm is an effective cache replacement strategy that helps maintain the most frequently accessed data while efficiently managing limited cache resources. This method significantly reduces the chances of cache misses and improves the performance of applications reliant on fast data retrieval. \ No newline at end of file diff --git a/docs/algorithms/Scheduling Algorithms/PriorityScheduling.md b/docs/algorithms/Scheduling Algorithms/PriorityScheduling.md deleted file mode 100644 index 406d824d5..000000000 --- a/docs/algorithms/Scheduling Algorithms/PriorityScheduling.md +++ /dev/null @@ -1,132 +0,0 @@ ---- - -id: priority-scheduling -title: Priority Scheduling Algorithm -sidebar_label: "Priority Scheduling" -sidebar_position: 7 -description: Priority Scheduling is a scheduling algorithm that selects processes based on priority. Higher priority processes are executed before lower priority ones. -tags: [Scheduling, Priority] - ---- - -# Priority Scheduling Algorithm - -## Introduction - -The **Priority Scheduling** algorithm is a process scheduling technique where processes are assigned priorities. The CPU is allocated to the process with the highest priority. If two processes have the same priority, they are scheduled in the order they arrive (FCFS). - -### Example - -Consider four processes with the following burst times and priorities: -- Process 1: `10 units` (Priority 2) -- Process 2: `1 unit` (Priority 1) -- Process 3: `2 units` (Priority 3) -- Process 4: `1 unit` (Priority 4) - -Using the Priority Scheduling algorithm, the processes will be executed in the order of their priority: Process 2, Process 1, Process 3, and then Process 4. - -## Problem Definition - -Given a list of processes along with their burst times and priorities, calculate the waiting times, turnaround times, average waiting time, and average turnaround time for the processes. - -### Key Concepts - -- **Waiting Time**: The amount of time a process spends waiting before it starts executing. -- **Turnaround Time**: The total time taken for a process from arrival to completion, which includes both the waiting time and the duration time. - -## Priority Scheduling Approach - -In the Priority Scheduling algorithm: -- The process with the highest priority is selected for execution next. -- If multiple processes have the same priority, the one that arrives first is executed first. - -## Code Implementation in Python - -Below is the Python implementation for the Priority Scheduling algorithm: - -```python -from typing import List, Tuple - -def calculate_wait_times(processes: List[Tuple[int, int, int]]) -> List[int]: - """ - Calculate the waiting times for a list of processes given their burst times and priorities. - """ - # Sort processes by priority (lower number indicates higher priority) - processes.sort(key=lambda x: (x[2], x[0])) # Sort by priority, then by arrival time - n = len(processes) - wait_times = [0] * n - - for i in range(1, n): - wait_times[i] = processes[i - 1][1] + wait_times[i - 1] - - return wait_times - -def calculate_turnaround_times(processes: List[Tuple[int, int, int]], wait_times: List[int]) -> List[int]: - """ - Calculate the turnaround times for a list of processes. - Turnaround time is the sum of waiting time and burst time for each process. - """ - return [processes[i][1] + wait_times[i] for i in range(len(processes))] - -def calculate_avg_turnaround_time(turnaround_times: List[int]) -> float: - """ - Calculate the average turnaround time for a list of processes. - """ - return sum(turnaround_times) / len(turnaround_times) - -def calculate_avg_wait_time(wait_times: List[int]) -> float: - """ - Calculate the average waiting time for a list of processes. - """ - return sum(wait_times) / len(wait_times) - -if __name__ == "__main__": - processes = [(1, 10, 2), (2, 1, 1), (3, 2, 3), (4, 1, 4)] # List of (process_id, burst_time, priority) - - # Calculate waiting times and turnaround times - wait_times = calculate_wait_times(processes) - turnaround_times = calculate_turnaround_times(processes, wait_times) - - # Calculate average waiting time and average turnaround time - avg_wait_time = calculate_avg_wait_time(wait_times) - avg_turnaround_time = calculate_avg_turnaround_time(turnaround_times) - - # Display process details and calculated times - print("Process ID\tBurst Time\tPriority\tWaiting Time\tTurnaround Time") - for i, (process_id, burst_time, priority) in enumerate(processes): - print(f"{process_id}\t\t{burst_time}\t\t{priority}\t\t{wait_times[i]}\t\t{turnaround_times[i]}") - - # Display averages - print(f"Average waiting time = {avg_wait_time}") - print(f"Average turnaround time = {avg_turnaround_time}") - -``` - -## Explanation of the Code - - Waiting Time Calculation: - - Processes are first sorted by their priority and then by arrival time. - - The waiting time for the first process is 0, and for subsequent processes, it is the sum of the durations of all previous processes. - - Turnaround Time Calculation: - - Turnaround time is calculated as the sum of the waiting time and the burst time of each process. - - Average Times: - - The average waiting time and average turnaround time are calculated by taking the sum of the respective times and dividing by the total number of processes. - -## Example Output -For the input where processes are [(1, 10, 2), (2, 1, 1), (3, 2, 3), (4, 1, 4)], the output is as follows: -```plaintext -Process ID Burst Time Priority Waiting Time Turnaround Time -2 1 1 0 1 -1 10 2 1 11 -3 2 3 11 13 -4 1 4 13 14 - -Average waiting time = 6.25 -Average turnaround time = 9.75 -``` - -## Time and Space Complexity -- **Time Complexity**: The time complexity is O(n log n) due to the sorting of processes, where n is the number of processes. -- **Space Complexity**: The space complexity is O(n) due to the storage of waiting times and turnaround times. - -## Conclusion -The Priority Scheduling algorithm is effective for ensuring that high-priority processes are executed first. However, it can lead to the "starvation" of lower-priority processes if higher-priority processes continue to arrive. diff --git a/docs/algorithms/Scheduling Algorithms/RoundRobin.md b/docs/algorithms/Scheduling Algorithms/RoundRobin.md deleted file mode 100644 index 31d740cde..000000000 --- a/docs/algorithms/Scheduling Algorithms/RoundRobin.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: round-robin-scheduling -title: Round Robin Scheduling Algorithm -sidebar_label: "Round Robin Scheduling" -sidebar_position: 6 -description: Round Robin (RR) is a preemptive scheduling algorithm where each process is assigned a fixed time slice in a cyclic order. -tags: [Scheduling, Round Robin] ---- - -# Round Robin (RR) Scheduling Algorithm - -## Introduction - -The **Round Robin (RR)** scheduling algorithm is a preemptive process scheduling technique used in operating systems. In this algorithm, each process is assigned a fixed time slice, known as a quantum, to execute in a cyclic manner. This ensures that no process waits too long in the queue, promoting fairness among processes. - -### Example - -Consider three processes with the following burst times: -- Process 1: `3 units` -- Process 2: `5 units` -- Process 3: `7 units` - -Using the Round Robin algorithm with a quantum of `2 units`, the processes will be executed in the order of their arrival. - -## Problem Definition - -Given a list of processes and their corresponding burst times, calculate the waiting times, turnaround times, average waiting time, and average turnaround time for the processes. - -### Key Concepts - -- **Waiting Time**: The amount of time a process spends waiting before it starts executing. -- **Turnaround Time**: The total time taken for a process from arrival to completion, which includes both the waiting time and the burst time. - -## Round Robin Scheduling Approach - -In the RR algorithm: -- Each process is given a fixed time slice (quantum) for execution. -- If a process does not finish within its quantum, it is moved to the end of the queue and waits for its next turn. - -## Code Implementation in Python - -Below is the Python implementation for the Round Robin scheduling algorithm: - -```python -from __future__ import annotations -from statistics import mean - -def calculate_waiting_times(burst_times: list[int], quantum: int = 2) -> list[int]: - """ - Calculate the waiting times for each process using Round Robin scheduling. - - Parameters: - burst_times (list[int]): The burst time for each process. - quantum (int): The time slice for each process (default is 2). - - Returns: - list[int]: The waiting time for each process. - """ - remaining_burst_times = list(burst_times) - waiting_times = [0] * len(burst_times) - current_time = 0 - - while True: - all_done = True - - for i, burst_time in enumerate(burst_times): - if remaining_burst_times[i] > 0: - all_done = False - if remaining_burst_times[i] > quantum: - current_time += quantum - remaining_burst_times[i] -= quantum - else: - current_time += remaining_burst_times[i] - waiting_times[i] = current_time - burst_time - remaining_burst_times[i] = 0 - - if all_done: - return waiting_times - -def calculate_turnaround_times(burst_times: list[int], waiting_times: list[int]) -> list[int]: - """ - Calculate the turnaround times for each process. - - Turnaround time is the sum of waiting time and burst time for each process. - - Returns: - list[int]: The turnaround time for each process. - """ - return [burst + wait for burst, wait in zip(burst_times, waiting_times)] - -if __name__ == "__main__": - burst_times = [3, 5, 7] - - # Calculate waiting times and turnaround times - waiting_times = calculate_waiting_times(burst_times) - turnaround_times = calculate_turnaround_times(burst_times, waiting_times) - - # Display the results - print("Process ID \tBurst Time \tWaiting Time \tTurnaround Time") - for i, burst_time in enumerate(burst_times): - print( - f" {i + 1}\t\t {burst_time}\t\t {waiting_times[i]}\t\t " - f"{turnaround_times[i]}" - ) - - # Calculate and display average waiting and turnaround times - print(f"\nAverage waiting time = {mean(waiting_times):.5f}") - print(f"Average turnaround time = {mean(turnaround_times):.5f}") -``` -### Explanation of the Code - -1. **Waiting Time Calculation**: - - Each process gets a chance to execute for a fixed quantum of time. - - The waiting time for each process is calculated based on how much time has elapsed before it gets executed. - -2. **Turnaround Time Calculation**: - - Turnaround time is the sum of waiting time and burst time for each process. - -3. **Average Times**: - - The average waiting time and average turnaround time are calculated by dividing the total time by the number of processes. - -### Example Output - -For the input where burst times are `[3, 5, 7]`, the output is as follows: - -Process ID Burst Time Waiting Time Turnaround Time -1 3 0 3 -2 5 3 8 -3 7 8 15 - -Average waiting time = 3.67 -Average turnaround time = 8.67 - -### Time and Space Complexity - -- **Time Complexity**: The time complexity is O(n) where n is the number of processes. Each function iterates through the process list. -- **Space Complexity**: The space complexity is O(n) due to the storage of waiting times and turnaround times. - -### Conclusion - -The Round Robin (RR) scheduling algorithm is effective for ensuring fairness in process execution. While it can introduce context switching overhead, it is widely used in time-sharing systems to allow multiple processes to share CPU time efficiently. \ No newline at end of file diff --git a/docs/algorithms/Scheduling Algorithms/ShortestJobRemainingFirst.md b/docs/algorithms/Scheduling Algorithms/ShortestJobRemainingFirst.md deleted file mode 100644 index dd5025a3d..000000000 --- a/docs/algorithms/Scheduling Algorithms/ShortestJobRemainingFirst.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -id: shortest-job-remaining-first-scheduling -title: Shortest Job Remaining First Scheduling Algorithm -sidebar_label: "Shortest Job Remaining First Scheduling" -sidebar_position: 6 -description: Shortest Job Remaining First (SJR) is a preemptive scheduling algorithm that selects the process with the smallest remaining time to execute next. -tags: [Scheduling, SJR] ---- - -# Shortest Job Remaining First (SJR) Scheduling Algorithm - -## Introduction - -The **Shortest Job Remaining First (SJR)** scheduling algorithm is a preemptive scheduling technique used in operating systems. It selects the process with the smallest remaining burst time to execute next, allowing for efficient handling of processes with varying execution times. - -### Example - -Consider four processes with the following arrival and burst times: -- Process 1: Arrival time `1`, Burst time `3` -- Process 2: Arrival time `2`, Burst time `3` -- Process 3: Arrival time `3`, Burst time `5` -- Process 4: Arrival time `4`, Burst time `1` - -Using the SJR algorithm, the processes will be executed based on their remaining times and arrival sequence. - -## Problem Definition - -Given a list of processes with their corresponding arrival times and burst times, calculate the waiting times, turnaround times, average waiting time, and average turnaround time for the processes. - -### Key Concepts - -- **Waiting Time**: The amount of time a process spends waiting before it starts executing. -- **Turnaround Time**: The total time taken for a process from arrival to completion, which includes both the waiting time and burst time. - -## SJR Scheduling Approach - -In the SJR algorithm: -- The waiting time is calculated based on the execution order of the processes with the shortest remaining time. -- Processes can be preempted if a newly arriving process has a shorter burst time than the remaining time of the currently executing process. - -## Code Implementation in Python - -Below is the Python implementation for the SJR scheduling algorithm: - -```python -from __future__ import annotations -import pandas as pd - -def calculate_waiting_time(arrival_time: list[int], burst_time: list[int], num_processes: int) -> list[int]: - remaining_time = burst_time.copy() - waiting_time = [0] * num_processes - - completed_processes = 0 - current_time = 0 - min_remaining_time = float('inf') - shortest_process = 0 - process_found = False - - while completed_processes != num_processes: - for j in range(num_processes): - if (arrival_time[j] <= current_time and remaining_time[j] > 0 - and remaining_time[j] < min_remaining_time): - min_remaining_time = remaining_time[j] - shortest_process = j - process_found = True - - if not process_found: - current_time += 1 - continue - - remaining_time[shortest_process] -= 1 - - min_remaining_time = remaining_time[shortest_process] - if min_remaining_time == 0: - min_remaining_time = float('inf') - - if remaining_time[shortest_process] == 0: - completed_processes += 1 - finish_time = current_time + 1 - waiting_time[shortest_process] = finish_time - arrival_time[shortest_process] - burst_time[shortest_process] - waiting_time[shortest_process] = max(waiting_time[shortest_process], 0) - - current_time += 1 - - return waiting_time - -def calculate_turnaround_time(burst_time: list[int], num_processes: int, waiting_time: list[int]) -> list[int]: - return [burst + wait for burst, wait in zip(burst_time, waiting_time)] - -def calculate_average_times(waiting_time: list[int], turnaround_time: list[int], num_processes: int) -> None: - total_waiting_time = sum(waiting_time) - total_turnaround_time = sum(turnaround_time) - print(f"Average waiting time = {total_waiting_time / num_processes:.5f}") - print("Average turnaround time =", total_turnaround_time / num_processes) - -if __name__ == "__main__": - print("Enter how many processes you want to analyze:") - num_processes = int(input()) - burst_time = [0] * num_processes - arrival_time = [0] * num_processes - processes = list(range(1, num_processes + 1)) - - for i in range(num_processes): - print("Enter the arrival time and burst time for process:", i + 1) - arrival_time[i], burst_time[i] = map(int, input().split()) - - waiting_time = calculate_waiting_time(arrival_time, burst_time, num_processes) - turnaround_time = calculate_turnaround_time(burst_time, num_processes, waiting_time) - - calculate_average_times(waiting_time, turnaround_time, num_processes) - - fcfs = pd.DataFrame( - list(zip(processes, burst_time, arrival_time, waiting_time, turnaround_time)), - columns=[ - "Process", - "Burst Time", - "Arrival Time", - "Waiting Time", - "Turnaround Time", - ], - ) - - pd.set_option("display.max_rows", fcfs.shape[0] + 1) - print(fcfs) -``` - -# Explanation of the Code - -## Waiting Time Calculation - -The waiting time is calculated by tracking the remaining times of each process as they are executed in order of their shortest remaining time. - -## Turnaround Time Calculation - -Turnaround time is calculated as the sum of waiting time and burst time for each process. - -## Average Times - -The average waiting time and turnaround time are printed by dividing the total by the number of processes. - -## Example Output - -For the input where the arrival and burst times are: - -- **Arrival Time**: `[1, 2, 3, 4]` -- **Burst Time**: `[3, 3, 5, 1]` - -The output will display the waiting and turnaround times, as well as the average values for all processes. - -## Time and Space Complexity - -- **Time Complexity**: The time complexity is O(n²) due to the nested loops for finding the shortest job remaining. -- **Space Complexity**: The space complexity is O(n) for storing waiting times and turnaround times. - -## Conclusion - -The **Shortest Job Remaining First (SJR)** scheduling algorithm effectively minimizes waiting times for processes by executing the shortest jobs first. However, it may lead to **starvation** for longer processes if shorter jobs continue to arrive. \ No newline at end of file diff --git a/docs/algorithms/Scheduling Algorithms/SweepLine.md b/docs/algorithms/Scheduling Algorithms/SweepLine.md deleted file mode 100644 index 98fc083f6..000000000 --- a/docs/algorithms/Scheduling Algorithms/SweepLine.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: sweep-line-algorithm -sidebar_position: 3 -title: Sweep Line Algorithm -sidebar_label: Sweep Line Algorithm -description: "This document explains the Merge Intervals problem using the Sweep Line Algorithm, including its description, approach, and implementation in C++." -tags: [leetcode, algorithms, problem-solving, sweep-line-algo] ---- - -# sweep-line-merge-intervals - -## Description -Given an array of intervals where `intervals[i] = [start_i, end_i]`, merge all overlapping intervals and return an array of the non-overlapping intervals that cover all the intervals in the input. - -### Example: -**Input**: `intervals = [[1,3],[2,6],[8,10],[15,18]]` -**Output**: `[[1,6],[8,10],[15,18]]` -**Explanation**: Since intervals [1,3] and [2,6] overlap, merge them into [1,6]. - -## Approach - -This approach uses a **sweep line algorithm**. Here's how it works: - -1. **Transform the intervals into events**: - - Each interval generates two events: one at the start and one at the end. A start event increases the "active" interval count, while an end event decreases it. -2. **Sort all events**: - - Sort events primarily by time. If two events have the same time, prioritize end events over start events. This ensures the correct merging of intervals. -3. **Sweep through the events**: - - Track when new intervals start and end based on active intervals, and merge intervals accordingly. - -## C++ Implementation - -```cpp -#include -#include -#include - -class Solution { -public: - std::vector> merge(std::vector>& intervals) { - // Step 1: Create events (start and end) from each interval - std::vector> events; - for (const auto& interval : intervals) { - events.push_back({interval[0], 1}); // Start event (+1) - events.push_back({interval[1], -1}); // End event (-1) - } - - // Step 2: Sort events. Sort by time, and if equal, end (-1) comes before start (+1) - std::sort(events.begin(), events.end(), [](const std::pair& a, const std::pair& b) { - if (a.first == b.first) return a.second < b.second; - return a.first < b.first; - }); - - // Step 3: Sweep through the events and merge intervals - std::vector> merged; - int active = 0; // Active intervals count - int start = -1; // Start of the current interval - - for (const auto& event : events) { - if (active == 0) { - // No active intervals, so this is the start of a new interval - start = event.first; - } - - // Update the active intervals count - active += event.second; - - if (active == 0) { - // When active becomes 0, we finished an interval - merged.push_back({start, event.first}); - } - } - - return merged; - } -}; - -int main() { - Solution sol; - std::vector> intervals = {{1, 3}, {2, 6}, {8, 10}, {15, 18}}; - - std::vector> result = sol.merge(intervals); - - for (const auto& interval : result) { - std::cout << "[" << interval[0] << "," << interval[1] << "] "; - } - - return 0; -} -``` - -## Time and Space Complexity -- **Time Complexity**:O(n log n), where n is the number of intervals. Sorting the events takes O(n log n), and the sweeping phase takes O(n). -- **Space Complexity**: O(n) due to the space used for storing events and the output merged intervals. - - diff --git a/docs/algorithms/Scheduling Algorithms/_category_.json b/docs/algorithms/Scheduling Algorithms/_category_.json deleted file mode 100644 index 6bac5ad86..000000000 --- a/docs/algorithms/Scheduling Algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Scheduling Algorithms", - "position": 3, - "link": { - "type": "generated-index", - "description": "Learn about some Scheduling Algorithms." - } - } \ No newline at end of file diff --git a/docs/algorithms/Scheduling Algorithms/least-recently-used.md b/docs/algorithms/Scheduling Algorithms/least-recently-used.md deleted file mode 100644 index 487e2b4c8..000000000 --- a/docs/algorithms/Scheduling Algorithms/least-recently-used.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -id: least-recently-used-scheduling -title: Least Recently used Scheduling -sidebar_label: "Least Recently used Scheduling" -sidebar_position: 6 -description: An overview of Least Recently Used Scheduling and its applications in programming. -tags: [CPU Scheduling, algorithms, programming, LRU] ---- - -LRU (Least Recently Used) is a cache replacement algorithm that removes the least recently accessed item when the cache reaches its maximum capacity. It tracks the order in which items are used, ensuring that the most recently accessed items remain in the cache while the least recently accessed are evicted. - -- **Key Idea:** When a new item is accessed or added to the cache, it is moved to the front, and when the cache is full, the item at the end (least recently used) is removed. - -## Where It Is Used -- Used in systems where limited memory is allocated for caching frequently accessed data (e.g., web browsers, CPU cache, database management). -- Operating systems implement it for paging to replace the least recently used memory pages. - -## Steps to Implement LRU -1. **Check Cache Size:** If the cache is full, remove the least recently used item. -2. **Access or Add New Item:** Move the accessed item to the front of the cache. -3. **Update Order:** Reorder the items so that the most recently used item is at the front and the least recently used is at the end. - -## Example - -Consider a cache with a capacity of 3: -- **Initial Cache:** `[]` -- **Access 1:** Cache becomes `[1]` -- **Access 2:** Cache becomes `[2, 1]` -- **Access 3:** Cache becomes `[3, 2, 1]` -- **Access 1:** Cache becomes `[1, 3, 2]` (1 is most recently used) -- **Access 4:** Cache becomes `[4, 1, 3]` (2 is evicted) - -## Time Complexity Analysis - -### Best Case Scenario: -In the best case, when accessing or adding an item that is already in the cache, the LRU algorithm only needs to reorder the items. - -#### Example: -- Cache: `[3, 2, 1]` -- Accessing `3` (already in cache), simply move `3` to the front. - -- **Time Complexity (Best Case):** `O(1)` for access and reorder operations, assuming the use of a data structure like a hash map with a doubly linked list. - -### Worst Case Scenario: -In the worst case, when adding an item to a full cache, the LRU algorithm must remove the least recently used item and add the new item to the cache. - -#### Example: -- Cache: `[3, 2, 1]` (full) -- Accessing `4` (not in cache), remove `1`, add `4`, and reorder the list. - -- **Time Complexity (Worst Case):** `O(1)` for removing and adding operations (with a hash map and linked list), but if not implemented efficiently, it can be `O(n)` where `n` is the size of the cache (for searching and removing). - -### Detailed Best and Worst Case Analysis: -- **Best Case:** Accessing or updating an existing element is `O(1)` when using a hash map for fast lookups and a doubly linked list to maintain the access order. -- **Worst Case:** Adding a new element to a full cache, followed by removing the least recently used element, still results in `O(1)` operations using an efficient combination of hash map and linked list. - -### Summary of Time Complexities: -- **Best Case Time Complexity:** `O(1)` for accessing or updating an existing element. -- **Worst Case Time Complexity:** `O(1)` for removing the least recently used item and adding a new item in an efficiently implemented cache. - -## Advantages -- **Efficient for Cache Replacement:** Quickly identifies and removes the least recently used items. -- **Simple to Implement:** LRU logic is relatively simple when using appropriate data structures (hash map + linked list). - -## Disadvantages -- **Memory Overhead:** Requires additional memory to maintain the linked list and hash map. -- **Complexity in Implementation:** Requires careful implementation to ensure efficient `O(1)` access and modification times. - -## C Implementation - -```c -#include -#include - -#define CAPACITY 3 - -struct Node { - int key; - struct Node* prev; - struct Node* next; -}; - -struct LRUCache { - struct Node* head; - struct Node* tail; - int size; -}; - -struct LRUCache* createCache() { - struct LRUCache* cache = (struct LRUCache*) malloc(sizeof(struct LRUCache)); - cache->head = NULL; - cache->tail = NULL; - cache->size = 0; - return cache; -} - -void accessCache(struct LRUCache* cache, int key) { - // Implementation to access and reorder the cache items - // Code omitted for brevity -} - -int main() { - struct LRUCache* cache = createCache(); - accessCache(cache, 1); - accessCache(cache, 2); - accessCache(cache, 3); - accessCache(cache, 4); // Evicts least recently used item - return 0; -} -``` -## Python Implementation - -```c -class LRUCache: - def __init__(self, capacity: int): - self.cache = {} - self.capacity = capacity - self.order = [] - - def get(self, key: int) -> int: - if key in self.cache: - self.order.remove(key) - self.order.insert(0, key) - return self.cache[key] - return -1 - - def put(self, key: int, value: int) -> None: - if key in self.cache: - self.order.remove(key) - elif len(self.cache) == self.capacity: - lru = self.order.pop() - del self.cache[lru] - self.order.insert(0, key) - self.cache[key] = value - -# Example usage: -cache = LRUCache(3) -cache.put(1, 1) -cache.put(2, 2) -cache.put(3, 3) -cache.get(1) # Access 1, makes it most recently used -cache.put(4, 4) # Evicts 2 - -``` -## Java Implementation - -```c -import java.util.LinkedHashMap; -import java.util.Map; - -class LRUCache extends LinkedHashMap { - private int capacity; - - public LRUCache(int capacity) { - super(capacity, 0.75f, true); - this.capacity = capacity; - } - - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > capacity; - } - - public static void main(String[] args) { - LRUCache cache = new LRUCache(3); - cache.put(1, 1); - cache.put(2, 2); - cache.put(3, 3); - cache.get(1); // Accesses 1, makes it most recently used - cache.put(4, 4); // Evicts 2 - } -} - -``` diff --git a/docs/algorithms/Scheduling Algorithms/multilevel-queue-scheduling.md b/docs/algorithms/Scheduling Algorithms/multilevel-queue-scheduling.md deleted file mode 100644 index 33272e298..000000000 --- a/docs/algorithms/Scheduling Algorithms/multilevel-queue-scheduling.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -id: multilevel-queue-scheduling -title: Multilevel Queue Scheduling Algorithm -sidebar_label: "Multilevel Queue Scheduling Algorithm" -sidebar_position: 7 -description: An overview of the Multilevel Queue Scheduling Algorithm and its applications in programming. -tags: [CPU Scheduling, algorithms, programming, queue] ---- - -Multilevel Queue Scheduling is a type of CPU scheduling algorithm where the processes are divided into multiple queues based on certain criteria (like process priority or memory size). Each queue can have its own scheduling algorithm, and processes do not move between queues. - -- It is mainly used in systems that can separate processes into categories, such as real-time, system processes, or user processes. -- Each queue has a different priority level. - -## Where It Is Used -- Real-time systems where priority segregation is needed. -- Time-sharing systems where interactive processes need faster responses. -- Systems where different types of processes (foreground, background, etc.) need to be handled differently. - -## Steps to Perform Multilevel Queue Scheduling - -1. **Divide Processes:** Split the processes into multiple queues based on their types, priorities, or other criteria. -2. **Assign Scheduling Algorithms:** Each queue may have a distinct scheduling algorithm (e.g., FIFO, Round Robin). -3. **Fixed Priority Scheduling:** Each queue is assigned a fixed priority. Higher-priority queues are executed before lower-priority ones. -4. **Execution:** Processes are executed from higher-priority queues first. If there is no process in the higher-priority queue, the scheduler executes processes from the lower-priority queues. - -## Example - -Consider a system with three queues: -- **Queue 1**: System processes (priority 1, uses FIFO) -- **Queue 2**: Interactive processes (priority 2, uses Round Robin) -- **Queue 3**: Batch processes (priority 3, uses Round Robin) - -If there are no system processes, the CPU schedules processes from the interactive queue. If no interactive processes are present, it schedules batch processes. - -## Time Complexity Analysis - -### Best Case Scenario: -In the best case, all processes are in the highest-priority queue, which allows the CPU to execute them without needing to check other queues. For example: - -#### Example: -Let's say there are 3 queues: -- **Queue 1**: 5 high-priority processes (using FIFO) -- **Queue 2**: 3 medium-priority processes (using Round Robin) -- **Queue 3**: 2 low-priority processes (using Round Robin) - -If all processes are in **Queue 1**, the CPU only needs to execute the processes in that queue without checking the other queues. - -- **Time Complexity (Best Case):** `O(1)` for each process, because the scheduler simply picks the next process in **Queue 1** (using FIFO). -- For **n** processes in the highest-priority queue, the complexity is `O(n)`. - -### Worst Case Scenario: -In the worst case, the CPU has to check multiple queues and switch between different scheduling algorithms. - -#### Example: -Let's consider the same three queues: -- **Queue 1**: Empty -- **Queue 2**: 3 medium-priority processes (Round Robin) -- **Queue 3**: 2 low-priority processes (Round Robin) - -Here, the CPU first checks **Queue 1**, finds it empty, and then moves to **Queue 2**. After executing a process in **Queue 2**, it may have to perform a context switch and check **Queue 3** if all processes in **Queue 2** have finished. This adds overhead. - -- **Time Complexity (Worst Case):** - - The worst-case complexity arises from checking multiple queues and handling context switches between different queues and scheduling algorithms. This can be **O(n)** per queue. - - For **k** queues with **n** processes spread across them, the worst-case time complexity could be **O(k × n)**. - -#### Detailed Worst Case Example: -- **Queue 1**: Empty -- **Queue 2**: 3 processes with Round Robin scheduling. -- **Queue 3**: 2 processes with Round Robin scheduling. - -At each step: -1. CPU checks **Queue 1** → Empty (Time: O(1)) -2. CPU checks **Queue 2** → Executes a process (Time: O(1)) -3. CPU checks **Queue 3** → Executes a process (Time: O(1)) - -Total checks across **k** queues with **n** processes lead to **O(k × n)**, where **k** is the number of queues. - - - - -## Advantages -- **Separation of Processes:** Processes with different requirements can be separated and handled by different scheduling algorithms. -- **Efficient for Real-Time Systems:** High-priority tasks can be executed immediately. -- **Customizability:** Each queue can have its own scheduling algorithm. - -## Disadvantages -- **Rigid Queue Structure:** Processes cannot move between queues, which can lead to inefficiency. -- **Starvation Risk:** Lower-priority queues might starve if higher-priority queues are always full. -- **Complexity:** Managing multiple queues and algorithms increases complexity. - -## C Implementation - -```c -#include - -#define HIGH_PRIORITY 1 -#define LOW_PRIORITY 2 - -struct process { - int pid; - int priority; -}; - -void multilevelQueueScheduling(struct process p[], int n) { - printf("Scheduling high-priority processes (priority 1):\n"); - for (int i = 0; i < n; i++) { - if (p[i].priority == HIGH_PRIORITY) { - printf("Process %d is running\n", p[i].pid); - } - } - - printf("Scheduling low-priority processes (priority 2):\n"); - for (int i = 0; i < n; i++) { - if (p[i].priority == LOW_PRIORITY) { - printf("Process %d is running\n", p[i].pid); - } - } -} - -int main() { - struct process p[] = {{1, HIGH_PRIORITY}, {2, LOW_PRIORITY}, {3, HIGH_PRIORITY}, {4, LOW_PRIORITY}}; - int n = sizeof(p) / sizeof(p[0]); - - multilevelQueueScheduling(p, n); - return 0; -} -``` -## Python Implementation -```c -class Process: - def __init__(self, pid, priority): - self.pid = pid - self.priority = priority - -def multilevel_queue_scheduling(processes): - print("Scheduling high-priority processes (priority 1):") - for process in processes: - if process.priority == 1: - print(f"Process {process.pid} is running") - - print("Scheduling low-priority processes (priority 2):") - for process in processes: - if process.priority == 2: - print(f"Process {process.pid} is running") - -processes = [Process(1, 1), Process(2, 2), Process(3, 1), Process(4, 2)] -multilevel_queue_scheduling(processes) - -``` -## Java Implementation -```c -class Process { - int pid; - int priority; - - Process(int pid, int priority) { - this.pid = pid; - this.priority = priority; - } -} - -public class MultilevelQueueScheduling { - public static void main(String[] args) { - Process[] processes = { - new Process(1, 1), - new Process(2, 2), - new Process(3, 1), - new Process(4, 2) - }; - - System.out.println("Scheduling high-priority processes (priority 1):"); - for (Process p : processes) { - if (p.priority == 1) { - System.out.println("Process " + p.pid + " is running"); - } - } - - System.out.println("Scheduling low-priority processes (priority 2):"); - for (Process p : processes) { - if (p.priority == 2) { - System.out.println("Process " + p.pid + " is running"); - } - } - } -} - -``` diff --git a/docs/algorithms/Scheduling Algorithms/priority-scheduling.md b/docs/algorithms/Scheduling Algorithms/priority-scheduling.md deleted file mode 100644 index f7cceb038..000000000 --- a/docs/algorithms/Scheduling Algorithms/priority-scheduling.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -id: Priority-Scheduling -title: Priority Scheduling -sidebar_label: "Priority Scheduling" -sidebar_position: 6 -description: An overview of Priority Scheduling and its applications in programming. -tags: [CPU Scheduling, algorithms, programming, priority] ---- - -# Priority Scheduling - -**Priority Scheduling** is a CPU scheduling algorithm where each process is assigned a priority, and the CPU is allocated to the process with the highest priority. The process with the highest priority gets executed first. If two processes have the same priority, a scheduling algorithm like FCFS (First-Come, First-Serve) or Round Robin is used to break the tie. - -## Steps of Priority Scheduling: -1. **Assign Priority**: Each process in the queue is assigned a priority value. -2. **Sort Processes**: Sort the processes based on their priority. -3. **Execute Process**: Allocate CPU to the process with the highest priority. -4. **Re-Evaluate Priorities**: When a process completes or is preempted, re-evaluate the remaining processes and pick the next highest-priority process. -5. **Handle Ties**: If two processes have the same priority, handle them using another scheduling technique (like FCFS). - -There are two types of Priority Scheduling: -- **Preemptive**: The currently executing process can be preempted if a new process with a higher priority arrives. -- **Non-preemptive**: The currently executing process finishes before a new process can start, even if a higher-priority process arrives. - ---- - -## Example of Priority Scheduling: - -### Example Process Table - -| Process | Arrival Time | Burst Time | Priority | -|---------|--------------|------------|----------| -| P1 | 0 | 10 | 3 | -| P2 | 1 | 1 | 1 | -| P3 | 2 | 2 | 4 | -| P4 | 3 | 1 | 5 | - -### Non-Preemptive Priority Scheduling - -- At time 0, P1 arrives, but P2 arrives at time 1 with a higher priority. So P2 executes first. -- After P2 finishes, P1 resumes execution. -- After P1 finishes, P3 executes as it has a higher priority than P4. - -**Gantt Chart**: -**| P2 | P1 | P3 | P4 |** - - ---- - -## Time Complexity Analysis - -### Best Case Time Complexity: **O(n log n)** - -- Sorting the processes based on priority will take **O(n log n)**. -- In the best case, if no new higher-priority processes arrive during execution, we only need to sort and then execute sequentially. - -**Best Case Example**: -If all processes arrive at the same time and are already sorted by priority. - -### Worst Case Time Complexity: **O(n²)** - -- In the worst case (especially for preemptive scheduling), a new process with a higher priority arrives just before the current process finishes. This requires frequent preemption, and the process list must be updated multiple times, resulting in **O(n²)**. - -**Worst Case Example**: -Each time a process is about to finish, a higher-priority process arrives, causing frequent preemption. - ---- - -## Advantages of Priority Scheduling -1. **Efficient Handling of Critical Tasks**: Higher-priority tasks (e.g., system-critical processes) get CPU time first. -2. **Flexible**: Can handle a variety of systems by dynamically changing priority values. -3. **Preemption Capability**: Preemptive priority scheduling can ensure that important processes are not starved for resources. - -## Disadvantages of Priority Scheduling -1. **Starvation**: Lower-priority processes may never get CPU time if higher-priority processes keep arriving. -2. **Complexity**: Dynamically adjusting priorities can increase system complexity. -3. **Indefinite Blocking**: A lower-priority process may never get executed if new, higher-priority processes keep arriving. - ---- - -## Implementation of Priority Scheduling - -### C Implementation - -```c -#include - -struct Process { - int id; - int burstTime; - int priority; -}; - -void priorityScheduling(struct Process processes[], int n) { - struct Process temp; - - // Sort based on priority - for (int i = 0; i < n - 1; i++) { - for (int j = i + 1; j < n; j++) { - if (processes[i].priority > processes[j].priority) { - temp = processes[i]; - processes[i] = processes[j]; - processes[j] = temp; - } - } - } - - printf("Process Execution Order:\n"); - for (int i = 0; i < n; i++) { - printf("P%d (Priority: %d)\n", processes[i].id, processes[i].priority); - } -} - -int main() { - struct Process processes[] = {{1, 10, 3}, {2, 1, 1}, {3, 2, 4}, {4, 1, 5}}; - int n = sizeof(processes) / sizeof(processes[0]); - - priorityScheduling(processes, n); - return 0; -} -``` -# 2) Python Implementation -```c - - -class Process: - def __init__(self, pid, burst_time, priority): - self.pid = pid - self.burst_time = burst_time - self.priority = priority - -def priority_scheduling(processes): - # Sort processes based on priority - processes.sort(key=lambda x: x.priority) - - print("Process Execution Order:") - for process in processes: - print(f"P{process.pid} (Priority: {process.priority})") - -processes = [ - Process(1, 10, 3), - Process(2, 1, 1), - Process(3, 2, 4), - Process(4, 1, 5) -] - -priority_scheduling(processes) -``` - -# 3) Java Implementation - -```c -import java.util.Arrays; - -class Process { - int pid; - int burstTime; - int priority; - - Process(int pid, int burstTime, int priority) { - this.pid = pid; - this.burstTime = burstTime; - this.priority = priority; - } -} - -public class PriorityScheduling { - public static void priorityScheduling(Process[] processes) { - Arrays.sort(processes, (p1, p2) -> p1.priority - p2.priority); - - System.out.println("Process Execution Order:"); - for (Process p : processes) { - System.out.println("P" + p.pid + " (Priority: " + p.priority + ")"); - } - } - - public static void main(String[] args) { - Process[] processes = { - new Process(1, 10, 3), - new Process(2, 1, 1), - new Process(3, 2, 4), - new Process(4, 1, 5) - }; - - priorityScheduling(processes); - } -} - -``` diff --git a/docs/algorithms/Searching Algorithms/A*-Search.md b/docs/algorithms/Searching Algorithms/A*-Search.md deleted file mode 100644 index 8fe5bcf96..000000000 --- a/docs/algorithms/Searching Algorithms/A*-Search.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: a-*-search -sidebar_position: 1 -title: A* Search -sidebar_label: A* ---- - -### Definition: - -**A* Search** is a pathfinding and graph traversal algorithm used to find the shortest path from a starting point to a goal. It combines the actual cost from the starting point and a heuristic estimate of the cost to reach the goal, making it both efficient and effective in scenarios where an optimal path is needed. - -### Characteristics: - -- **Heuristic-Based**: Utilizes heuristics to prioritize nodes. -- **Optimal**: Finds the shortest path if the heuristic is admissible. -- **Complete**: Ensures a solution is found if one exists. - -### How A* Works: - -1. **Initialize**: Start with the initial node in the open list. -2. **Expand**: Select the node with the lowest estimated total cost. -3. **Explore Neighbors**: For each unvisited neighbor, calculate the cost, update if lower. -4. **Repeat**: Continue until reaching the goal node or the open list is empty. - -### Time Complexity: - -- **Time Complexity**: \(O(b^d)\), where `b` is the branching factor and `d` is the depth of the solution. - -### Space Complexity: - -- **Space Complexity**: \(O(b^d)\) - -### Advantages of A*: - -- **Optimal Path**: Finds the shortest path in a graph. -- **Efficient Exploration**: Heuristic allows focusing on promising paths. - -### Disadvantages of A*: - -- **Memory Usage**: Can require high memory for large graphs. -- **Dependence on Heuristic**: Performance relies on the quality of the heuristic. - -### A* Algorithm (Java Implementation): - -```java -import java.util.*; - -class Node implements Comparable { - int x, y, cost, heuristic; - - Node(int x, int y, int cost, int heuristic) { - this.x = x; - this.y = y; - this.cost = cost; - this.heuristic = heuristic; - } - - @Override - public int compareTo(Node other) { - return Integer.compare(this.cost + this.heuristic, other.cost + other.heuristic); - } -} - -class AStarAlgorithm { - public static List aStarSearch(Node start, Node goal) { - PriorityQueue openList = new PriorityQueue<>(); - Set closedList = new HashSet<>(); - openList.add(start); - - while (!openList.isEmpty()) { - Node current = openList.poll(); - if (current.equals(goal)) { - return reconstructPath(goal); - } - closedList.add(current); - - for (Node neighbor : getNeighbors(current)) { - if (closedList.contains(neighbor)) continue; - int tentativeCost = current.cost + calculateCost(current, neighbor); - - if (!openList.contains(neighbor) || tentativeCost < neighbor.cost) { - neighbor.cost = tentativeCost; - neighbor.heuristic = calculateHeuristic(neighbor, goal); - openList.add(neighbor); - } - } - } - return null; // Goal not reached - } - - // Dummy implementations for path reconstruction, neighbors, and heuristics - private static List reconstructPath(Node goal) { return new ArrayList<>(); } - private static List getNeighbors(Node node) { return new ArrayList<>(); } - private static int calculateCost(Node current, Node neighbor) { return 1; } - private static int calculateHeuristic(Node current, Node goal) { return Math.abs(current.x - goal.x) + Math.abs(current.y - goal.y); } -} -``` -### Applications of A*: -Pathfinding: Used in games, robotics, and network routing. -AI for Games: Determines optimal paths in dynamic environments. -Robotics: Helps in navigating obstacles effectively. -### Summary: -A* Search is an optimal, heuristic-based search algorithm with broad applications in AI, robotics, and pathfinding. Its focus on efficient pathfinding while guaranteeing optimality makes it a key algorithm in many fields. diff --git a/docs/algorithms/Searching Algorithms/AO*-Search.md b/docs/algorithms/Searching Algorithms/AO*-Search.md deleted file mode 100644 index 1956a0fb5..000000000 --- a/docs/algorithms/Searching Algorithms/AO*-Search.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: ao-star-search -sidebar_position: 2 -title: AO* Search -sidebar_label: AO* ---- - -### Definition: - -**AO* Search** is an algorithm designed for AND-OR graphs, where nodes may have both AND and OR conditions. This is common in decision-making and problem-solving applications where subproblems must be solved together or independently to reach a solution. - -### Characteristics: - -- **AND-OR Structure**: Solves problems with combined conditions. -- **Heuristic-Based**: Uses heuristics for efficient traversal. -- **Backtracking**: Updates cost estimates and paths dynamically. - -### How AO* Works: - -1. **Initialize**: Start with the root node. -2. **Evaluate Nodes**: Expand nodes based on heuristic values. -3. **Select Optimal Paths**: Choose paths with minimum costs, backtracking if needed. -4. **Repeat**: Continue until reaching a terminal node or completing all AND-conditions. - -### Time Complexity: - -- **Time Complexity**: Variable, based on graph complexity and heuristic. - -### Space Complexity: - -- **Space Complexity**: \(O(n)\) - -### Advantages of AO*: - -- **Solves Complex Problems**: Ideal for problems with AND-OR structures. -- **Heuristic Efficiency**: Minimizes unnecessary expansions. - -### Disadvantages of AO*: - -- **Dependent on Heuristic**: Heuristic choice impacts performance. -- **Complexity in Large Graphs**: May become inefficient on large, complex graphs. - -### AO* Algorithm (Java Implementation): - -```java -// Placeholder for a general AO* graph node -class AONode { - List children; - int cost; - boolean isANDNode; - - AONode(int cost, boolean isANDNode) { - this.cost = cost; - this.isANDNode = isANDNode; - children = new ArrayList<>(); - } -} - -class AOStar { - public static int aoStarSearch(AONode startNode) { - return search(startNode); - } - - private static int search(AONode node) { - if (node.children.isEmpty()) return node.cost; - - int totalCost = node.isANDNode ? 0 : Integer.MAX_VALUE; - for (AONode child : node.children) { - int childCost = search(child); - if (node.isANDNode) totalCost += childCost; - else totalCost = Math.min(totalCost, childCost); - } - return totalCost; - } -} -``` -### Applications of AO*: -Decision-Making in Expert Systems: Uses AND-OR logic for complex decisions. -Game Theory: Assesses multiple paths in strategic games. -Knowledge Representation: Maps complex rule-based systems. -### Summary: -AO* is powerful in scenarios involving both mandatory and optional paths (AND-OR) for reaching goals, making it ideal for expert systems and decision-making applications. diff --git a/docs/algorithms/Searching Algorithms/Best-First-Search.md b/docs/algorithms/Searching Algorithms/Best-First-Search.md deleted file mode 100644 index dc68cdd7e..000000000 --- a/docs/algorithms/Searching Algorithms/Best-First-Search.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: best-first-search -sidebar_position: 7 -title: Best-First Search -sidebar_label: BFS ---- -### Definition: -**Best-First Search (BFS)** is a graph traversal algorithm that selects the most promising node to expand based on a given heuristic. This heuristic is often the estimated cost or distance to the goal, and BFS chooses nodes that appear to lead most directly to the target. -### Characteristics: -- **Greedy Approach:** - BFS uses a greedy strategy by selecting the node with the lowest heuristic value, aiming to find the goal faster by following the path that seems most promising at each step. - -- **Heuristic Function:** - The algorithm uses a heuristic function `h(n)` to estimate the distance from the current node `n` to the goal node. This is central to how the algorithm prioritizes which nodes to explore. - -- **Priority Queue:** - BFS uses a priority queue (often a min-heap) to keep track of nodes, where the node with the lowest heuristic value is given priority for exploration. -### How BFS Works: -1. **Initialize the Priority Queue:** - Start by adding the initial node to the priority queue, assigning it a heuristic value based on how close it appears to be to the goal. -2. **Expand the Most Promising Node:** - Pop the node with the lowest heuristic value from the priority queue, mark it as visited, and explore its neighbors. -3. **Evaluate Neighbors:** - For each neighbor of the current node, assign a heuristic value and add it to the priority queue if it hasn’t been visited yet. -4. **Repeat:** - Repeat the process until the goal node is reached or all reachable nodes have been visited. -### Time Complexity: -- **Time Complexity**: O(V + E log V) - Where `V` is the number of vertices and `E` is the number of edges. The additional log factor comes from using the priority queue. -### Space Complexity: -- **Space Complexity**: O(V) - The space complexity is proportional to the number of vertices, as the priority queue will store each node once. -### Advantages of BFS: -- **Efficient for Shortest Paths:** - When combined with an appropriate heuristic, BFS can efficiently find the shortest or most optimal path in many scenarios. -- **Flexibility:** - Different heuristic functions can tailor BFS to different types of problems, making it versatile. -### Disadvantages of BFS: -- **Not Always Optimal:** - If the heuristic is not well-designed, BFS may not find the best solution or may get stuck in suboptimal areas. -- **Heuristic Dependency:** - The performance of BFS is highly dependent on the accuracy of the heuristic function. -### Best-First Search Algorithm (Java Implementation): -```java -import java.util.*; -class Graph { - private int numVertices; - private LinkedList adjList[]; - // Node class with heuristic value - class Node { - int vertex; - int heuristic; - Node(int v, int h) { - vertex = v; - heuristic = h; - } - } - // Constructor - Graph(int v) { - numVertices = v; - adjList = new LinkedList[v]; - for (int i = 0; i < v; ++i) - adjList[i] = new LinkedList<>(); - } - // Add edge to the graph - void addEdge(int v, int w, int h) { - adjList[v].add(new Node(w, h)); // Add w with heuristic h to v's list. - } - // Best-First Search function - void bestFirstSearch(int start, int goal) { - // Priority queue to store nodes with priority on heuristic - PriorityQueue pq = new PriorityQueue<>((a, b) -> a.heuristic - b.heuristic); - // Add the starting node to the priority queue - pq.add(new Node(start, 0)); - // Track visited nodes - boolean visited[] = new boolean[numVertices]; - // BFS Loop - while (!pq.isEmpty()) { - Node current = pq.poll(); - if (visited[current.vertex]) - continue; - visited[current.vertex] = true; - System.out.println("Visited node: " + current.vertex); - // If the goal is reached - if (current.vertex == goal) { - System.out.println("Goal reached: " + goal); - return; - } - // Explore neighbors - for (Node neighbor : adjList[current.vertex]) { - if (!visited[neighbor.vertex]) { - pq.add(new Node(neighbor.vertex, neighbor.heuristic)); - } - } - } - } - public static void main(String[] args) { - Graph g = new Graph(5); - g.addEdge(0, 1, 3); - g.addEdge(0, 2, 6); - g.addEdge(1, 3, 2); - g.addEdge(2, 4, 5); - g.addEdge(3, 4, 4); - System.out.println("Best-First Search traversal starting from node 0 to reach node 4:"); - g.bestFirstSearch(0, 4); // Perform BFS from node 0 to node 4 - } -} -``` -### Applications of BFS: -- Pathfinding in AI: BFS is widely used in AI for navigating mazes and finding optimal routes. -- Optimization Problems: BFS is useful in optimization problems like the Traveling Salesman Problem when paired with the right heuristic. -- Game Development: It is used in game AI for pathfinding, especially when the terrain or world map is large and complex. -- Network Routing: BFS is helpful in finding efficient routes in communication networks, balancing load, or finding optimal network paths. -### Summary: -Best-First Search is a powerful graph traversal algorithm that uses a heuristic to prioritize which nodes to explore. By selecting the most promising nodes first, BFS is able to efficiently find solutions to problems like pathfinding, optimization, and game AI. However, its success largely depends on the heuristic function used, and it may not always provide optimal solutions. diff --git a/docs/algorithms/Searching Algorithms/BinarySearch.md b/docs/algorithms/Searching Algorithms/BinarySearch.md deleted file mode 100644 index 70a9e33de..000000000 --- a/docs/algorithms/Searching Algorithms/BinarySearch.md +++ /dev/null @@ -1,248 +0,0 @@ ---- - -id: binary-search-algo -sidebar_position: 2 -title: Binary Search -sidebar_label: Binary Search - ---- - -### Definition: - -Binary search is an efficient algorithm for finding an element in a **sorted array**. It works by repeatedly dividing the search interval in half. If the target value is less than the middle element, the search continues in the left half; if the target is greater, the search continues in the right half. This process continues until the element is found or the search interval becomes empty. - -### Characteristics: - -- **Divide and Conquer**: - - Binary search applies the divide-and-conquer strategy by repeatedly halving the search space until the target element is found or the subarray is empty. - -- **Efficient for Sorted Data**: - - Binary search requires the input array to be sorted. It is highly efficient for large datasets compared to linear search. - -- **Works on Indexable Structures**: - - Binary search is best suited for data structures that allow **random access**, such as arrays, but not for linked lists, where traversal is sequential. - -- **Non-Adaptive**: - - Binary search does not adjust to find elements more quickly when there are patterns or duplicate elements in the array, unlike some adaptive algorithms. - -### Time Complexity: - -- **Best Case: $O(1)$** - In the best case, the middle element of the array is the target value, found after just one comparison. - -- **Average Case: $O(log n)$** - On average, binary search reduces the search space by half at each step, leading to a logarithmic time complexity. - -- **Worst Case: $O(log n)$** - In the worst case, the target element is not present in the array or is located at the extreme ends, requiring `log n` comparisons. - -### Space Complexity: - -- **Iterative: $O(1)$** - The iterative version of binary search requires a constant amount of memory for variables like the low and high indices. - -- **Recursive: $O(log n)$** - The recursive version of binary search uses additional space due to recursive function calls, leading to an O(log n) space complexity for storing stack frames. - -### When to Use Binary Search: - -- **Sorted Arrays**: - - Binary search is ideal for large, sorted datasets where quick searches are required. It is much faster than linear search in these cases. - -- **Searching for a Specific Element**: - - When you need to find a specific element in a sorted array and want to minimize the number of comparisons, binary search is the go-to choice. - -- **Efficient Lookups**: - - It is used in situations where fast lookup times are critical, such as in searching through large databases, dictionaries, or ordered lists. - -### C++ and Python Implementation: - -**Iterative Approach** -```cpp -#include -using namespace std; - -int binarySearchIterative(int arr[], int size, int target) { - int low = 0; - int high = size - 1; - - while (low <= high) { - int mid = low + (high - low) / 2; // Avoid overflow for large indices - - if (arr[mid] == target) { - return mid; // Target element found - } else if (arr[mid] < target) { - low = mid + 1; // Search in the right half - } else { - high = mid - 1; // Search in the left half - } - } - - return -1; // Return -1 if target is not found -} - -int main() { - int arr[] = {2, 3, 4, 10, 40}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 10; - - int result = binarySearchIterative(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` -```python -def binary_search_iterative(arr, target): - low = 0 - high = len(arr) - 1 - - while low <= high: - mid = low + (high - low) // 2 # Avoid overflow for large indices - - if arr[mid] == target: - return mid # Target element found - elif arr[mid] < target: - low = mid + 1 # Search in the right half - else: - high = mid - 1 # Search in the left half - - return -1 # Return -1 if target is not found - -def main(): - arr = [2, 3, 4, 10, 40] - target = 10 - - result = binary_search_iterative(arr, target) - - if result != -1: - print("Element found at index", result) - else: - print("Element not found") - -if __name__ == "__main__": - main() -``` - -**Recursive Approach** -```cpp -#include -using namespace std; - -int binarySearchRecursive(int arr[], int low, int high, int target) { - if (low <= high) { - int mid = low + (high - low) / 2; // Avoid overflow for large indices - - if (arr[mid] == target) { - return mid; // Target element found - } else if (arr[mid] < target) { - return binarySearchRecursive(arr, mid + 1, high, target); // Search in the right half - } else { - return binarySearchRecursive(arr, low, mid - 1, target); // Search in the left half - } - } - - return -1; // Return -1 if target is not found -} - -int main() { - int arr[] = {2, 3, 4, 10, 40}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 10; - - int result = binarySearchRecursive(arr, 0, size - 1, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` -```python -def binary_search_recursive(arr, low, high, target): - if low <= high: - mid = low + (high - low) // 2 # Avoid overflow for large indices - - if arr[mid] == target: - return mid # Target element found - elif arr[mid] < target: - return binary_search_recursive(arr, mid + 1, high, target) # Search in the right half - else: - return binary_search_recursive(arr, low, mid - 1, target) # Search in the left half - - return -1 # Return -1 if target is not found - -def main(): - arr = [2, 3, 4, 10, 40] - target = 10 - - result = binary_search_recursive(arr, 0, len(arr) - 1, target) - - if result != -1: - print("Element found at index", result) - else: - print("Element not found") - -if __name__ == "__main__": - main() -``` -### Variations of Binary Search: - -- **Finding the First or Last Occurrence**: - - Binary search can be modified to find the first or last occurrence of a target element in a sorted array. This is useful when the array contains duplicate elements. - -- **Finding the Smallest/Largest Element Greater/Less than Target**: - - Binary search can be adapted to find the smallest element greater than the target or the largest element less than the target. This is known as a lower or upper bound search. - -### Use Cases: - -- **Efficient Search in Sorted Data**: - - Binary search is often used in large datasets, such as databases, to perform efficient lookups or range queries in sorted data. - -- **Searching in Static Data**: - - When the dataset doesn't change often, binary search is the preferred choice due to its efficiency, especially for read-heavy applications. - -- **Standard Library Implementations**: - - Many programming languages provide binary search implementations in their standard libraries. In C++, the `std::binary_search` function can be used directly to search sorted containers like `vector` or `array`. - -### Advantages and Disadvantages: - -#### Advantages: -- **Efficient for Large Datasets**: - - Binary search drastically reduces the number of comparisons needed to find an element, making it ideal for large, sorted arrays. - -- **Logarithmic Time Complexity**: - - The O(log n) time complexity makes binary search much faster than linear search for large datasets. - -- **Low Memory Usage**: - - The iterative version of binary search has a constant space complexity of O(1), making it memory efficient. - -#### Disadvantages: -- **Requires Sorted Data**: - - Binary search can only be applied to sorted arrays, limiting its use in scenarios where the data is unsorted. - -- **Poor Performance on Small Datasets**: - - For small datasets, the overhead of calculating midpoints and repeatedly halving the search space may make binary search less efficient than linear search. - -- **Not Suitable for Linked Lists**: - - Binary search requires random access to elements (i.e., indexing), which is not possible in linked lists or other sequential data structures. - -### Optimizations and Applications: - -- **Exponential Search**: - - When the size of the array is unknown or infinite, binary search can be combined with exponential search to first find a range where the target might exist and then apply binary search within that range. - -- **Ternary Search**: - - A variation of binary search, called **ternary search**, divides the array into three parts instead of two, and performs two comparisons per iteration. It works well for unimodal functions but is rarely faster than binary search. - -### Summary: - -Binary search is an efficient and widely-used algorithm for searching through large, sorted datasets. It operates in O(log n) time complexity, making it far superior to linear search for large arrays. Binary search is well-suited for scenarios where the dataset is static or sorted in advance, such as in databases or ordered lists. While it is not suitable for unsorted data or linked lists, its power in sorted datasets makes it a fundamental algorithm in computer science. diff --git a/docs/algorithms/Searching Algorithms/Boyer-Moore-Search.md b/docs/algorithms/Searching Algorithms/Boyer-Moore-Search.md deleted file mode 100644 index 70b74d81b..000000000 --- a/docs/algorithms/Searching Algorithms/Boyer-Moore-Search.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -id: boyer-moore-search -sidebar_position: 5 -title: Boyer-Moore Search -sidebar_label: Boyer-Moore ---- - -### Definition: - -**Boyer-Moore Search** is a string-search algorithm that skips sections of text to improve efficiency, making it highly effective for long text searches. It relies on two heuristics—bad character rule and good suffix rule—to skip sections that don’t match, enabling faster matching. - -### Characteristics: - -- **String Matching**: Efficient for matching strings in long texts. -- **Heuristic-Based Skipping**: Uses heuristics to skip mismatching sections. -- **Backward Matching**: Compares the pattern from right to left. - -### How Boyer-Moore Works: - -1. **Initialize**: Place pattern at the start of the text. -2. **Compare Backwards**: Match the pattern from right to left. -3. **Skip**: Use heuristics to skip mismatching sections. -4. **Repeat**: Continue until the pattern is found or text is exhausted. - -### Time Complexity: - -- **Best Case**: \(O(n/m)\), where `n` is the length of the text and `m` is the length of the pattern. -- **Worst Case**: \(O(n \times m)\) - -### Space Complexity: - -- **Space Complexity**: \(O(m)\) for storing pattern rules. - -### Advantages of Boyer-Moore: - -- **High Efficiency**: Reduces unnecessary comparisons. -- **Ideal for Large Texts**: Particularly effective with long strings. - -### Disadvantages of Boyer-Moore: - -- **Complex Heuristic**: More challenging to implement than simpler algorithms. -- **Less Effective for Short Patterns**: Overhead is high for short patterns. - -### Boyer-Moore Algorithm (Java Implementation): - -```java -class BoyerMoore { - public static int boyerMooreSearch(String text, String pattern) { - int[] last = new int[256]; - Arrays.fill(last, -1); - for (int i = 0; i < pattern.length(); i++) { - last[pattern.charAt(i)] = i; - } - - int n = text.length(); - int m = pattern.length(); - int s = 0; - - while (s <= n - m) { - int j = m - 1; - while (j >= 0 && pattern.charAt(j) == text.charAt(s + j)) { - j--; - } - if (j < 0) { - return s; - } else { - s += Math.max(1, j - last[text.charAt(s + j)]); - } - } - return -1; // Pattern not found - } -} -``` -### Applications of Boyer-Moore: -Text Editors: Searching for patterns in documents. -DNA Sequencing: Efficiently matches DNA sequences. -Intrusion Detection: Finds malicious patterns in network traffic. -### Summary: -The Boyer-Moore algorithm is a high-performance string-matching algorithm that uses heuristics to skip non-matching segments, making it efficient for long strings and complex searches. diff --git a/docs/algorithms/Searching Algorithms/Breadth-First-Search-(BFS)-Algo.md b/docs/algorithms/Searching Algorithms/Breadth-First-Search-(BFS)-Algo.md deleted file mode 100644 index f7e52b474..000000000 --- a/docs/algorithms/Searching Algorithms/Breadth-First-Search-(BFS)-Algo.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: bfs-algo -sidebar_position: 6 -title: Breadth-First Search -sidebar_label: BFS ---- - -### Definition: - -**Breadth-First Search (BFS)** is a graph traversal algorithm used to explore all vertices and edges of a graph. It starts from an initial node and explores all of its neighbours at the present depth before moving on to nodes at the next depth level. BFS is commonly used to find the shortest path in unweighted graphs, level-order traversal in trees, and solve puzzles like the shortest path in a maze. - -### Characteristics: - -- **Queue-Based Traversal:** - BFS uses a queue data structure to keep track of nodes that need to be explored next. - -- **Level-Order Exploration:** - BFS explores nodes in layers, first visiting all nodes at the current depth level before moving deeper. - -- **Complete Exploration:** - BFS continues to search until all the nodes of the graph are visited. - -### How BFS Works: - -1. **Start at a node** (root or any node). -2. **Mark the node as visited** and enqueue it. -3. **Dequeue a node** from the front of the queue and explore its unvisited neighbours. -4. **Mark each neighbor as visited** and enqueue them. -5. **Repeat** the process until the queue is empty. - -### Time Complexity: - -- **Time Complexity**: $O(V + E)$ - Where `V` is the number of vertices and `E` is the number of edges in the graph. - -### Space Complexity: - -- **Space Complexity**: $O(V)$ - BFS uses space proportional to the number of vertices due to the queue and visited list. - -### Advantages of BFS: - -- **Finds Shortest Path**: - BFS guarantees the shortest path in an unweighted graph. - -- **Systematic Exploration**: - BFS explores each level of the graph before moving to the next, ensuring that all nodes at the same level are visited. - -- **Ideal for Connected Components**: - BFS can be used to find connected components in a graph. - -### Disadvantages of BFS: - -- **Memory Intensive**: - BFS can consume more memory than depth-first search (DFS) due to storing all nodes at the current level. - -- **Not Optimal for Deep Solutions**: - BFS may take longer to reach deeper nodes if they are far from the starting point. - -### Breadth-First Search Algorithm (Java Implementation): - -```java -import java.util.*; - -class Graph { - private int numVertices; - private LinkedList adjList[]; - - // Constructor - Graph(int v) { - numVertices = v; - adjList = new LinkedList[v]; - for (int i = 0; i < v; ++i) - adjList[i] = new LinkedList(); - } - - // Add an edge to the graph - void addEdge(int v, int w) { - adjList[v].add(w); // Add w to v's list. - } - - // BFS traversal of the vertices reachable from v - void BFS(int s) { - // Mark all the vertices as not visited - boolean visited[] = new boolean[numVertices]; - - // Create a queue for BFS - LinkedList queue = new LinkedList<>(); - - // Mark the current node as visited and enqueue it - visited[s] = true; - queue.add(s); - - while (queue.size() != 0) { - // Dequeue a vertex from queue and print it - s = queue.poll(); - System.out.print(s + " "); - - // Get all adjacent vertices of the dequeued vertex - // If an adjacent vertex has not been visited, mark it visited and enqueue it - for (int neighbor : adjList[s]) { - if (!visited[neighbor]) { - visited[neighbor] = true; - queue.add(neighbor); - } - } - } - } - - public static void main(String args[]) { - Graph g = new Graph(4); - - g.addEdge(0, 1); - g.addEdge(0, 2); - g.addEdge(1, 2); - g.addEdge(2, 0); - g.addEdge(2, 3); - g.addEdge(3, 3); - - System.out.println("Following is Breadth First Traversal (starting from vertex 2):"); - - g.BFS(2); // Perform BFS starting from vertex 2 - } -} -``` - -### Applications of BFS: -- Shortest Path Finding: -BFS is used to find the shortest path in unweighted graphs. - -- Level-Order Traversal: -BFS is ideal for performing level-order traversal in trees. - -- Web Crawlers: -BFS can be used in web crawling to explore web pages in a breadth-wise manner. - -- Connected Components: -BFS helps identify connected components in undirected graphs. - -### Summary: -BFS is a fundamental algorithm for graph traversal and plays a crucial role in various applications like shortest path finding and level-order traversal. Its systematic approach ensures that all nodes at the current level are explored before moving deeper, making it invaluable for many graph-related diff --git a/docs/algorithms/Searching Algorithms/ComparisonSearch.md b/docs/algorithms/Searching Algorithms/ComparisonSearch.md deleted file mode 100644 index 4064bddc7..000000000 --- a/docs/algorithms/Searching Algorithms/ComparisonSearch.md +++ /dev/null @@ -1,218 +0,0 @@ ---- - -id: comparison-search-algo -sidebar_position: 3 -title: Comparison Search -sidebar_label: Comparison Search - ---- - -### Definition: - -A **comparison search** algorithm is one that relies on comparing elements to determine their order and find the target value in a dataset. These algorithms compare two elements to decide which one is larger, smaller, or equal. The most commonly known comparison search algorithms include **linear search**, **binary search**, and **ternary search**. - -### Characteristics: - -- **Element Comparison**: - - These algorithms use pairwise comparison to progressively narrow down the location of the target element or check every element. - -- **Applicable to Both Sorted and Unsorted Data**: - - Some comparison search algorithms (like linear search) can work on unsorted data, while others (like binary search) require sorted data for efficiency. - -- **Versatile**: - - Comparison-based search algorithms can be adapted to a wide range of data structures, including arrays, linked lists, trees, and more. - -### Types of Comparison Search Algorithms: - -#### 1. **Linear Search**: - - **Definition**: Linear search is a basic comparison search that checks each element one by one until the target is found or the array is exhausted. - - **Time Complexity**: $O(n)$ for both best, worst, and average cases. - - **When to Use**: Linear search is used for unsorted datasets or small arrays where other algorithms are not worth the overhead. - -#### 2. **Binary Search**: - - **Definition**: Binary search is a divide-and-conquer algorithm that works on sorted data. It repeatedly divides the search space in half and compares the middle element with the target. - - **Time Complexity**: $O(log n)$ in the average and worst case. - - **When to Use**: Best suited for large, sorted arrays or data structures with random access like arrays. - -#### 3. **Ternary Search**: - - **Definition**: Ternary search is similar to binary search but divides the array into three parts instead of two. It checks two midpoints in each iteration. - - **Time Complexity**: $O(log3 n)$, which is still logarithmic but often slower than binary search in practice due to the additional comparisons. - - **When to Use**: Useful in unimodal functions where there's a single peak, making ternary search more applicable. - -### Time Complexity of Comparison-Based Searches: - -- **Linear Search: $O(n)$** - Linear search scans through each element until the target is found. Its time complexity grows linearly with the input size, making it inefficient for large datasets. - -- **Binary Search: $O(log n)$** - Binary search reduces the search space by half in every iteration, leading to logarithmic time complexity. This makes it extremely efficient for large, sorted datasets. - -- **Ternary Search: $O(log3 n)$** - Ternary search divides the search space into three parts, but the extra comparisons in each iteration make it slower in practice compared to binary search. The time complexity is logarithmic, but the constant factors are higher. - -### Space Complexity: - -- **Linear Search: $O(1)$** - Linear search operates in constant space since it does not require any additional data structures. - -- **Binary Search: $O(1)$ (iterative), $O(log n)$ (recursive)** - The iterative version of binary search has a space complexity of $O(1)$, while the recursive version requires additional space for stack frames, leading to $O(log n)$ space complexity. - -- **Ternary Search: $O(1)$ (iterative), $O(log n)$ (recursive)** - Similar to binary search, the iterative ternary search uses constant space, while the recursive version requires logarithmic space due to recursive calls. - -### Applications of Comparison-Based Search Algorithms: - -- **Finding an Element in an Array**: - - All comparison-based searches can be used to find a target element in an array. The choice of algorithm depends on whether the array is sorted or not and the size of the dataset. - -- **Efficient Searching in Large Data**: - - Binary and ternary search are useful in large datasets, where a linear search would take too long. Binary search, in particular, is optimal when the data is already sorted. - -- **Searching in Data Structures**: - - Comparison searches are used in different data structures, including binary search trees, heaps, and linked lists. For example, binary search is a core operation in binary search trees. - -### C++ Implementations: - -**Linear Search** -```cpp -#include -using namespace std; - -int linearSearch(int arr[], int size, int target) { - for (int i = 0; i < size; i++) { - if (arr[i] == target) { - return i; // Return the index of the target element - } - } - return -1; // Return -1 if the target is not found -} - -int main() { - int arr[] = {2, 3, 4, 10, 40}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 10; - - int result = linearSearch(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -**Binary Search** -```cpp -#include -using namespace std; - -int binarySearch(int arr[], int size, int target) { - int low = 0; - int high = size - 1; - - while (low <= high) { - int mid = low + (high - low) / 2; - - if (arr[mid] == target) { - return mid; - } else if (arr[mid] < target) { - low = mid + 1; - } else { - high = mid - 1; - } - } - - return -1; -} - -int main() { - int arr[] = {2, 3, 4, 10, 40}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 10; - - int result = binarySearch(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -**Ternary Search** -```cpp -#include -using namespace std; - -int ternarySearch(int arr[], int low, int high, int target) { - if (high >= low) { - int mid1 = low + (high - low) / 3; - int mid2 = high - (high - low) / 3; - - if (arr[mid1] == target) { - return mid1; - } else if (arr[mid2] == target) { - return mid2; - } - - if (target < arr[mid1]) { - return ternarySearch(arr, low, mid1 - 1, target); - } else if (target > arr[mid2]) { - return ternarySearch(arr, mid2 + 1, high, target); - } else { - return ternarySearch(arr, mid1 + 1, mid2 - 1, target); - } - } - - return -1; -} - -int main() { - int arr[] = {2, 3, 4, 10, 40}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 10; - - int result = ternarySearch(arr, 0, size - 1, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -### Advantages and Disadvantages: - -#### Advantages: -- **Efficiency**: - - Binary and ternary search are significantly faster than linear search for large datasets, providing logarithmic time complexity. - -- **Versatility**: - - These algorithms can be applied to various data structures and can be modified to perform different tasks like finding ranges, first/last occurrences, or upper/lower bounds. - -- **Widely Applicable**: - - Comparison-based searches can be adapted for different types of data, including integers, strings, and custom objects. - -#### Disadvantages: -- **Requires Sorted Data**: - - Binary and ternary search only work efficiently on sorted data. Sorting an array can take additional time $(O(n log n))$ if the data is not already sorted. - -- **Overhead in Ternary Search**: - - Ternary search performs more comparisons than binary search and is rarely faster in practice. The overhead makes binary search more optimal in most scenarios. - -- **Not Suitable for Non-Random Access Structures**: - - These algorithms are best suited for arrays and data structures with direct indexing capabilities. They are inefficient in data structures like linked lists, where accessing the middle element requires traversal. - -### Summary: - -Comparison search algorithms are fundamental to searching tasks in computer science. Linear search is a simple yet inefficient option, while binary and ternary search provide logarithmic performance for sorted data. Binary search is the most widely used comparison-based search due to its balance of simplicity and efficiency, making it optimal for large datasets. Ternary search is a less common variation but can be useful in specialized scenarios. Overall, comparison-based searches play a critical role in fast data retrieval, particularly in ordered datasets. diff --git a/docs/algorithms/Searching Algorithms/Depth-First-Search-(DFS)-Algo.md b/docs/algorithms/Searching Algorithms/Depth-First-Search-(DFS)-Algo.md deleted file mode 100644 index 7be9ae9fa..000000000 --- a/docs/algorithms/Searching Algorithms/Depth-First-Search-(DFS)-Algo.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -id: dfs-algo -sidebar_position: 7 -title: Depth-First Search -sidebar_label: DFS ---- - -### Definition: - -**Depth-First Search (DFS)** is a graph traversal algorithm used to explore all vertices and edges of a graph. It starts from an initial node and explores as far as possible along each branch before backtracking. DFS is commonly used to solve problems like detecting cycles, solving mazes, and connectivity in graphs. - -### Characteristics: - -- **Stack-Based Traversal:** - DFS relies on an implicit or explicit stack data structure. When implemented recursively, the system call stack is used to keep track of the visited nodes. - -- **Backtracking:** - DFS explores all nodes along a path until it can’t go further, then backtracks to explore other unvisited nodes. - -- **Complete Exploration:** - DFS continues to search until all the nodes of the graph are visited. - -### Types of DFS: - -1. **Recursive DFS:** - A depth-first traversal using recursive function calls to visit each node. - -2. **Iterative DFS:** - Uses an explicit stack to simulate the recursive function, achieving the same result without recursion. - -### How DFS Works: - -1. **Start at a node** (root or any node). -2. **Mark the node as visited**. -3. **Explore each neighbor** of the node in depth-first fashion. -4. **Backtrack** when no further neighbors are found. -5. **Repeat** the process for other nodes if necessary. - -### Time Complexity: - -- **Time Complexity**: $O(V + E)$ - Where `V` is the number of vertices and `E` is the number of edges in the graph. - -### Space Complexity: - -- **Space Complexity**: $O(V)$ - DFS uses space proportional to the number of vertices due to the recursion stack or explicit stack. - -### Advantages of DFS: - -- **Memory-Efficient**: - DFS typically requires less memory than breadth-first search (BFS) since it doesn’t need to store all levels of the tree simultaneously. - -- **Finds Deeper Solutions**: - DFS is better suited for problems where the solution is deep in the graph. - -- **Backtracking**: - DFS is great for backtracking problems, such as solving puzzles and finding paths in mazes. - -### Disadvantages of DFS: - -- **Not Always Optimal**: - DFS does not guarantee finding the shortest path in an unweighted graph. - -- **May Get Stuck in Infinite Loops**: - Without proper handling (e.g., cycle detection), DFS can revisit nodes and lead to infinite recursion in graphs with cycles. - -### Depth-First Search Algorithm (Java Implementation): - -```java -import java.util.*; - -class Graph { - private int numVertices; - private LinkedList adjList[]; - - // Constructor - Graph(int v) { - numVertices = v; - adjList = new LinkedList[v]; - for (int i = 0; i < v; ++i) - adjList[i] = new LinkedList(); - } - - // Add an edge to the graph - void addEdge(int v, int w) { - adjList[v].add(w); // Add w to v's list. - } - - // DFS recursive function - void DFSUtil(int v, boolean visited[]) { - // Mark the current node as visited and print it - visited[v] = true; - System.out.print(v + " "); - - // Recur for all the vertices adjacent to this vertex - for (int neighbor : adjList[v]) { - if (!visited[neighbor]) - DFSUtil(neighbor, visited); - } - } - - // DFS traversal of the vertices reachable from v - void DFS(int v) { - // Mark all the vertices as not visited - boolean visited[] = new boolean[numVertices]; - - // Call the recursive helper function to print DFS traversal - DFSUtil(v, visited); - } - - public static void main(String args[]) { - Graph g = new Graph(4); - - g.addEdge(0, 1); - g.addEdge(0, 2); - g.addEdge(1, 2); - g.addEdge(2, 0); - g.addEdge(2, 3); - g.addEdge(3, 3); - - System.out.println("Following is Depth First Traversal (starting from vertex 2):"); - - g.DFS(2); // Perform DFS starting from vertex 2 - } -} -``` - -### Applications of DFS: -- Topological Sorting: -DFS is used in topological sorting of directed acyclic graphs (DAGs). - -- Cycle Detection: -DFS can detect cycles in both directed and undirected graphs. - -- Solving Mazes and Puzzles: -DFS can explore all possible paths and backtrack to find solutions. - -- Pathfinding and Connectivity: -DFS helps in finding paths and checking connectivity in graphs. - -### Summary: -DFS is an essential algorithm for graph traversal and problem-solving in various domains. Its memory efficiency, ability to find deep solutions, and use in applications like topological sorting and cycle detection make it valuable. While it may not always find the shortest path, it provides an efficient approach to exploring graph structures in depth-first order. diff --git a/docs/algorithms/Searching Algorithms/DigitalSearch.md b/docs/algorithms/Searching Algorithms/DigitalSearch.md deleted file mode 100644 index 8d332e01d..000000000 --- a/docs/algorithms/Searching Algorithms/DigitalSearch.md +++ /dev/null @@ -1,235 +0,0 @@ ---- - -id: digital-search-algo -sidebar_position: 4 -title: Digital Search -sidebar_label: Digital Search - ---- - -### Definition: - -A **digital search** algorithm is one that operates on the individual digits or characters of keys (rather than comparing whole elements like in comparison-based search). These algorithms are often used for searching in **digital data** structures like tries (prefix trees), radix trees, and hash tables. They work by processing elements based on their internal representation (such as binary digits or characters), making them efficient for specific types of data, particularly strings or fixed-length numeric data. - -### Characteristics: - -- **Digit-by-Digit Search**: - - Instead of comparing entire elements, digital search algorithms examine individual digits (or bits) of the data, processing one digit at a time to progressively refine the search space. - -- **Fast Access for Strings and Numbers**: - - Digital search algorithms excel in scenarios where keys have a known structure, such as strings, binary numbers, or fixed-length identifiers. - -- **Efficient Use of Prefixes**: - - In structures like tries, digital search algorithms are especially efficient when searching for keys with common prefixes, as they share computations. - -- **Non-Comparison-Based**: - - Unlike binary or linear search, digital search algorithms don’t rely on direct comparison between two elements. Instead, they navigate through nodes or tables based on the structure of the data (e.g., characters in a string or digits in a number). - -### Types of Digital Search Algorithms: - -#### 1. **Trie Search**: - - **Definition**: A trie (pronounced "try") is a tree-like data structure used for storing strings where each node represents a character. Searching in a trie involves traversing the tree, character by character. - - **Time Complexity**: $O(m)$ where *m* is the length of the key being searched. This is independent of the number of keys stored in the trie, making it fast for fixed-length keys. - - **Applications**: Used in applications like auto-completion, dictionary search, and IP routing tables. - -#### 2. **Radix Search**: - - **Definition**: Radix search uses the idea of processing keys digit by digit from the most significant digit to the least significant one. It can be implemented using a **radix tree** or **radix sort**. - - **Time Complexity**: $O(k)$ for searching, where *k* is the number of digits or characters in the key. - - **Applications**: Useful in scenarios like sorting strings or numbers with fixed lengths. - -#### 3. **Hashing**: - - **Definition**: Hashing is a form of digital search that uses a **hash function** to transform the search key into an index within a hash table. Searching involves hashing the key and accessing the corresponding bucket. - - **Time Complexity**: $O(1)$ for average-case search (constant time), though $O(n)$ in the worst case when hash collisions occur. - - **Applications**: Widely used in databases, caches, and associative arrays. - -### Time Complexity of Digital Search Algorithms: - -- **Trie Search: $O(m)$** - Searching for a string in a trie has linear time complexity relative to the length of the key, but it is independent of the number of stored keys. - -- **Radix Search: $O(k)$** - In radix search, the complexity depends on the number of digits or characters processed, but it is often much faster than comparison-based searches for long or fixed-length keys. - -- **Hashing: $O(1)$** - Hashing provides constant time search on average, although the worst-case complexity can degrade to O(n) if many keys hash to the same index (collisions). - -### Space Complexity: - -- **Trie Search: $O(m * n)$** - Tries can consume significant memory because each node represents a single character or digit, and the space grows with the number of keys (n) and the length of keys (m). - -- **Radix Search: $O(n)$** - The space complexity of radix search depends on the number of keys stored, with the size of the tree or table growing proportionally to the input. - -- **Hashing: $O(n)$** - Hash tables require space proportional to the number of stored elements, although the space may also include additional memory to handle collisions. - -### Applications of Digital Search Algorithms: - -- **Auto-Completion and Text Search**: - - Digital search algorithms like tries are used in auto-completion systems, where partial strings need to be searched quickly. These algorithms are also used in spell-checkers and text-based search engines. - -- **Network Routing**: - - Digital search structures such as tries are heavily used in networking, specifically for IP routing, where prefixes of IP addresses need to be matched efficiently. - -- **Databases and Hash Tables**: - - Hash-based search is a critical part of databases and caches, allowing fast retrieval of records using unique keys. It's commonly used for indexing in database systems. - -- **Sorting and Searching Large Keys**: - - Radix-based searches are often used for searching or sorting large datasets with long or fixed-length keys, such as phone numbers, social security numbers, or credit card numbers. - -### C++ Implementations: - -**Trie Search** -```cpp -#include -#include -using namespace std; - -// Trie node definition -class TrieNode { -public: - unordered_map children; - bool isEndOfWord; - - TrieNode() { - isEndOfWord = false; - } -}; - -// Trie class definition -class Trie { -private: - TrieNode* root; - -public: - Trie() { - root = new TrieNode(); - } - - // Insert a word into the trie - void insert(string word) { - TrieNode* current = root; - for (char c : word) { - if (!current->children[c]) { - current->children[c] = new TrieNode(); - } - current = current->children[c]; - } - current->isEndOfWord = true; - } - - // Search for a word in the trie - bool search(string word) { - TrieNode* current = root; - for (char c : word) { - if (!current->children[c]) { - return false; - } - current = current->children[c]; - } - return current->isEndOfWord; - } -}; - -int main() { - Trie trie; - trie.insert("hello"); - trie.insert("world"); - - cout << "Search result for 'hello': " << trie.search("hello") << endl; - cout << "Search result for 'world': " << trie.search("world") << endl; - cout << "Search result for 'hell': " << trie.search("hell") << endl; - - return 0; -} -``` - -**Radix Search** -```cpp -#include -using namespace std; - -int getMax(int arr[], int n) { - int max = arr[0]; - for (int i = 1; i < n; i++) { - if (arr[i] > max) { - max = arr[i]; - } - } - return max; -} - -void countingSort(int arr[], int n, int exp) { - int output[n]; - int count[10] = {0}; - - for (int i = 0; i < n; i++) { - count[(arr[i] / exp) % 10]++; - } - - for (int i = 1; i < 10; i++) { - count[i] += count[i - 1]; - } - - for (int i = n - 1; i >= 0; i--) { - output[count[(arr[i] / exp) % 10] - 1] = arr[i]; - count[(arr[i] / exp) % 10]--; - } - - for (int i = 0; i < n; i++) { - arr[i] = output[i]; - } -} - -void radixSort(int arr[], int n) { - int max = getMax(arr, n); - - for (int exp = 1; max / exp > 0; exp *= 10) { - countingSort(arr, n, exp); - } -} - -int main() { - int arr[] = {170, 45, 75, 90, 802, 24, 2, 66}; - int n = sizeof(arr) / sizeof(arr[0]); - - radixSort(arr, n); - - cout << "Sorted array: \n"; - for (int i = 0; i < n; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Advantages and Disadvantages: - -#### Advantages: -- **Fast for Fixed-Length Keys**: - - Digital search algorithms, such as radix and trie-based searches, can outperform traditional comparison-based algorithms for fixed-length or structured data. - -- **Prefix-Based Searches**: - - Tries are ideal for prefix-based searches, such as finding all words that start with a given prefix. - -- **$O(1)$ Lookup with Hashing**: - - Hash tables provide constant-time lookup for unique keys, making them one of the fastest search mechanisms. - -#### Disadvantages: -- **High Memory Usage**: - - Tries, in particular, can consume a lot of memory as each node may need to store multiple child pointers, leading to a higher space overhead compared to other search algorithms. - -- **Collisions in Hashing**: - - Hashing can degrade to $O(n)$ time complexity in the worst case due to collisions. While collisions can be mitigated by using good hash functions, they can still pose a challenge in practice. - -- **Complexity in Implementation**: - - Implementing digital search structures like tries and radix - - trees can be more complex than simpler comparison-based searches like binary or linear search. - -### Summary: - -Digital search algorithms provide highly efficient methods for searching structured data, especially when working with strings, fixed-length keys, or large datasets. Trie-based searches excel in prefix-based search operations, while radix and hash-based searches offer fast retrieval for large amounts of data. Although these algorithms can consume more memory and may be more complex to implement, their speed and scalability make them essential tools in modern computing applications such as networking, databases, and text search engines. diff --git a/docs/algorithms/Searching Algorithms/ExponentialSerach.md b/docs/algorithms/Searching Algorithms/ExponentialSerach.md deleted file mode 100644 index f881d5c7b..000000000 --- a/docs/algorithms/Searching Algorithms/ExponentialSerach.md +++ /dev/null @@ -1,112 +0,0 @@ ---- - -id: exponential-search-algo -sidebar_position: 4 -title: Exponential Search -sidebar_label: Exponential Search - ---- - -### Definition: - -Exponential search is an algorithm that searches for a target element in a **sorted array**. It combines **binary search** with exponential growth to quickly identify a range where the target element may exist and then applies binary search within that range. - -### Characteristics: - -- **Exponentially Grows Search Range**: - - Exponential search starts by checking the first element, then elements at exponentially increasing indices (1, 2, 4, 8, …) until it exceeds the target. - -- **Binary Search in Identified Range**: - - Once the range is identified, a binary search is applied within that range to find the target element. - -### Time Complexity: - -- **Best Case: $O(1)$** - If the target element is at the first position, it is found in constant time. - -- **Average and Worst Case: $O(log n)$** - The exponential growth phase takes $O(log i)$, where `i` is the position where the range is identified. The binary search within the range also takes $O(log i)$. - -### Space Complexity: - -- **Iterative: $O(1)$** - The iterative approach requires only a few variables for managing indices. - -### C++ Implementation: - -```cpp -#include -#include -using namespace std; - -int binarySearch(int arr[], int low, int high, int target) { - while (low <= high) { - int mid = low + (high - low) / 2; - - if (arr[mid] == target) return mid; - else if (arr[mid] < target) low = mid + 1; - else high = mid - 1; - } - return -1; -} - -int exponentialSearch(int arr[], int size, int target) { - if (arr[0] == target) return 0; - - int i = 1; - while (i < size && arr[i] <= target) { - i *= 2; - } - - return binarySearch(arr, i / 2, min(i, size - 1), target); -} - -int main() { - int arr[] = {3, 5, 7, 9, 10, 14, 18, 21, 25}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 14; - - int result = exponentialSearch(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -## Use Cases: - -- **Searching in Infinite Lists**: - - Exponential search is particularly useful when dealing with data that can grow indefinitely or when the length of the dataset is not known beforehand. - -- **Dynamic Datasets**: - - It can be applied in scenarios where data is continuously added, allowing efficient searches even in dynamic datasets. - -## Advantages and Disadvantages: - -### Advantages: -- **Works with Unbounded Arrays**: - - The ability to search in unbounded or infinite arrays makes exponential search a unique tool in specific applications. - -- **Combines Best of Both Worlds**: - - By leveraging both exponential and binary search, it effectively narrows down search space while maintaining efficiency. - -### Disadvantages: -- **Requires Sorted Data**: - - Like binary search, exponential search requires the data to be sorted, limiting its application in unsorted datasets. - -- **Overhead in Range Determination**: - - The initial phase of finding the range can introduce additional overhead compared to direct binary search in known datasets. - -## Optimizations and Applications: - -- **Faster Range Detection**: - - Exponential search can improve the efficiency of finding the target in large datasets by quickly locating the range, making it suitable for various search problems. - -## Summary: - -Exponential search is a specialized search algorithm that efficiently locates an element in infinite or unbounded datasets by first establishing a range and then applying binary search. Its unique design makes it suitable for dynamic datasets where the length is not known, while still maintaining the requirement for sorted data. diff --git a/docs/algorithms/Searching Algorithms/FibbonaciSearch.md b/docs/algorithms/Searching Algorithms/FibbonaciSearch.md deleted file mode 100644 index 8f30e50dd..000000000 --- a/docs/algorithms/Searching Algorithms/FibbonaciSearch.md +++ /dev/null @@ -1,198 +0,0 @@ ---- - -id: fibonacci-search-algo -sidebar_position: 5 -title: Fibonacci Search -sidebar_label: Fibonacci Search - ---- - -### Definition: - -**Fibonacci Search** is a search algorithm that uses the Fibonacci sequence to divide the search space into progressively smaller sections. This method is typically applied to search in **sorted arrays** and can be seen as a variation of binary search but with Fibonacci numbers guiding the search process. The algorithm reduces the search space in steps defined by Fibonacci numbers rather than splitting in half as in binary search. - -### Characteristics: - -- **Fibonacci Division**: - - The search space is divided based on Fibonacci numbers, making it useful for optimization in certain cases where the size of the dataset is fixed. - -- **Works on Sorted Arrays**: - - Fibonacci search is specifically designed for sorted arrays, similar to binary search, but offers potential optimizations when the data distribution or hardware access favors Fibonacci-based divisions. - -- **Non-Recursive**: - - Fibonacci search operates iteratively and does not require recursion, making it more memory-efficient for certain applications. - -### How Fibonacci Search Works: - -1. **Initialize** the Fibonacci numbers and compare the element at the Fibonacci index with the target. -2. **Reduce the search range** by eliminating sections of the array based on Fibonacci steps. -3. Continue comparing and narrowing the search space until the target element is found or the search space is exhausted. - -### Time Complexity of Fibonacci Search: - -- **Time Complexity**: $O(\log n)$ - Like binary search, Fibonacci search operates in logarithmic time. However, the divisions occur at positions determined by Fibonacci numbers, which may lead to fewer comparisons in certain scenarios. - -### Space Complexity: - -- **Space Complexity**: $O(1)$ - Fibonacci search requires only a few variables to keep track of the Fibonacci numbers and the current index, leading to constant space complexity. - -### Advantages of Fibonacci Search: - -- **Efficient for Specific Data Sizes**: - - Fibonacci search can be faster than binary search in cases where the data structure size aligns with Fibonacci numbers, providing optimized search steps. - -- **Minimizes Comparisons**: - - In some cases, Fibonacci search may require fewer comparisons than binary search due to the way the search space is divided. - -- **Iterative Implementation**: - - Fibonacci search is non-recursive, which can be beneficial in environments where recursion is expensive or limited by stack size. - -### Disadvantages of Fibonacci Search: - -- **Requires Sorted Arrays**: - - Fibonacci search, like binary search, is only applicable to sorted arrays. - -- **Slower in Random Access**: - - It may not outperform binary search when random access to elements is possible, as binary search divides the array in equal halves, which is often more efficient for arbitrary data sizes. - -### Fibonacci Search Algorithm (C++ Implementation): - -```cpp -#include -using namespace std; - -// Fibonacci Search Function -int fibonacciSearch(int arr[], int x, int n) { - int fibMMm2 = 0; // (m-2)'th Fibonacci number - int fibMMm1 = 1; // (m-1)'th Fibonacci number - int fibM = fibMMm2 + fibMMm1; // m'th Fibonacci number - - while (fibM < n) { - fibMMm2 = fibMMm1; - fibMMm1 = fibM; - fibM = fibMMm2 + fibMMm1; - } - - int offset = -1; - - while (fibM > 1) { - int i = min(offset + fibMMm2, n - 1); - - if (arr[i] < x) { - fibM = fibMMm1; - fibMMm1 = fibMMm2; - fibMMm2 = fibM - fibMMm1; - offset = i; - } else if (arr[i] > x) { - fibM = fibMMm2; - fibMMm1 -= fibMMm2; - fibMMm2 = fibM - fibMMm1; - } else { - return i; - } - } - - if (fibMMm1 && arr[offset + 1] == x) { - return offset + 1; - } - - return -1; -} - -int main() { - int arr[] = {10, 22, 35, 40, 45, 50, 80, 82, 85, 90, 100}; - int n = sizeof(arr) / sizeof(arr[0]); - int x = 85; - - int result = fibonacciSearch(arr, x, n); - if (result != -1) { - cout << "Found at index: " << result << endl; - } else { - cout << "Not found." << endl; - } - - return 0; -} -``` - -**Recursive Approach** - -```cpp -#include -using namespace std; - -// Recursive Fibonacci Search Function -int fibonacciSearchRecursive(int arr[], int x, int fibMMm2, int fibMMm1, int offset, int n) { - // Base case: If the Fibonacci number is 1 - if (fibMMm1 == 1) { - if (offset + 1 < n && arr[offset + 1] == x) - return offset + 1; - else - return -1; - } - - // Find the index using fibMMm2 - int i = min(offset + fibMMm2, n - 1); - - // If x is greater than the value at index i, cut the subarray from offset to i - if (arr[i] < x) { - return fibonacciSearchRecursive(arr, x, fibMMm1 - fibMMm2, fibMMm2, i, n); - } - // If x is less than the value at index i, cut the subarray after i+1 - else if (arr[i] > x) { - return fibonacciSearchRecursive(arr, x, fibMMm2, fibMMm1 - fibMMm2, offset, n); - } - // If element is found, return the index - else { - return i; - } -} - -// Fibonacci Search Wrapper Function -int fibonacciSearch(int arr[], int x, int n) { - // Initialize Fibonacci numbers - int fibMMm2 = 0; // (m-2)'th Fibonacci number - int fibMMm1 = 1; // (m-1)'th Fibonacci number - int fibM = fibMMm2 + fibMMm1; // m'th Fibonacci number - - // Generate the smallest Fibonacci number greater than or equal to n - while (fibM < n) { - fibMMm2 = fibMMm1; - fibMMm1 = fibM; - fibM = fibMMm2 + fibMMm1; - } - - // Start recursive search - return fibonacciSearchRecursive(arr, x, fibMMm2, fibMMm1, -1, n); -} - -int main() { - int arr[] = {10, 22, 35, 40, 45, 50, 80, 82, 85, 90, 100}; - int n = sizeof(arr) / sizeof(arr[0]); - int x = 85; - - int result = fibonacciSearch(arr, x, n); - if (result != -1) { - cout << "Found at index: " << result << endl; - } else { - cout << "Not found." << endl; - } - - return 0; -} -``` - -### Applications of Fibonacci Search: - -- **Search in Sorted Arrays:** - - Used for efficient searching in large datasets where minimizing the number of comparisons is critical. - -- **Hardware Optimized Searches:** - - In certain hardware implementations, Fibonacci search may offer optimizations over binary search, especially in systems where division operations are expensive. - -### Summary: - - -Fibonacci Search is a powerful search algorithm with logarithmic time complexity, making it suitable for large, sorted datasets. While it shares similarities with binary search, its use of Fibonacci numbers for dividing the search space can provide optimizations in specific scenarios. Its iterative nature and constant space complexity make it an attractive option for environments where recursion or memory usage is a concern. diff --git a/docs/algorithms/Searching Algorithms/HashingSearch.md b/docs/algorithms/Searching Algorithms/HashingSearch.md deleted file mode 100644 index a9e11fafe..000000000 --- a/docs/algorithms/Searching Algorithms/HashingSearch.md +++ /dev/null @@ -1,161 +0,0 @@ ---- - -id: hashing-search-algo -sidebar_position: 5 -title: Hashing Search -sidebar_label: Hashing Search - ---- - -### Definition: - -**Hashing search** is an algorithm that uses a **hash function** to map keys to specific indices in a hash table. This allows for efficient data retrieval based on the hash value of the key. When searching for a value, the algorithm computes the hash of the key, which directly points to the location in the hash table, enabling average-case constant time complexity for search operations. - -### Characteristics: - -- **Direct Addressing**: - - Hashing provides a way to access data directly via its computed hash value, allowing for fast retrieval without the need for searching through other elements. - -- **Hash Function**: - - A hash function transforms the input key into an integer index within the bounds of the hash table. The choice of a good hash function is crucial for maintaining performance and minimizing collisions. - -- **Collision Handling**: - - When two keys hash to the same index (a collision), the algorithm must implement a strategy to resolve it. Common methods include chaining (linking entries at the same index) and open addressing (finding another open slot). - -- **Dynamic Resizing**: - - Hash tables often resize when they reach a certain load factor to maintain efficient performance, typically doubling the size of the table and rehashing existing keys. - -### Time Complexity: - -- **Best Case: $O(1)$** - In the best-case scenario, where there are no collisions, searching for a key takes constant time. - -- **Average Case: $O(1)$** - With a well-designed hash function and a reasonable load factor, the average time complexity for search operations remains constant. - -- **Worst Case: $O(n)$** - In the worst-case scenario, if all keys hash to the same index (e.g., poor hash function), the search may degrade to linear time complexity as it has to traverse through all entries in that bucket. - -### Space Complexity: - -- **Space Complexity: $O(n)$** - The space required is proportional to the number of keys stored, plus additional space for handling collisions, depending on the chosen collision resolution method. - -### Hash Functions: - -- **Division Method**: - - A simple and common hash function that takes the key and divides it by a prime number, returning the remainder as the index. - -- **Multiplication Method**: - - This method multiplies the key by a constant and extracts the fractional part to produce an index. This can help in evenly distributing keys across the table. - -- **Universal Hashing**: - - A family of hash functions designed to minimize collisions by randomly selecting a hash function from a set, making it difficult for adversaries to cause performance degradation. - -### Collision Resolution Techniques: - -1. **Chaining**: - - Each index in the hash table points to a linked list of entries that hash to the same index. When a collision occurs, the new entry is simply added to the list. - - **Example:** - ```cpp - struct Node { - int key; - int value; - Node* next; - }; - ``` - -2. **Open Addressing**: - - When a collision occurs, the algorithm searches for the next available slot in the hash table. Techniques include linear probing, quadratic probing, and double hashing. - -### C++ Implementation: - -Here’s a simple implementation of a hashing search using separate chaining for collision resolution: - -```cpp -#include -#include -#include -using namespace std; - -class HashTable { -private: - vector>> table; - int size; - -public: - HashTable(int s) : size(s) { - table.resize(size); - } - - int hashFunction(int key) { - return key % size; // Simple modulo hash function - } - - void insert(int key, string value) { - int index = hashFunction(key); - table[index].emplace_back(key, value); // Add key-value pair to the list - } - - string search(int key) { - int index = hashFunction(key); - for (const auto& pair : table[index]) { - if (pair.first == key) { - return pair.second; // Return the value if key matches - } - } - return "Not Found"; // Key not found - } -}; - -int main() { - HashTable hashTable(10); - hashTable.insert(1, "One"); - hashTable.insert(2, "Two"); - hashTable.insert(11, "Eleven"); // Collision with key 1 - - cout << "Value for key 1: " << hashTable.search(1) << endl; - cout << "Value for key 11: " << hashTable.search(11) << endl; - cout << "Value for key 5: " << hashTable.search(5) << endl; - - return 0; -} -``` - -### Applications of Hashing Search: - -- **Databases**: - - Hashing is extensively used in databases for indexing to allow fast retrieval of records based on unique keys. - -- **Caches**: - - Caches use hashing to store frequently accessed data for quick retrieval, reducing latency in data access. - -- **Symbol Tables**: - - In programming language compilers and interpreters, hashing is used for symbol tables to manage variable names and scope. - -- **Distributed Systems**: - - Hashing helps in partitioning data across distributed databases and servers to balance load and optimize access times. - -### Advantages and Disadvantages: - -#### Advantages: -- **Fast Lookups**: - - Hashing provides average-case constant time complexity for searches, making it very efficient for large datasets. - -- **Simple Implementation**: - - Hash tables are relatively easy to implement and manage, especially with modern programming languages providing built-in support. - -#### Disadvantages: -- **Collisions**: - - The presence of collisions can degrade performance, and managing them can add complexity to the implementation. - -- **Memory Usage**: - - Hash tables may require more memory than other data structures due to the need for additional space to handle collisions and maintain load factors. - -- **Poor Hash Function**: - - A poorly chosen hash function can lead to many collisions, resulting in performance issues similar to linear search. - -### Summary: - -Hashing search is a powerful technique for efficient data retrieval, particularly suited for situations where rapid access to a large amount of data is required. By using hash functions to map keys to specific indices, hashing allows for average-case constant time complexity in search operations. While hashing provides significant advantages in terms of speed and simplicity, careful consideration must be given to hash function design and collision resolution strategies to ensure optimal performance. Hashing plays a crucial role in various applications, including databases, caching systems, and programming language interpreters, making it an essential concept in computer science and software engineering. diff --git a/docs/algorithms/Searching Algorithms/Interpolation-search-algorithm.md b/docs/algorithms/Searching Algorithms/Interpolation-search-algorithm.md deleted file mode 100644 index 9d479216d..000000000 --- a/docs/algorithms/Searching Algorithms/Interpolation-search-algorithm.md +++ /dev/null @@ -1,120 +0,0 @@ ---- - -id: Interpolation algorithm -sidebar_position: 5 -title: Interpolation search -sidebar_label: Interpolation search algorithm - ---- - - -## Definition 📖 - -**Interpolation search** is a search algorithm that improves upon binary search by estimating the position of a target value within a sorted array. This estimation is based on the values at the start and end of the search range, assuming the data is uniformly distributed. Interpolation search calculates an approximate position for the target element, which helps in reducing the number of comparisons in sorted arrays. - -## Characteristics ✨ - -- **Estimation Based Search**: - - Unlike binary search, which splits the array in half, interpolation search attempts to guess the position of the target value based on its value relative to the range boundaries. - -- **Efficient in Uniformly Distributed Data**: - - Interpolation search works best when the elements in the array are uniformly distributed. The performance degrades if the distribution is uneven. - -- **Adaptive Positioning**: - - It calculates the position based on the formula: - ``` - pos = low + ((target - array[low]) * (high - low) / (array[high] - array[low])) - ``` - where `low` and `high` are the bounds of the search range. - -## Time Complexity ⏱️ - -- **Best Case: `O(1)`** 🌟 - - In the best-case scenario, the estimated position is exactly where the target element is located, leading to a constant time complexity. - -- **Average Case: `O(log log n)`** 🔄 - - For uniformly distributed data, interpolation search is generally faster than binary search, providing a sub-logarithmic time complexity. - -- **Worst Case: `O(n)`** 💥 - - In the worst case (e.g., non-uniform distribution), interpolation search may perform poorly and degrade to linear search. - -## Space Complexity 💾 - -- **Space Complexity: `O(1)`** - Interpolation search operates in constant space, as it only requires a few extra variables for the calculations. - -## C++ Implementation 💻 - -Here’s a simple implementation of interpolation search in C++: - -```cpp -#include -#include -using namespace std; - -int interpolationSearch(const vector& arr, int target) { - int low = 0; - int high = arr.size() - 1; - - while (low <= high && target >= arr[low] && target <= arr[high]) { - // Estimating the position - int pos = low + ((target - arr[low]) * (high - low) / (arr[high] - arr[low])); - - // Target found - if (arr[pos] == target) - return pos; - - // Adjust search range - if (arr[pos] < target) - low = pos + 1; - else - high = pos - 1; - } - return -1; // Target not found -} - -int main() { - vector arr = {10, 20, 30, 40, 50, 60, 70, 80, 90}; - int target = 40; - - int index = interpolationSearch(arr, target); - - if (index != -1) - cout << "Element found at index " << index << endl; - else - cout << "Element not found" << endl; - - return 0; -} -``` -## Applications of Interpolation Search 🌐 - - **Databases:** -- Often used for searching in large databases with sorted numeric keys, where the data is close to uniformly distributed. - -**Address Lookup:** -- Useful in address-based data searches where entries are nearly uniform, such as postal codes or phone numbers. - -**Search Engines:** -- Search engines might employ interpolation-like techniques for indexing and searching, especially when data distribution is predictable. - -## Advantages and Disadvantages -**Advantages:** ✅ -- Faster Than Binary Search in Uniform Data: - - When data is uniformly distributed, interpolation search can perform better than binary search, achieving a time complexity of `𝑂(log log 𝑛)`. -- Low Memory Requirement: - - It requires only constant space, which makes it efficient in terms of memory usage. - -**Disadvantages:** ⚠️ -- Requires Sorted and Uniformly Distributed Data: - - Interpolation search is inefficient for unsorted data and can degrade to `𝑂(𝑛)` for uneven distributions. -- Complexity in Non-Uniform Data: - - If the data is not uniformly distributed, interpolation search may perform poorly compared to binary search. - -## Summary 📚 -Interpolation search is a specialized search technique that provides fast search times in uniformly distributed sorted arrays by estimating the likely position of the target element. -While it offers significant speed advantages for specific data distributions, it is less versatile than binary search, particularly in cases of non-uniform data. -Interpolation search is applied in fields such as databases, address lookups, and search engines where data tends to be evenly distributed. diff --git a/docs/algorithms/Searching Algorithms/InterpolationSearch.md b/docs/algorithms/Searching Algorithms/InterpolationSearch.md deleted file mode 100644 index 808bebf3a..000000000 --- a/docs/algorithms/Searching Algorithms/InterpolationSearch.md +++ /dev/null @@ -1,193 +0,0 @@ ---- -id: interpolation-search-algo -sidebar_position: 6 -title: Interpolation Search -sidebar_label: Interpolation Search ---- - -Interpolation search is an optimized variant of binary search that works based on proportionality. It estimates the position of the target value in a sorted array by comparing the value of the target to the array's boundary values. This makes it particularly effective for uniformly distributed datasets. - -### Key Characteristics - -- **Proportional Positioning**: - Interpolation search calculates the estimated position of the target using a formula that takes into account the values at the low and high indices, as well as the target value. - -- **Ideal for Uniformly Distributed Data**: - The algorithm performs best when data is uniformly distributed, as the predicted position will closely match the target's actual location. - -- **Works on Sorted Arrays**: - Like binary search, interpolation search requires the array to be sorted for efficient searching. - -- **Memory Efficiency**: - The algorithm operates in constant space, requiring no additional memory beyond the input array. - -- **Stable Search**: - It preserves the relative order of equal elements during the search process. - -### Time Complexity - -- **Best Case: $O(1)$** - In the best scenario, the target is found in the estimated position after one comparison. - -- **Average Case: $O(log log n)$** - For uniformly distributed data, interpolation search can achieve a time complexity of $O(log log n)$, making it faster than binary search. - -- **Worst Case: $O(n)$** - For non-uniformly distributed data, the algorithm’s performance may degrade to $O(n)$, similar to linear search. - -### Space Complexity - -- **Iterative Approach: $O(1)$** - The iterative version only needs constant space for the `low`, `high`, and `pos` variables. - -### When to Use Interpolation Search - -- **Uniformly Distributed Data**: - Best suited for datasets where the values are uniformly spread. It efficiently leverages the data distribution to predict the target's position. - -- **Large Sorted Data**: - Particularly effective for large, sorted datasets, as it significantly reduces comparisons by jumping to the estimated target location. - -- **Performance-Critical Applications**: - When performance is critical, and the data is large and uniformly distributed, interpolation search offers improvements over linear or binary search. - -- **Numeric Data**: - Works best with numeric data where the distribution is known or can be approximated. It's less effective for irregularly distributed or non-numeric data. - -### C++ Implementation - -**Iterative Approach**: - -```cpp -#include -using namespace std; - -int interpolationSearch(int arr[], int size, int target) { - int low = 0, high = size - 1; - - while (low <= high && target >= arr[low] && target <= arr[high]) { - if (low == high) { - if (arr[low] == target) return low; - return -1; - } - - int pos = low + (((double)(high - low) / (arr[high] - arr[low])) * (target - arr[low])); - - if (arr[pos] == target) { - return pos; - } - - if (arr[pos] < target) { - low = pos + 1; - } else { - high = pos - 1; - } - } - return -1; -} - -int main() { - int arr[] = {10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 18; - - int result = interpolationSearch(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -**Recursive Approach**: - -```cpp -#include -using namespace std; - -int interpolationSearchRecursive(int arr[], int low, int high, int target) { - if (low <= high && target >= arr[low] && target <= arr[high]) { - if (low == high) { - if (arr[low] == target) return low; - return -1; - } - - int pos = low + (((double)(high - low) / (arr[high] - arr[low])) * (target - arr[low])); - - if (arr[pos] == target) { - return pos; - } - - if (arr[pos] < target) { - return interpolationSearchRecursive(arr, pos + 1, high, target); - } else { - return interpolationSearchRecursive(arr, low, pos - 1, target); - } - } - return -1; -} - -int main() { - int arr[] = {10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 18; - - int result = interpolationSearchRecursive(arr, 0, size - 1, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -### Use Cases - -- **Efficient Search in Uniformly Distributed Data**: - Commonly used for large datasets like databases where efficient lookups in uniformly distributed data are needed. - -- **Searching in Static Data**: - Works well in scenarios where the data doesn’t change often, making it suitable for read-heavy applications. - -### Advantages and Disadvantages - -**Advantages**: - -- **Efficient for Uniform Data**: - Minimizes comparisons for uniformly distributed arrays, making it highly efficient for such datasets. - -- **Log-Logarithmic Time Complexity**: - Its $O(log log n)$ time complexity offers a significant speed boost over binary search in ideal conditions. - -- **Memory Efficiency**: - The algorithm operates with constant space, $O(1)$, making it memory efficient. - -**Disadvantages**: - -- **Requires Uniform Distribution**: - Limited to uniformly distributed datasets, making it ineffective for irregular or unpredictable data. - -- **Less Efficient for Small Datasets**: - The overhead of calculating positions makes it less efficient than simpler search algorithms for smaller datasets. - -- **Not Suitable for Linked Lists**: - The algorithm requires random access to elements, so it's not usable with linked lists or other sequential data structures. - -### Optimizations and Applications - -- **Hybrid Search Algorithms**: - Combining interpolation search with other search techniques (e.g., binary search) can enhance performance in non-uniformly distributed datasets. - -- **Exponential Search**: - For arrays of unknown or infinite size, interpolation search can be combined with exponential search to first narrow down the range of the target element. - -### Summary - -Interpolation search is a powerful algorithm for searching large, uniformly distributed, sorted datasets. With an average time complexity of $O(log log n)$, it outperforms binary search in ideal conditions. While it’s best suited for numeric, static datasets with uniform distribution, interpolation search remains an essential tool in the realm of efficient search algorithms. diff --git a/docs/algorithms/Searching Algorithms/JumpSearch.md b/docs/algorithms/Searching Algorithms/JumpSearch.md deleted file mode 100644 index 2d878b478..000000000 --- a/docs/algorithms/Searching Algorithms/JumpSearch.md +++ /dev/null @@ -1,106 +0,0 @@ ---- - -id: jump-search-algo -sidebar_position: 5 -title: Jump Search -sidebar_label: Jump Search - ---- - -### Definition: - -Jump search is a **search algorithm** for **sorted arrays**. It works by jumping ahead by a fixed number of steps (block size) and then performing a linear search within the identified block where the target element may reside. - -### Characteristics: - -- **Fixed Block Size**: - - The array is divided into blocks, and the algorithm jumps by the block size. The block size is typically chosen as the square root of the array size for optimal performance. - -- **Linear Search in Identified Block**: - - Once the target block is identified, a linear search is performed within that block. - -### Time Complexity: - -- **Best Case: $O(1)$** - If the target element is at the start of the array or the block. - -- **Average and Worst Case: $O(\sqrt{n})$** - The optimal block size for jump search is $\sqrt{n}$, making its time complexity $O(\sqrt{n})$. - -### Space Complexity: - -- **Iterative: $O(1)$** - Jump search uses a constant amount of space for the variables that store block indices. - -### C++ Implementation: - -```cpp -#include -#include -using namespace std; - -int jumpSearch(int arr[], int size, int target) { - int step = sqrt(size); // Step size - int prev = 0; - - while (arr[min(step, size) - 1] < target) { - prev = step; - step += sqrt(size); - if (prev >= size) return -1; - } - - for (int i = prev; i < min(step, size); i++) { - if (arr[i] == target) return i; - } - - return -1; // Target not found -} - -int main() { - int arr[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 11; - - int result = jumpSearch(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` -## Use Cases: - -- **Searching in Large Sorted Lists**: - - Jump search is efficient for searching in large sorted arrays, especially when the size of the array is known in advance. - -- **Improving Search Performance**: - - It can be applied in scenarios where comparisons are costly, improving overall search performance. - -## Advantages and Disadvantages: - -### Advantages: -- **Reduced Comparisons**: - - By skipping blocks, jump search reduces the number of comparisons needed compared to linear search. - -- **Optimal for Specific Scenarios**: - - It provides a balance between linear and binary search, making it useful for large datasets with a predictable size. - -### Disadvantages: -- **Not as Fast as Binary Search**: - - With a time complexity of O(√n), jump search is generally slower than binary search’s O(log n) performance for large datasets. - -- **Requires Sorted Data**: - - Jump search is only applicable to sorted arrays, limiting its use in unsorted datasets. - -## Optimizations and Applications: - -- **Block Size Selection**: - - Optimizing the block size used for jumping can enhance the performance of jump search, making it more adaptable to different datasets. - -## Summary: - -Jump search is an efficient algorithm for searching in large, sorted arrays by combining the benefits of linear and binary search. It operates in O(√n) time complexity, making it a viable alternative for specific scenarios where the size of the dataset is known, and comparisons are costly. While it does not outperform binary search in terms of speed, its unique approach provides a useful tool in certain applications. diff --git a/docs/algorithms/Searching Algorithms/LinearSearch.md b/docs/algorithms/Searching Algorithms/LinearSearch.md deleted file mode 100644 index 5fe08c754..000000000 --- a/docs/algorithms/Searching Algorithms/LinearSearch.md +++ /dev/null @@ -1,226 +0,0 @@ ---- - -id: linear-search-algo -sidebar_position: 1 -title: Linear Search -sidebar_label: Linear Search - ---- - -### Definition: - -Linear search, also known as sequential search, is the simplest searching algorithm. It checks every element in the array (or list) one by one until the target element is found or the entire array has been searched. The algorithm doesn't assume any particular order in the data and is useful for small or unsorted datasets. - -### Characteristics: - -- **Sequential Search**: - - The algorithm traverses the array one element at a time, comparing each element with the target value. - -- **Unordered Data**: - - Linear search works on any dataset, whether sorted or unsorted, making it a versatile search method. - -- **Simplicity**: - - Linear search is one of the easiest search algorithms to understand and implement. It requires no preprocessing or complex data structures. - -- **Inefficient for Large Data**: - - The algorithm is inefficient for large datasets because it potentially searches through every element, making it slow in comparison to more advanced search techniques. - -- **Works with All Data Types**: - - Linear search can be applied to any data type that supports comparison, making it universally applicable. - -### Time Complexity: - -- **Best Case: $O(1)$** - In the best case, the target element is found at the very beginning of the array, requiring only a single comparison. - -- **Average Case: $O(n)$** - On average, the algorithm must search through half of the elements in the array before finding the target. - -- **Worst Case: $O(n)$** - In the worst case, the target element is located at the end of the array, or it may not be present at all, requiring a full traversal of the array. - -### Space Complexity: - -- **Space Complexity: $O(1)$** - Linear search requires a constant amount of additional memory, regardless of the size of the array, making it a space-efficient algorithm. - -### When to Use Linear Search: - -- **Unsorted or Small Data**: - - Linear search is ideal for small or unsorted datasets where more complex algorithms may not offer significant performance improvements. - -- **Checking Every Element**: - - It is useful when every element needs to be checked regardless of whether the data is sorted or not, such as searching for a specific condition. - -- **Data in Linked Lists**: - - Linear search works well with linked lists, where random access is not possible and each element must be checked sequentially. - -### C++ and Python Implementation: - -**Iterative Approach** -```cpp -#include -using namespace std; - -int linearSearchIterative(int arr[], int size, int target) { - for (int i = 0; i < size; i++) { - if (arr[i] == target) { - return i; // Return index if target is found - } - } - return -1; // Return -1 if target is not found -} - -int main() { - int arr[] = {10, 23, 45, 70, 11, 15}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 70; - - int result = linearSearchIterative(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` -```python -def linearSearchIterative(array, size, target): - for i in range(len(array)): - if array[i] == target: - return i #Return index if target is found - return -1 #Return -1 if target is not found -def main(): - array = [1 ,2 ,5 ,3 ,7 ,9 ,4 ,1 ,9 ,6 ] - size = len(array) - target = 9 - result = linearSearchIterative(array,size,target) - if result != -1: - print("Element found at index",result) - else: - print("Element not found ") - -if __name__ == "__main__": - main() - ``` - - -**Recursive Approach** -```cpp -#include -using namespace std; - -int linearSearchRecursive(int arr[], int size, int target) { - if (size == 0) { - return -1; // Return -1 if the array is empty - } - if (arr[size - 1] == target) { - return size - 1; // Return index if target is found - } - return linearSearchRecursive(arr, size - 1, target); // Recur for the rest of the array -} - -int main() { - int arr[] = {10, 23, 45, 70, 11, 15}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 70; - - int result = linearSearchRecursive(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` -```python -def linear_search_recursive(arr, size, target): - if size == 0: - return -1 # Return -1 if the array is empty - if arr[size - 1] == target: - return size - 1 # Return index if target is found - return linear_search_recursive(arr, size - 1, target) # Recur for the rest of the array - -def main(): - arr = [10, 23, 45, 70, 11, 15] - size = len(arr) - target = 70 - - result = linear_search_recursive(arr, size, target) - - if result != -1: - print("Element found at index", result) - else: - print("Element not found") - -if __name__ == "__main__": - main() -``` - -### Use Cases: - -- **Looking for a Specific Value**: - - Linear search is often used when you want to find the index of a specific value in an array or list, especially when the dataset is small or unsorted. - -- **Finding a Minimum or Maximum**: - - Linear search can also be used to find the minimum or maximum value in an unsorted array by comparing each element with the current minimum or maximum as you traverse the list. - -- **Linked Lists**: - - Since linked lists don't allow random access to elements, linear search is the go-to search method for finding values in a linked list structure. - -### Advantages and Disadvantages: - -#### Advantages: -- **Simplicity**: - - Easy to implement and understand, making it ideal for quick searches in small datasets or educational purposes. - -- **No Preprocessing**: - - Linear search doesn't require any preprocessing like sorting or indexing, making it applicable to any kind of data. - -- **Universal Application**: - - Works with any data type that supports comparison, whether it's numbers, strings, or complex objects. - -#### Disadvantages: -- **Slow for Large Datasets**: - - Linear search is inefficient for large datasets, as it has to examine each element until it finds the target. - -- **No Optimization**: - - It doesn't take advantage of the structure of the data, such as order or indexing, which could be exploited by more advanced algorithms like binary search. - -- **Not Ideal for Sorted Data**: - - If the data is sorted, more efficient algorithms like binary search should be used instead of linear search. - -### Optimization: - -- **Sentinel Search**: - - A slight variation of linear search called the **sentinel search** can be used to reduce the number of comparisons. By placing the target element at the end of the array as a "sentinel," the search loop can eliminate the need to check if the array is fully traversed in each iteration. - -```cpp -int sentinelSearch(int arr[], int size, int target) { - int last = arr[size - 1]; // Store the last element - arr[size - 1] = target; // Set sentinel - - int i = 0; - while (arr[i] != target) { - i++; - } - - arr[size - 1] = last; // Restore the last element - - if (i < size - 1 || arr[size - 1] == target) { - return i; - } else { - return -1; - } -} -``` - -### Summary: - -Linear search is the most basic and straightforward search algorithm, making it suitable for small or unsorted datasets. Its simplicity is its greatest strength, but its inefficiency for larger datasets is a major drawback. While it's not the most optimal choice for sorted or large data, it remains an essential algorithm for scenarios where simplicity or sequential checking is required. Though linear search has a time complexity of O(n), it can be implemented with constant space, making it useful for memory-constrained environments. diff --git a/docs/algorithms/Searching Algorithms/Meta-binary-search.md b/docs/algorithms/Searching Algorithms/Meta-binary-search.md deleted file mode 100644 index 40d3b65e0..000000000 --- a/docs/algorithms/Searching Algorithms/Meta-binary-search.md +++ /dev/null @@ -1,292 +0,0 @@ ---- - -id: Meta-binary-search-algo -sidebar_position: 1 -title: Meta binary search -sidebar_label: Meta binary search ---- - -### Definition: - -Meta Binary Search is an optimized version of the traditional binary search that uses bitwise operations to reduce the number of comparisons required to find an element in a sorted array. Instead of calculating the middle index using arithmetic, meta binary search directly manipulates the bits of the search range to divide it into halves more efficiently. This allows it to perform the search with fewer arithmetic operations, leveraging the speed of bitwise shifts to determine the next search interval. - -### Characteristics: - -- **Bitwise Operations:**: - - Meta Binary Search uses bitwise shifts instead of traditional arithmetic operations (like division by 2) to calculate the middle index in the search space. This makes the search faster, especially in low-level programming, by reducing the number of CPU instructions required. - -- **Efficient Halving:**: - - Similar to binary search, it continuously halves the search range, but by leveraging the power of bitwise manipulation, it eliminates the need for expensive arithmetic operations like division. - -- **Recursive or Iterative:**: - - Meta binary search can be implemented both recursively or iteratively, just like binary search, making it flexible in terms of implementation. - - -- **Sorted Data Requirement:**: - - Meta binary search, like traditional binary search, requires the array or dataset to be sorted before searching for the target element. - -- **Logarithmic Time Complexity:**: - - The time complexity remains (logn), similar to the traditional binary search. However, due to the use of bitwise operations, the constant factors involved in execution time might be slightly reduced. - -- **Lower-level Optimization:**: -- It is often used in system-level applications or cases where performance optimization is crucial. It provides a slight optimization over binary search by minimizing overhead from division operations. - -### Time Complexity: - -- **Best Case: $O(1)$** - Scenario: The best case occurs when the target element is found at the middle index on the very first comparison. -Complexity: Only one comparison is needed in this case, so the time complexity is O(1). - -- **Average Case: $O(logn)$** - Scenario: On average, we have to halve the search space multiple times until the target is found. -Complexity: Since we reduce the search space by half after each iteration, the number of iterations required is logarithmic in the size of the input, leading to O(logn). - - -- **Worst Case: $O(logn)$** - Scenario: The worst case happens when the target element is either not present in the array or is found at one of the last comparisons (e.g., at the last position). -Complexity: Similar to binary search, the worst case would require halving the search space until a single element remains, resulting in O(logn). - -### Space Complexity: - -- **Space Complexity: $O(1)$** - Iterative Meta Binary Search requires a constant amount of additional memory, regardless of the size of the array, making it a space-efficient algorithm. and Recursive Meta Binary Search it O(logn). - -### When to Use Linear Search: - -- **Bitwise Operations**: - - Use it when the data or problem can benefit from bitwise manipulation, especially when dealing with integer ranges or binary-like structures. - -- **Optimization**: - - It helps optimize binary search when the range of values is large, but the exact value we're searching for can be extracted efficiently using bitwise comparisons. - -```cpp -// C++ implementation of the optimized approach - -#include -#include -#include -#include - -using namespace std; - -// Function to implement optimized Meta Binary Search -int optimizedMetaBinarySearch(const vector& A, int key_to_search) { - int n = static_cast(A.size()); - - // Edge case: if the array is empty - if (n == 0) return -1; - - // Set number of bits to represent the largest array index - int lg = log2(n - 1) + 1; - int pos = 0; - - // Main loop for searching the key - for (int i = lg; i >= 0; i--) { - if (A[pos] == key_to_search) { - return pos; // Key found - } - - // Construct new position - int new_pos = pos | (1 << i); - // Check bounds and values - if (new_pos < n && A[new_pos] <= key_to_search) { - pos = new_pos; // Move to the new position - } - } - - // Final check if the key is at the current position - return (A[pos] == key_to_search) ? pos : -1; -} - -// Function to test the optimized Meta Binary Search -int main() { - vector A = {-2, 10, 100, 250, 32315}; // Example sorted array - - int key = 10; // Key to search - int result = optimizedMetaBinarySearch(A, key); - - if (result != -1) { - cout << "Element found at index: " << result << endl; - } else { - cout << "Element not found." << endl; - } - - return 0; -} - -``` -- **Integer-based Problems**: - - Works well in problems where you're dealing with integer values or ranges, like finding specific values within a range. - -### C++ Implementation: - -**Iterative Approach** -```cpp -#include -using namespace std; - -int linearSearchIterative(int arr[], int size, int target) { - for (int i = 0; i < size; i++) { - if (arr[i] == target) { - return i; // Return index if target is found - } - } - return -1; // Return -1 if target is not found -} - -int main() { - int arr[] = {10, 23, 45, 70, 11, 15}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 70; - - int result = linearSearchIterative(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -**Recursive Approach** -```cpp -#include -using namespace std; - -int linearSearchRecursive(int arr[], int size, int target) { - if (size == 0) { - return -1; // Return -1 if the array is empty - } - if (arr[size - 1] == target) { - return size - 1; // Return index if target is found - } - return linearSearchRecursive(arr, size - 1, target); // Recur for the rest of the array -} - -int main() { - int arr[] = {10, 23, 45, 70, 11, 15}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 70; - - int result = linearSearchRecursive(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -### Use Cases: - -- **Performance-Critical Systems:**: - - When efficiency is crucial, especially in embedded systems or real-time applications where every bit counts. -Bitwise operations can outperform traditional arithmetic operations in these scenarios. - -- **Finding a Minimum or Maximum**: - - Linear search can also be used to find the minimum or maximum value in an unsorted array by comparing each element with the current minimum or maximum as you traverse the list. - -- **Fixed-Size Arrays**: - - deal when working with fixed-size arrays where index positions can be efficiently represented in a bitwise manner. -Useful in memory-constrained environments like low-level hardware systems. - -- **Sorted Data with Large Ranges**: - - Searching over a large range of sorted data, especially where binary manipulations can simplify computations. -Could be used in game development, graphics, or systems dealing with large-scale integer ranges. - -### Advantages and Disadvantages: - -#### Advantages: -- **Simplicity**: - - Easy to implement and understand, making it ideal for quick searches in small datasets or educational purposes. - -- **No Preprocessing**: - - Meta binaray search doesn't require any preprocessing like sorting or indexing, making it applicable to any kind of data. - -- **Universal Application**: - - Works with any data type that supports comparison, whether it's numbers, strings, or complex objects. - -#### Disadvantages: -- **Not always faster**: - - Meta binary search is inefficient for large datasets. - -- **Limited Applicability**: - - Specific Use Cases: Not suitable for all types of data structures or search requirements. It is best applied to sorted arrays or specific conditions where bitwise indexing makes sense. -Less Intuitive: For developers unfamiliar with bitwise operations, the method may seem less intuitive compared to standard binary search. - -- **Not Ideal for Sorted Data**: - - If the data is sorted, more efficient algorithms like binary search should be used instead of linear search. - -### Optimization: - -- **Avoid Redundant Calculations**: - - Index Calculation: Optimize index calculations by minimizing unnecessary bitwise operations. Cache previously calculated positions to avoid recalculating them multiple times. - -```cpp -// C++ implementation of above approach - -#include -#include -#include -#include - -using namespace std; - -// Function to implement optimized Meta Binary Search -int optimizedMetaBinarySearch(const vector& A, int key_to_search) { - int n = static_cast(A.size()); - - // Edge case: if the array is empty - if (n == 0) return -1; - - // Set number of bits to represent the largest array index - int lg = log2(n - 1) + 1; - int pos = 0; - - // Main loop for searching the key - for (int i = lg; i >= 0; i--) { - if (A[pos] == key_to_search) { - return pos; // Key found - } - - // Construct new position - int new_pos = pos | (1 << i); - // Check bounds and values - if (new_pos < n && A[new_pos] <= key_to_search) { - pos = new_pos; // Move to the new position - } - } - - // Final check if the key is at the current position - return (A[pos] == key_to_search) ? pos : -1; -} - -// Function to test the optimized Meta Binary Search -int main() { - vector A = {-2, 10, 100, 250, 32315}; // Example sorted array - - int key = 10; // Key to search - int result = optimizedMetaBinarySearch(A, key); - - if (result != -1) { - cout << "Element found at index: " << result << endl; - } else { - cout << "Element not found." << endl; - } - - return 0; -} - - -``` - -### Summary: - -Meta Binary Search, also known as One-Sided Binary Search, is a variation of the binary search algorithm that is used to search an ordered list or array of elements. This algorithm is designed to reduce the number of comparisons needed to search the list for a given element. -The basic idea behind Meta Binary Search is to start with an initial interval of size n that includes the entire array. The algorithm then computes a middle element, as in binary search, and compares it to the target element. If the target element is found, the search terminates. If the middle element is greater than the target element, the algorithm sets the new interval to the left half of the previous interval, and if the middle element is less than the target element, the new interval is set to the right half of the previous interval. However, unlike binary search, Meta Binary Search does not perform a comparison for each iteration of the loop. diff --git a/docs/algorithms/Searching Algorithms/Rabin-Karp-Algorithm.md b/docs/algorithms/Searching Algorithms/Rabin-Karp-Algorithm.md deleted file mode 100644 index 8484701bb..000000000 --- a/docs/algorithms/Searching Algorithms/Rabin-Karp-Algorithm.md +++ /dev/null @@ -1,131 +0,0 @@ ---- - -id: Rabin-Karp-algorithm -sidebar_position: 5 -title: Rabin-Karp algorithm -sidebar_label: Rabin-Karp algorithm ---- -## Definition 📖 - -**Rabin-Karp algorithm** is a string-searching algorithm that utilizes hashing to find a pattern within a text. This algorithm is particularly efficient for finding multiple patterns within the same text by comparing hash values, reducing the need for repeated character comparisons. - -## Characteristics ✨ - -- **Hash-Based Search**: - - Rabin-Karp uses a hash function to convert a pattern and substrings of the text into hash values. It compares these hash values to identify matching patterns. - -- **Efficient for Multiple Patterns**: - - Ideal for cases with multiple patterns, as it can reuse the hash calculations, making it efficient in such scenarios. - -- **Rolling Hash**: - - Uses a rolling hash technique to quickly update the hash value for the next substring, enhancing efficiency for large texts. - -## Time Complexity ⏱️ - -- **Best Case: `O(n + m)`** 🌟 - - When there are no hash collisions, the algorithm efficiently processes both text and pattern in linear time. - -- **Average Case: `O(n + m)`** 🔄 - - Typically performs well with a low number of hash collisions, maintaining linear time complexity. - -- **Worst Case: `O(n * m)`** 💥 - - In cases with many hash collisions, the algorithm may degrade to checking each substring individually. - -## Space Complexity 💾 - -- **Space Complexity: `O(1)`** - Requires constant space for the hash values and other variables, making it memory-efficient. - -## C++ Implementation 💻 - -Here’s a simple implementation of the Rabin-Karp algorithm in C++: - -```cpp -#include -#include -using namespace std; - -const int d = 256; // Number of characters in the input alphabet -const int q = 101; // A prime number for modulo operation - -void rabinKarpSearch(string pattern, string text) { - int m = pattern.length(); - int n = text.length(); - int i, j; - int p = 0; // Hash value for pattern - int t = 0; // Hash value for text - int h = 1; - - // Calculate the hash value of the pattern and first window of text - for (i = 0; i < m - 1; i++) - h = (h * d) % q; - - for (i = 0; i < m; i++) { - p = (d * p + pattern[i]) % q; - t = (d * t + text[i]) % q; - } - - // Slide the pattern over text - for (i = 0; i <= n - m; i++) { - if (p == t) { // Check for hash match - for (j = 0; j < m; j++) { - if (text[i + j] != pattern[j]) - break; - } - if (j == m) - cout << "Pattern found at index " << i << endl; - } - - if (i < n - m) { - t = (d * (t - text[i] * h) + text[i + m]) % q; - if (t < 0) - t += q; - } - } -} - -int main() { - string text = "ABCCDABCDABCD"; - string pattern = "ABCD"; - rabinKarpSearch(pattern, text); - return 0; -} -``` -## Applications of Rabin-Karp Algorithm 🌐 -**Text Search Engines:** - - Widely used in text search applications where multiple patterns need to be matched, as it can efficiently handle repeated hash calculations. - -**Plagiarism Detection:** - - Helps in detecting plagiarism by checking for large sections of identical or similar text within documents. - -**DNA Sequence Analysis:** - - Useful for matching specific gene sequences by searching for patterns in large DNA strands. - -## Advantages and Disadvantages -**Advantages:** ✅ - - - **Efficient for Multiple Patterns:** - - Offers efficient handling of multiple patterns in a single pass. - - - **Low Memory Requirement:** - - Uses constant memory, as it doesn’t require additional space for each character. - -**Disadvantages:** ⚠️ - - - **Hash Collisions:** - - Performance can degrade in the presence of hash collisions, especially in repetitive or similar text. - - - **Not Ideal for Small Texts:** - - Other algorithms may be more efficient for shorter texts where the hash calculation overhead is less advantageous. - -## Summary 📚 - -The Rabin-Karp algorithm is an efficient, hash-based approach for pattern searching, especially suitable for finding multiple patterns in a large body of text. -It balances memory efficiency and speed in scenarios with minimal hash collisions, making it a preferred choice in applications like text searching and DNA analysis. diff --git a/docs/algorithms/Searching Algorithms/SentinelSearch.md b/docs/algorithms/Searching Algorithms/SentinelSearch.md deleted file mode 100644 index 3a636ece3..000000000 --- a/docs/algorithms/Searching Algorithms/SentinelSearch.md +++ /dev/null @@ -1,124 +0,0 @@ ---- - -id: sentinel-search-algo -sidebar_position: 3 -title: Sentinel Search -sidebar_label: Sentinel Search - ---- - -### Definition: - -**Sentinel search** is an optimization of linear search that improves the performance of searching for an element in an **unsorted array**. It does so by placing a sentinel (or marker) value at the end of the array, which helps to eliminate the need for checking whether the end of the array has been reached during the search process. This reduces the number of comparisons and enhances efficiency. - -### Characteristics: - -- **Linear Search Enhancement**: - - Sentinel search builds on the concept of linear search by introducing a sentinel value, effectively optimizing the search process for arrays. -- **Works on Unsorted Data**: - - Unlike binary search, sentinel search does not require the input data to be sorted, making it versatile for various applications. -- **Single Pass**: - - The sentinel search performs the search in a single pass through the array, leading to a simplified control structure and fewer checks. - -### Time Complexity: - -- **Best Case: $O(1)$** - In the best-case scenario, the target element is the first element in the array. -- **Average Case: $O(n)$** - On average, the sentinel search will require about half the comparisons as the target is equally likely to be anywhere in the array. -- **Worst Case: $O(n)$** - In the worst case, the target element is not present in the array, resulting in $n$ comparisons. - -### Space Complexity: - -- **$O(1)$** - The sentinel search requires a constant amount of additional space to store the sentinel value, making it space-efficient. - -### When to Use Sentinel Search: - -- **Unsorted Arrays**: - - Sentinel search is ideal for searching in unsorted datasets where the overhead of sorting would be too high. -- **Simplifying Search Logic**: - - It is beneficial when you want to simplify search logic and reduce the number of bounds checking during linear search. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -int sentinelSearch(int arr[], int size, int target) { - // Store the last element - int last = arr[size - 1]; - arr[size - 1] = target; // Set the sentinel - - int i = 0; - while (arr[i] != target) { - i++; - } - - // Restore the last element - arr[size - 1] = last; - - // Check if the target was found - if (i < size - 1 || arr[size - 1] == target) { - return i; // Target element found - } - - return -1; // Return -1 if target is not found -} - -int main() { - int arr[] = {5, 8, 1, 3, 7}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 3; - - int result = sentinelSearch(arr, size, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -### Variations of Sentinel Search: - -- **Search with Multiple Sentinels**: - - In cases with multiple sentinels or markers, variations can be made to speed up searches further, especially in specialized data structures. - -### Use Cases: - -- **Real-Time Applications**: - - Sentinel search can be applied in scenarios requiring quick searches in streaming data or real-time applications where data is continuously changing. - -- **Unsorted Data**: - - It is particularly useful for applications dealing with large volumes of unsorted data where efficiency in searching is paramount. - -### Advantages and Disadvantages: - -#### Advantages: -- **Fewer Comparisons**: - - The introduction of a sentinel reduces the number of comparisons needed, particularly in scenarios where the target is located near the beginning of the array. - -- **Simplicity**: - - The algorithm simplifies control structures, making the implementation straightforward and easy to understand. - -#### Disadvantages: -- **Not Suitable for Sorted Data**: - - While effective for unsorted arrays, it does not take advantage of sorted data, where algorithms like binary search would be more efficient. - -- **Space for Sentinel**: - - Requires the use of an additional variable for the sentinel, although this is a minor overhead. - -### Optimizations and Applications: - -- **Integration with Other Algorithms**: - - Sentinel search can be combined with other searching or sorting algorithms to enhance performance further, particularly when dealing with dynamically changing datasets. - -### Summary: - -Sentinel search is an optimized linear search technique that enhances efficiency by using a sentinel value at the end of the array. While it operates in O(n) time complexity in the average and worst cases, it simplifies the search process and reduces the number of comparisons needed. This makes sentinel search particularly effective for unsorted datasets, providing a practical solution for applications requiring fast and efficient searching. \ No newline at end of file diff --git a/docs/algorithms/Searching Algorithms/Sublist-Search.md b/docs/algorithms/Searching Algorithms/Sublist-Search.md deleted file mode 100644 index c793e7091..000000000 --- a/docs/algorithms/Searching Algorithms/Sublist-Search.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -id: sublist-search -sidebar_position: 3 -title: Sublist Search -sidebar_label: Sublist ---- - -### Definition: - -**Sublist Search** is a pattern-matching algorithm used to search for a sequence of nodes (sublist) within a larger list or sequence. It is particularly useful in text search, DNA sequence matching, and linked list matching. - -### Characteristics: - -- **Pattern Matching**: Searches for a smaller sequence in a larger sequence. -- **Sequential Traversal**: Typically traverses the larger list sequentially. -- **Efficient**: Designed to be optimized for quick matching with minimal backtracking. - -### How Sublist Search Works: - -1. **Initialize**: Start with the head of the larger list. -2. **Match Start**: Check each element of the main list against the first element of the sublist. -3. **Continue Matching**: For each matching start, check consecutive elements. -4. **Repeat**: Continue until the sublist is found or the main list is exhausted. - -### Time Complexity: - -- **Time Complexity**: \(O(n \times m)\) where `n` is the length of the main list and `m` is the length of the sublist. - -### Space Complexity: - -- **Space Complexity**: \(O(1)\) - -### Advantages of Sublist Search: - -- **Pattern Identification**: Effective in finding patterns within lists. -- **Space Efficient**: Operates with minimal additional space. - -### Disadvantages of Sublist Search: - -- **Linear Complexity**: Can be slow for large lists. -- **Limited to Sequential Matching**: Inefficient for complex search patterns. - -### Sublist Search Algorithm (Java Implementation): - -```java -class Node { - int data; - Node next; - - Node(int data) { - this.data = data; - this.next = null; - } -} - -class SublistSearch { - public static boolean isSublist(Node mainList, Node subList) { - Node ptr1 = mainList; - while (ptr1 != null) { - Node ptr2 = subList; - Node ptr3 = ptr1; - while (ptr2 != null && ptr3 != null && ptr2.data == ptr3.data) { - ptr2 = ptr2.next; - ptr3 = ptr3.next; - } - if (ptr2 == null) return true; - ptr1 = ptr1.next; - } - return false; - } -} -``` -### Applications of Sublist Search: -DNA Sequence Matching: Finds gene sequences in DNA. -Text Search: Locates patterns in text. -Linked List Operations: Detects sub-sequences in linked lists. -### Summary: -Sublist Search is an efficient pattern-matching algorithm widely used in string matching, DNA sequence analysis, and other pattern-based searches. diff --git a/docs/algorithms/Searching Algorithms/TernarySearch.md b/docs/algorithms/Searching Algorithms/TernarySearch.md deleted file mode 100644 index b0bda3421..000000000 --- a/docs/algorithms/Searching Algorithms/TernarySearch.md +++ /dev/null @@ -1,121 +0,0 @@ ---- - -id: ternary-search-algo -sidebar_position: 3 -title: Ternary Search -sidebar_label: Ternary Search - ---- - -### Definition: - -Ternary search is a **divide-and-conquer** algorithm similar to binary search, but instead of dividing the array into two halves, it divides it into three parts. The array is split by examining two midpoints, and the search continues in the section where the target value lies. Ternary search is particularly useful in unimodal functions (functions that increase then decrease). - -### Characteristics: - -- **Divides into Three Parts**: - - Ternary search compares the target with two midpoints to decide which of the three parts to search next. - -- **Unimodal Function**: - - In unimodal functions, ternary search is more effective as it narrows down the search space in logarithmic time. - -- **Works on Sorted Data**: - - Like binary search, ternary search requires the array to be sorted. - -### Time Complexity: - -- **Best Case: $O(1)$** - In the best case, the target element is found at one of the midpoints after just one comparison. - -- **Average and Worst Case: $O(log_3 n)$** - Since the array is divided into three parts, ternary search runs in logarithmic time, specifically $log_3 n$, where `n` is the number of elements. - -### Space Complexity: - -- **Iterative: $O(1)$** - The iterative version requires constant memory for storing low, mid1, mid2, and high indices. - -- **Recursive: $O(log_3 n)$** - In the recursive version, the space complexity is proportional to the recursion depth. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -int ternarySearch(int arr[], int low, int high, int target) { - if (high >= low) { - int mid1 = low + (high - low) / 3; - int mid2 = high - (high - low) / 3; - - if (arr[mid1] == target) { - return mid1; // Target found at mid1 - } - if (arr[mid2] == target) { - return mid2; // Target found at mid2 - } - - if (target < arr[mid1]) { - return ternarySearch(arr, low, mid1 - 1, target); // Search in the first third - } - else if (target > arr[mid2]) { - return ternarySearch(arr, mid2 + 1, high, target); // Search in the third third - } - else { - return ternarySearch(arr, mid1 + 1, mid2 - 1, target); // Search in the middle third - } - } - - return -1; // Target not found -} - -int main() { - int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - int size = sizeof(arr) / sizeof(arr[0]); - int target = 5; - - int result = ternarySearch(arr, 0, size - 1, target); - - if (result != -1) { - cout << "Element found at index " << result << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -## Use Cases: - -- **Optimization Problems**: - - Ternary search is particularly useful in optimization problems where a function is unimodal, helping to find optimal points efficiently. - -- **Advanced Data Structures**: - - It can be utilized in data structures that require finding minimum or maximum values, such as in certain algorithms related to graphs and networks. - -## Advantages and Disadvantages: - -### Advantages: -- **Useful for Unimodal Functions**: - - Ternary search excels in scenarios where the function being analyzed is unimodal, providing an effective way to find extrema. - -- **Reduced Search Space**: - - By dividing the search space into three parts, it can potentially provide a better estimate of where to find the target. - -### Disadvantages: -- **Less Efficient than Binary Search**: - - Ternary search has a time complexity of O(log3 n), which is generally slower than the O(log2 n) time complexity of binary search. - -- **Increased Comparisons**: - - Each iteration requires two comparisons instead of one, which can lead to higher overhead in some cases. - -## Optimizations and Applications: - -- **Enhanced Algorithm Efficiency**: - - While it may not outperform binary search in terms of time complexity, it can be applied in specific scenarios to improve algorithm efficiency, particularly in optimization tasks. - -## Summary: - -Ternary search is a valuable algorithm for searching in sorted datasets and finding extrema in unimodal functions. Although it has a higher overhead than binary search, its unique approach can be advantageous in certain optimization problems. Ternary search finds its niche in specific applications, especially where the characteristics of the data allow for a three-way split. diff --git a/docs/algorithms/Searching Algorithms/Uniform-Cost-Search.md b/docs/algorithms/Searching Algorithms/Uniform-Cost-Search.md deleted file mode 100644 index b31ecf6f2..000000000 --- a/docs/algorithms/Searching Algorithms/Uniform-Cost-Search.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -id: uniform-cost-search -sidebar_position: 4 -title: Uniform-Cost Search -sidebar_label: Uniform-Cost ---- - -### Definition: - -**Uniform-Cost Search (UCS)** is a search algorithm that expands the node with the lowest cost first, ensuring that it finds the least-cost path in weighted graphs. UCS is similar to Dijkstra's algorithm but is often applied in AI and pathfinding scenarios. - -### Characteristics: - -- **Lowest Cost Path**: Always expands the node with the lowest path cost. -- **Optimal**: Guarantees an optimal solution for paths with non-negative weights. -- **Uninformed**: Does not use heuristics and is a type of uninformed search. - -### How Uniform-Cost Search Works: - -1. **Initialize**: Start with the root node. -2. **Expand Node**: Choose the node with the lowest cumulative path cost. -3. **Add Neighbors**: Add unvisited neighbors with updated path costs. -4. **Repeat**: Continue until reaching the goal or emptying the priority queue. - -### Time Complexity: - -- **Time Complexity**: \(O(b^d)\) where `b` is the branching factor and `d` is the depth of the goal. - -### Space Complexity: - -- **Space Complexity**: \(O(b^d)\) - -### Advantages of Uniform-Cost Search: - -- **Optimal Path**: Finds the least-cost path for weighted graphs. -- **No Heuristic Needed**: Effective without heuristic guidance. - -### Disadvantages of Uniform-Cost Search: - -- **Inefficient for Large Graphs**: Can be slow for large search spaces. -- **High Memory Use**: Stores all frontier nodes in memory. - -### Uniform-Cost Search Algorithm (Java Implementation): - -```java -import java.util.*; - -class GraphNode { - int id, cost; - List neighbors; - - GraphNode(int id, int cost) { - this.id = id; - this.cost = cost; - neighbors = new ArrayList<>(); - } -} - -class UniformCostSearch { - public static int ucs(GraphNode start, GraphNode goal) { - PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(n -> n.cost)); - Set visited = new HashSet<>(); - pq.add(new GraphNode(start.id, 0)); - - while (!pq.isEmpty()) { - GraphNode current = pq.poll(); - if (current.id == goal.id) return current.cost; - visited.add(current); - - for (GraphNode neighbor : current.neighbors) { - if (!visited.contains(neighbor)) { - pq.add(new GraphNode(neighbor.id, current.cost + neighbor.cost)); - } - } - } - return -1; // Goal not reachable - } -} -``` -### Applications of Uniform-Cost Search: -Pathfinding in AI: Used for finding the shortest path in robotics. -Network Routing: Ensures the lowest cost route in weighted networks. -Resource Allocation: Finds optimal paths with resource constraints. -### Summary: -Uniform-Cost Search is optimal and complete for finding the lowest-cost path in weighted graphs, widely used in AI and networking. diff --git a/docs/algorithms/Two-Pointers/IntroductionToTwoPointers.png b/docs/algorithms/Two-Pointers/IntroductionToTwoPointers.png deleted file mode 100644 index 9e0b2e19b7b5d350ca734666f294a26a5791e8a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 357058 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 z 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

    u}Cpe}9#jiB%G}${N(P9iy{=~ex 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 z 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�S_7`gr`aO^k)@{@(cgQJYB3 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 oOE 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

    RyK8~n_!L5(j&<}#JcOA?qvP7!v$D^KF!5}e z_ZLmZWXZxWv}}0DQ4rz{RyHHPvt%GD76dDeNIS*R&U?_)jmGEpUZHM-}Sq< zbq|82bTJ`sg>gfUlQbG&SLWDX63l1LZNecxSpnhkhQ(}b5Iy{A;pq$N(Kv`nMB0vF zRaMD=#KtGK*{N-uEG4Q&qX)hU#(EPz)*%MD$=N+=CryQ% zekmJC-17>PyEe$WZ2X6O>9<=XYkS-#MVR-qq}(Dt5bZ{EJNvf`P~Gem6#%OGt66oU zDCCRJlG3;A8HCnmjg@|~5&&vPD*7?~b3|Ae<>b{sbXkRyi8B6*M>!?MMM(Ff3Ojd~ zknIXTxR_YfvVKN{EYA+2RbNEM&I1(VG5j2y_|t8xH`tqf3zsW1(ZHAzS&X0yZyI}- zW7Zu0ylKJ8gYy(sskTHsd?7Sm=m)@T@!#z|6_z?5pUp)xD$w`#tByhaV z`t1Q_2CjsSsx!=2nHMIL;~__p4O3(JRH>ii%u~z}Y5dZI; z1b6mrP=+tN!Hw*6iQ$WPolp0ZKG)_YF|{4|5xHx2>YpMGO6g<#cb|wLALyA+`L~>$ zL(v056CLx(=I0Sy)fR3{)Tm@C7nsjr+y)hV*g$_l`%rZx@EKzBO)u2)4wI=l-cSq> zHL)iWBBrF7pFV;6*iVE#REYjR*Tck6Ra6x0@?g;FIh^3$8!-L11(PvWw*R7ct{Y7v z|AigWRTL*hgpaCS$!@3+hBv^TCIuMJ^oR##8$&^fU0TGASspoxU^Dzt-iEzB39Pr` z5Nk%ElWX_9M@zOVh0Xvo7n-)2FO5Fa$Yu;Z0eQsa?;T{OoS(Zk(k&UJ5X8Y{Om}n) z5>+VlW7(S&2k^1F3H8Rj9Std!+NQBQ250Qh^*>mF{o6O%8O|U*?@d%oYWl5C-&X{1 z$Hm2AcKUQMzP<$OqqN_ydG>fXp(z~jC-4%MT*_`s->5DMxG)*Sm<4Z12q;)CWzS}B zAg>oT>*PiDhcsbS@tkupjC;{IK*W>&6FMwsuV$@g#Z5NWWk?NBXCjD=O%N@cr#Bwn zHlT_f(tAJru}8$6N(dDY7ivF!{GRu{WlWgV)(6SaGu%JdyTJr>g_anNd)oA`>jY7L9xD4OI{>U&jSM3acQ>}=`nnc4B$bLG& zbSbKGP;wnj-ZIXs62lH`JzC_B-sMkSBY2$gq|P&=*e4j*Wm8}4IX}wd&*J-BIQ*nE zyi1{J+m|rd*;CZ>?jj9xf^wQpo%RN{_98=}a%xg?j?5Y){c4n8mUnkL`d;BcIRf<+dNpIoFVHE-wEj?xUsJ=>o93+l2yw*J0(Q_dm{!v$Tnd(JW#$idXN$>QS>I$n)1i%M(=x$Xh ztt7`q!QcuHk^Xpr=CzcyjCRiM694LmrwQsjG5Y82lpG57Nsg;cr#17w_Ql|BZ7H=M zk-HrPZH;peG}ckCac;j)QYvwgEG{v)){C39{k<*P&wApbdegd-cKrW4C4}(DbD?4| z!4_|JT&;z9Rws7CBGQafa_t%^Je5e32k-`Y$@@4XMv_0Hx{ko2abcjHwAk=x^Zc_v zVwzpz{GS$}YjezyTfiyb{#`HD2F%2t=-xkfvEe5*PAqk6EMG=?pZ>=&**?(_^b`q{;+p@XsSfuu+$4BqXE#wW_FSAtm8@ete*o&86C5 zsZt*|0^upByPmz+<Uh4G{LHr1Z7dQ4- zWtI>b-Dl0u(Amo$65dfsZ#O7$oM0BJLo5?*Z34`0xCvctjdzSIIzHvCGE=4|z@{_X{sL-zL z$rHn~bVNs_V9C#)uK`yBjSJ(6Gp@%N_#y6cvu^KXJ;e4L`d@IVEmpmI0`%=Cyg0PK zP|kK@8~Y|tJFm}T*fDqAkEcLpkwh+n_?MeQubp8ivaOo&b*3kf&aymt@lNa`q;g>! zU!LAQ3LYHSMhbf;)D_t-`;rMPN>`$VIsV!o^AJy%TN;PbizzXjZC=qwi@qt39sK+y zD`UKqa*YEH!j_tKod}CpQFvN zf(i2{Cl&xNF%C^^V~M-&f4d#RtK-N@a2erR%b(}pBS6Nlo+xysKca}f{F2r!^8 zkuXl1x`PN)D#Esk11BjVJ z=z-~@DZMEQ!SPK76DJ>IzQ9x8)8ZM?Kxy2|!c?NnPKxCHmU>w3sbPaRT;Bj%Q@zGEl0ii*U+f;6GFj z#04mwQxt%c_p0S1e=40{Cpl7+)z(?WC(cg#T!*e8W9&aC>0f<&Dw5b>Uy=F-0RQ91 zp$U@Ssrp2*>_+R;^gW>!$e)pku1kg%i?FeO)XP<~{t$tHF24#<0U1}|Q`SogTHbb&+aVlfSqE@@ zM@=30ckm2Sx!P?uVdcULE{rFYl%b^tB~vvkw^CVSCc-e__en=kdoD^&Dch6vaL?eS zekLAV@K>?!J4*WorVOr>^%OUCO8p+n{tDy*aXdSb2UUYevJ5BvY|tYb`#4o1KVWoi zLrZfYm{~%kwg!;gz{=vWmJHrcBv( zdmqOShqy`@%)2VT8n$#__`l3LcA?dm0v@J0{P<(cQ2>K~)>#+w_Il1dfy{yDKg~lp zJDg#3Hbut@gLYUXT#wdG(d|I{%&xi~$PS79#aV2!l=vDd{C+anuXV)&h&&9Zw+#^4 zkt-_OLWg%7w!}TY(R2z%Io{)_=6iIFCvt;be~nA5@3ZhF4svSGDArZ_e?L}%yHYy* z03u$l5eZrQNkwaUbX$GbU8(wYOH$IivZOjc`m8EXs+$9K;`BchFA)qSo;h=6`2b7n zAV_gjrfP6-m%}cVMQ@con$hPAn~PxUpbN)5)P0N;N%-vvhWHieX|;Aw5`a)3;(&y7 zWSPH^&M8wYyB2R0AQ}+w^cBW}{H(zW_q&bB^2ewWC!Wx7k4v^{O zrHRTXaVytNFV-bx!BT_h1(Yz z1o1dr5OUWROLBQKjeS){-cGjWK+BlN;?1(%m;9TewmIdWfP0n~TVJmVdmEggFa-;V zNx%m95Edp3B&io(LasKMmfSl*tEde3qGR>R=?WTpRGTQM+s4}t0WcjwCJctFHr(QT zzW7nC4dHdSE7;GPAx2g9_YQ`xxCd15y;a#WYo2KTFBlMx^mz3TH0*fwc5=@_D<~$T zSPp)P5pbaRi5rLU7cOT!V&KuW&m#$U=l}-gJ@?TP6gYzHl2GK~_XQ8asf`pOLJJBJ zBaFJCB$R$67Il2IN<}}y%1YsBD({neQ^DezHBv=n27N&go&$J8e0-#kKm z)I$>q5^dxYXch?l>3`8QKawm@-tWz+X+U2m*#mWn6puZ(aCCG&FA_tEI&f7G`vNSA z`e|pMum&}t{K!{ZL2>DeB1SLMh3)UThh1?u(R^_ZhF7w*vVwtW(_iMj%Ow}XR^sCq zfUbzKpHw~L4ZJzjq zy&&=XiTFJjt$81f5OduiM7wLMoo5em9090`<hUqSk{kwj%rhb>yq5Wun+=@<(Y+9QoFRe7F!OX7_D6P2a?;T)+~u}e*C zfbEj`U2{#GZVIXod5oH0?(0kXa~5-FSfT*d6t{+<=KHUuB%{Ne2LphUItemMfh#%) zT}+z^-{1-|Qh297{*O!H;q>iG{Hf$)Lcpns)Z|HKmE9hBEKfEyHD-nT7?|<(a$p;t zK<%Z;fqG&mx_EgnJka{_(}OgN=LP^jn;l zj?dgAp1)hd?N|i^v`rcNJFY~-CXfb;diK>l{lD-oPFi0504xMwP#r@B``GW=1BN5z z{jCMLJP{~E1BzGCnS-V<8$@@W3zQ3R&iTBqRT?^J)Gi`jQf!0{jShJ&SpNq2nv$|I zQ2e9{xw5r5M(T*7Tc|jwNHF7dbw~LOZS*|4Z(81Yf&Vh#yNYjU=xzYL*3mBJizsON zg%Si+*Ta9@*jC~QeH1Lv>JJ!c{m>z9CXyke`EH>98B_H}6zDe~5FmcARvu0P4S9O6zEkeY+GL-`aoD@AUTaDH$)L-c9+~=+wGf>>WFnxILc+{g;^-kn*ILP1=E_|L zgGZBXM@9B1GRsZ99%~^IhUKI!KvrwySMOpDUDy|jcc+1#rs^LEMkvqNQ(8huf$~Gl z?L%|;A+rtQl4H`Z9K-Vhg9v>M@=Cd@o~4Xsn57zpcOLE#J_Y=(41te52)|~K_UF4k#H)rlo3lF#N<^qg^zLKaGP`8t@lrUT+f#%m_EF1 z*gQbXa`_NApA2w&J${0gB7<&+P1H2cm&anyMquZQbi6{uF_Xb;v3_&vpNwL)P^p8Y zhmxVaA2M|4ASEEIPSd$roeGXk#Z)JdAX1MD2ppIO`Pb8V%RE#PRQFeMyJ2YhDJs8g zSs3u*%)H*N!wc#kk-VHPPe!c%_GAtHI(2huEK@S!`(2y9gVfS^j-e~rYLe6&^c*GDW^J%tHhjh(szlq5|r7G11M$O9?I@QQ&SKyEPfFY?7q)WKh!kDT>kVC&As!) ze1|lgN*jLK*`P0=^#T&U@VUw+eb~e>GTI-ML+qK85+UnaNghi=@S{D+Y>V9#Pa6o} zf?<)P16|){Bzo5$=Z)WR9o5XQ4?U;yOiWB+(XYRAUZgup78VW|x8*;4yohOckuOvr z2~%3O+o3!VeZ_SV70!u)wQI>mB|}^_wiHp8nqbFG zmf6ICus-y@j<7E~g5rT$_@2q7qd2}x~yJw={R|Wdds%~&wzOn3Ohwhz)$gJCP zkeV)~*F1Q{JCODsG<-QmIX?0^EN>jD*R3&PGLAOLR~-<*Y*HZ7Aq)PiJ1_rO zWt_#Z|5-up$K)qhdwwfSaQt_dCnOK!U+H@qSh^N2$n>7r_9O>QPD#rMUs@H@h2sC0 zxNKr&Y{e~Dm(N@1XIRdO0#JOQHSYC~>Hu^L)!y4h%j!2T-k>U}{TCMwgvf})V>FcP zUZR;3WP#x2mIs#UuMYp_^pd6k=W5^n`M!De7&>IwKO?<0bNt_XC%#rch%*1^@@C}- z6KKn=CT7m=h}J2(^74@0unp!--uMVq2mi!&t)p9f3s>pKKurc{iRfM;7$Zv!2S>`W z<~bvACuM%+-Kf4FZSet07>Fk|r{al9F<{6VO!Ml7lG_%4(iPTR?N1I;nckUttOpPO zc~iB>kM=M zxBP`-!@e(*FxFeYyBW@mchl;whAw&oyHZ_ta=Jb}6#RVpem_WZ*QP>m)89+I8vP${ zruza*(}^uf9ds0^6!zX4t*D658LfFSc~PV9NhE=YWkzwDSA&|Vx|~5Fe~RxW@7&#+ zKS==dM`g^0{G3^JNQ5Tp$$W;^)acffu~pC4Ql8zg<)Y~If{6Mi?Hb6wGrhfF%8iB^ zi45}7TJmg+*Th>_K#aB-mCg1WeHx>%yKjEwDUuQf3N}3QPalXY^kW(Jmxot2hZ3@a ze^y7CUrpJ_PiANkMC&nTRnylqL$$({zad{S-D{Z68*EwZ+%gNtB>!`cL@DhfdKmw( zcDs~vT59te{gyc;7yisst%EHX;l{mJ#FNdctdYfp498gtzDupIrq3G!p53@0L&%iV zqhL~RC@d_`P;n6@#y^mq`AgM6e^`PkrX3$=_V|ePRN`q8U~!z}AeNL%D?&^odEuFm z(YaATextJI+|hK=jjDY{HGSs`(d~)n#PWYsOl{=>x?kwSM7gQ4G<4>2R=GJoG9grV z)o*UZiq<-?E2aPxd++zwi^J#z+Rt7N_lmjS0p^Nx{;Nu^4nIN*o`T^@OZ+VLvKJ7u zHhy`7N}>_3>g+)Z`_y3%#}spKDe6MFOpEe#(9j1vt(XJLMep35V<2Ejn0~TOm%{^K zKJC~TyUV#_yJ(9eU&KHlBS5l+x>(-QC?~6}N5LckChE z7`{(95MXEu7x4yW)A?PUfy|rw?J2huCBL7DWDtb!UGMr_)@z^!N|i`6auO)=v@H%b zu>Ukz_Ni{Qoxu<`cd}}-<$~(5b>>aH;=Gs_K^Rpm#J6e7AuiyADU2ptkqxW6Yhz@= zS?5SK?Y4&x1nV2T@3P5$vZJ*YsIH%w5Z<2PUbCwjki?LRKNB3oCg;gLk<&!=E~fyF z3=vR8sVd|I<2b96#e=tbgd?*2%}R7bfe&4*mGpZ>j~3C<{$-lvh2jHMK+*jw3UzLOPYj<{c zu}EG|T2GOko7R`%91U~V3Lu7)ia;n2Y1{F+cCF!EYmIJESqr^JN^wKeAAaV9Plrq} z?yvvT14bd@&C`EqhI?7^(uP?gu$j7wi~d~TJhaa%0#Bx15YqkW5gSZ0@2*hSzvWC0 z(y44OD6j1O>ukvRwn!F48tT3PLCvN`UEJx)XI6EiZaZ~EU?)P2kcUVFx!$Snd&8bC zrQfmfhsWGZIoQR8hS;JC9~*LW#8}!R6?PS5Hm@!=Ozt6)hf0B}-56s&F@{+`+{ipL z>EnjsTrMi!I}MY6^Vf>f;b*x~mSx)x?z4!t0RtZ3Zh9@?R030eo8H(5Vd;1v<4P@& zGLx6%U%ZGg{zs}60k2Py)Ei)=)fi#U*Xectma^-xny+_!)YZ*ka;Rqk1a+RQ16S#t z&)G45s3;i?3|AtL7Zc}kAaP(5=JA7P+-aY+>gEfZ>RMl36qK7*$7kHM2POF?fW;5i zTDnj)Qa4lU6E6OxOz--0(_%;Chza;*sCu-e9nTgeatw>Q!)hQ*I8bWlPve44tNFd7 z>!OL%K;IZRmJ}Oe2KSEwapaY=K%iA;~&3W1(rF{(?%Ztu1-N{YsV1I~rz&q@hjFS(pJ*-3#FFH8OLwn~CGkymt z*;7c2V!=IA55irnfEk28RTPsQ%|chN`^WLMyFJ@C;hSRT!Qqv7=sQwM339Ppq~p$$c8q zmYZKr5QTs0B0#9_17}-I_!Gs@F_`8zh-oERZ+x!B;}6KKm2to|eV_0hs%vhq)~;3y zf=zPlVg3FtbtK`P$dhz>SBw-9jB1{Di1m^HX%V;X-Q~pw+q$oxX`9*bM8o2Vywk*BHL9vF_R?Q8b4UiL$q56rBy8RI)-y*rchH?JEe>*aO z4RnqLG-KV=W|m(uqLC>=km;gTa^Wl7tRzGWa9q z7ii8;YChgOXdjG?sXzmM+xhAZu5E9MHf7h|IYNPciX< zP>PM;5*{AFn#T$gR}~J(W8hImvf>~>`hC~>9d}9d-|Ym|#RP21 zy|;CjGD5z|TJ#z}o6W64fZ$DQLRyN;Jrncb@a8lSNOaz^5V8eBCtIcD5%VZQ#G$|Z za-DAva2TTG-uoiad1RH!o{jS$5!gx}Q?n5uiOLq|q7Q^a-0!&A{!zWLCBhd8(SZf| zsOf1R4Yg`f1=I0*0$Wumq#EtmqDU6Hs^)XTM{50TEErYMze@cCdzTU-&TR&I)%2;! zA&aQb@4K}TAj<;r9ArX@FRtxB{mT?Qxl8E62Uy@-y~+7NFYkzYxDVU4N91?K32Cj~ zE)r8O=$UfbqvKFHS-!<&LGj=->eOK&d(w!xLZUg~k9tZqGEk0~CGcbKOp^Xcb`jP-NiV|vkSSS#G^LrB}?)tAZ_D?wD zllR)gA>|}fRla=0-}D1d4(}x&afL7qr6za1Tf1rZhTvvhxfg4G8c^_VnF_UPyEN<4 zu-ru3fKAZlfx*5$SXeixt|k-aI)iE}w-<7|`Hmo}La|JCEnZVfd@Dx>s)J=8#Y}}6 z*G}6dDu#eZW^|kMZ$H0DO}8 zTlGeLyB~Fm-Jy2lXE?Aabe5`kMtBu>d&TIJ7Psk`+$eA`a%|# zz8h&M>fl#*J~03Eh)=xnI9KUI3u!A+fr7+0DV7VxkPVl`SOwn@HPF^yntZD{o*tXC z;!nZ~vc7i*R5f;L+B&6$+Yb)xy-V%1mXFN^XHowVJbLLnWKN=xjuHnHsrX3IeoCSH zgtNSoGLKS}F4v^f67?4z#&2{r3Jf!O9|&UUN}x!#Uj85i%p9*U>IJLY%_IDoRLl4A1KXeRm(sKi63sV6nsSn)SJmbx>2 zp+v1S%Q(e9M~C%SbS5ts)6$5XOU~y4bC3n!V!~8G>{^|W z@(T8b*-hAY_mOEV(IBlKTXDP>Q-7B8D_K;YUB91;wG*~NG&VQ_qnaAje*&5uP_azf zvRyHSlf!{%5Y6mKT#H=(6{W?D<*YAOxZy#MZl@{eIygE7k_3@Vde}F`F4VFTs3$&% zY0cuZ7*tu}L_9BqS@p!BT!E^^?m;jX-notQRqG#*jQr!RWxz_!to}>7>>P|YR4DqvE(x{|(Ph%= zR10JE*+TuDmuM3tw+2<=bd;QfDwhRRas_gdH-?BA>1V@V*$`Yfamrs-aoN1|Dzmw-7NxoW~}Ppce|3m%SmW<7OQOWP<8rm zzvEilYiLS>3!Wquh}f%vY;E~x!Vm0gLi}8AxV7BqF|QTRUt#M#xHr41(c@6 z!@H_MSJWFRwri-V=nnF8ZK5?mqH>vr1Io#e;N*do%rkbq1+N5-02bJd?DAp}hgLlB zXgRQa1DrVleD}PJ73^rxjA;57!hd-9bntGeReJq-O%G5j{_T_$AOmQ_8Of2^!Olh> z11$gcq_)}C*q?iNmxiS!ILA( zmf#BoiLFP9=!P+z+;G-<&cR#wMLg>Y)~%(s3iJA^?aal1690sNM^fk$B-iMbZOFr= zSnHY9uhk4^2gb9z$tKaR13%knu9SnDzONeyORft!`mST1PVTuhwxs9LEVZRYN-0?>tg+WYa#(#VswrK7!oJn;tK7GZm@c zJa3?~WPH%?OX#p8{<#^rx#{FSUJ@%MMVo(}m?_wXaa}GJwA-WI*?f^0JY$hdIQ2`$ z0`;YFLp@T~J5(jlU^fRgwgdj)$M*Eq8Tl1+a_%`3J%!Yg$Zjg)BL85cm*Ka?gaqkJ zT*Q^RN?l~NL=9k%y*TiJ_(Uf7yZdz;PYY_PQ3_!7KK9KRI0A=CqG} z-}cU%!n5hiRZB4e0BnLo%qE%_p_?))TY#oXhQ07#{?pXS=irs$^M=^Ib0h0ClW{-laTBdo(~upfZ^|QSbap3me>w z-kHXx3^729D}KTqwH-f-{cO@um@VemsD4Q}y|l@nfEP8W{-p|+Jr1~qGH#kA-2PP^ zfb=cc4R;|8OS|E#{6QV`zw+_9>}k~eq0skmcWYEtZH1wMf5p9!jazH@-yE;T);kSE zus9=QJ%>KSOV;gGV$BFPEkg>l-->r=056;>zggkC*>c$0_Bx<+7V-OIf`NO;8G;zDK+pdDb4AiO5SJ4w zwc6oL0`x<>7ju6XLQVg0FD=1E=@v^nJ@D_CD@VpuUSxIOr@+`AF z$6t9=Sz$Al>Jzc0&}Bo=Wg}QwF=om05QB2!iT=KrbcR)?d=3K@MiB&LXW?3|;eYbp zdG_~PbkAm7*wHYvpzLp*o{vBIA^2iw`|1YKu7)pw%#GvKJrs(?G7VHrl}wJ;JyC$l>^GI5U+&I?>RK`<6GU zq9y>1wUCd_RwCoSCR3OLu~*pf9|?tWPJdnQ47GCpkEUx5j->s%6I&bGwrykMO|mg3 zwr$(V#>sAMZ0wC~+qU)1`&Ip_dZz#AnyKopr|-GE&iAU7RiU^?(x3s1KDJ9V50yD!^up&pNPwv253H96vVs{DWXxd4z|onu&G0b5L5 zEgx^xDua8o1#w~?kj187q*)QhX3TQ#)6x}EckJ9Q8?iTtY&#OsEqHs;&0vtSmc&5#0n(X&_M~KidrBb(rb5`^Azxqyv!_gORO%x?3>ztjh4$p8 z%MX$?^DfwT6#R7*2gU|dc+d7mBXl#fKBz_Fc&WL@fEctl zrdI&ADISje!s_u~eZk9yClEUd zW=cFWknG*zeM*Gs?G%^K%=n`h@oGnyFvNnqNf9%wO6h z@EwloUpm;YtMBLL!sLHX@vtS;N!r67>ik1D%mSCr1_xVERIK+Yu?McWHoGv&?f!Eq z!LfDa$ze}|QYm{41k5z9no!igh6-g4h_vkPI8%VNJo+I2*Dy14-s|9XzW(GQ9Kw~S zVcQp*6gr%iLoIvu;zUx!oMcezhO&mBA6q&hEK!Rk@CVOEVM2tNKGboIze`42&&;geBZ*{)u^j_@T z2U2cV7uSJn~{gWMq5wd*l;(whxjX?(?In`&LnG5SBtbm(^?z$m_* zi2+s?*!0O?Bfar0p=KZh})t^7osForW?P<+b`i8I~hwN zI|KkJ1{lSD5%7ViI7qYA5{K4{<-~cgdT6foaBLFIjObd@ONhP*=z#H8=ikI4+rOW1?cQd+_AZ41?pGk)B4~4m=NBiAC%j_G;t?ip z9@_*uh=_x@#n9Dad^UCGXyGToMkq=8YNl=qE-usNplU<;%ImyBPA**S(#xS{Wk=+V zM*Ao74K7F*k`f*kT6qLll=7Ddb74dTtW3&pGH|&R5|As|Ue7*(cd^=^htJZ})6-0_ zk52ciH@(jDtFxN+3dJ10GPj(DMR|Y&{mINfFsr1T z`L}=K7_=&E8&ad0r9$pGsNByawthTFrp|V%u^P^~-$5s@3QA99s=Yo`lZR)_|LH_# zfu5tbK&af}X7|M!b^sw-7!hqh#>=$DO*)p1cH5e}{`EXzdyKJ$Z4` z>6LjY4wG?PPWr9W5a2GH_pb%o^?0>Gyu$yQo$<{_;dDI?$~vgX)!dIKcSTJYfzDpJ z@il(SeDQar0`Yo!ZqYCEB8|zQs;tb_ukVMG*^}drS1EvH=v!I*>FCfb?pfzkNVPUM z*z3;J+7{L{9T|BuxpX%^Sf!*;9WK^`ru6%&Rf^1J8?(KP8Hxuv3$Xwd})L zogz|9l`MI+sW2t4qGSfFeK||vWF_YkT{@F1A6qY6eG0Xxq>A~HD>>IcO*K$$0Zfk{ za#RyMLacn-wvSzD##iRX%<{3Z3zqzT;!0w+X;X}JGM2I_cs%oL z8jY7B!`8G^G5#jXIobYnWhVE8?aK1g|C4Pt^K+2|=qnUSYu|-sLEVqc;IGX}9(*GH z%G#PAUL*i^cF&&RtDkEdYRt%X%D@isUWKn+qp_0&#G#Hi&RG(_uop?_R}VGvr)_QzrbT9%{>u+W4B!f z0Kezrq{P=%Mp3X=U7fj9>rFK71Vi-h%7MEZ_^EKudN5~ey7~e&l>PW7G{gwdbp!|% zleEf16-DpFK!&vzopl(&rRZ@6Y0sBSqA_T1t#bx#p1JsmcO8_=*;$2wm4 zusLF;=braAl%4S$Iq1L}lSJItCkwWol$TQj34P+i_uh%B!9*6~X|v_^rtDF=dnAY2 zPdMWIeibFHI@q5p__=q`FX9cq{56T%`R-&Oo~x*_R1UL;g|T*0g+nmw zwwWX-{x`9N}Ao(&Dt&e0wjsZ z?6tg>*j0LW(PZ@V&Bxty3JUy4I^?8iy}5nMcK%&ea7npGIi~c4(ie4!@%u`m4?b>% zV88_W6t-1HxYf7y-OAsDsq39Ur+MM{r@sag0$qi8 zjSk`#s|C;)9%t-$Lg7Ij?r$FNqd>p9J=~3cSF`hq@uSH0v=8-1vQG!vZ8V;@B0x=;)KDMZyzJvt?%jq*Sauf?~RC?E`EQHWOL^#e;5#2^v%(hlidneW`=U}*nZ8$ zOu+>h!nKz0noXgPKNUkClzeJjIkMQ1`t$JzSTo1Lffsxvi%KFZ*ex3P88inl@@!^i z)%Xy|Txn*6c{A|dz;o;6_HbfLI~R$z(n3%D5v*f>xjeiExTAc)lV9h*K`g%<95skP z*kVaB(-f)dcpGta3q2zq5uV^kz!|B}LTxHA@!rr$+cOPJXvTm{DCI}DkXJ5wCWV%B zw{(3%1UG*K!er?^Y=7KH|Csq`26X5%mJXI1_>ls*e5#RJ{gBiQF3MqGNEfzsz)+$@ zbWWpR#}%ktZN!_gB&b0l^za2@<#_w@J5`f^T(w~Pz0W|12bHT&?q)@AAkA2H%YL4O!?izQW}) zRS&uifZMtFyOB>nAA{B(Pr%ESrLGntZjXR)eD2nn`Gi&RBi!`zv#6|ZU4sKrgAl>k zeKT}}LnjuFB!tGgGzx3gR@Qh9dvclYX8u0PAt~-@zxdUNiNfV{n5vid zO{3h65cv=L*)3@I*zNiqI%lLTfe678h%Sak1U{f$dleXAtxYK1f_}G5lU2Dk56}I_m zCs8~!y9wNEps7nC@61X@-#?AV;GXV&67{@YVHeq1PKzv5-N3>5>@_XH252%>1QJmM zyJzn@v96%XFt+a9-RI7Bh*Q#{s%-ukp3mJl7II0*+>?enMn;?}Ja_sJ7w`2t#Xx{E za`7ojtFuv9f`cR-=9s|l%C>j5WYi1ISnitGXxR_Va!2m^R_$;`rPkJ1^xKgP`UF#O z_QR~$#ZsP@I=stTGjqN*$FAl2j9airRW<39cfFn#fvb$)^1VkycFKCSXH(&fa9RK7 zIqnkG(WGlPo2`ib#I*_Rruy&8%&S=7B6YcWT}EavC|x;j$E;|EkoB6%G1AV<9shE~ zos&lVV|{g*?~OM`3M^*#RTeHr!XLg*6nAA7%n6=VPVf7UpE3PTTYP^kC3(cbh%9n6 zku%W(9e?^N+KS&|&2bL`P)~%z=}vnTwb-?8Ov-IezheNp4rkHRplfHW3t)4b@mG_z zH!6(%`NbL^pyeqNob(c{<47PH2knS(HlTW_{$UxN}%z<1t^dP>;!i;ZAfW|&1Z_uJ|Tf+ys= zLtlBxq>S~}oZjc6;t_++pfdZ8Z;+28lRi{U)_<2Wl2yqk@OjU=D zPNIKo-PI5E$GC^F`_Ai(@a=+8s6 zM$*zMc-?qIvmB;w49qx89%|rIJ^3+j|z=WJqc8+VJHYs z$CM;AE{slIo4LgS!t+?icQDw0=G6 zGVyJ8;wV+3nPhm@V!98N53WCFCueuOv9>jG!S1F~dUAOpQQOq?HU?RX+8))|YwR%k zwcVj@PHN=9E$I>r{1LS!KHoWKzW#e=a6RU$wB6{dboLdk>hXNlc``bb-SQ!X<-sPWa73(zt;&6~@g42`Vl>3~ z!oK5bv_YKr^NCI2_QE{NyuDOCZB5;T8Xy&x{zsExKih=Slm857E@vqi-0G8i*nntT z59HN}r*3?k?%sJg+_aEg_hRPPQ3*jkem-E|ojK+%-QAxn=v{9%mgaL@5U$nbiKv)6HG1@v;A8(naBN7*G{)NbBx=s zzfO4G#HqY3)$C%SxrNzLyRP0&(I<=g7U<-^NU@3G&*+wm(Ry!%pY)=TitMnm04R9a znYVAbR#?lQw`T6_&zrJDmkhmsRgZ$p`};sc{>3G{_9K32_6MrX;HJOB5$6xImqs{o zxl32Ym5qRAw)oSR!`9j7m1=5Fa`8?@)DFHDQVZR>o0SsYD+lUoLE$v{I2f#eLQ{Yk zhgl=D8xc0agchs)T74tlc%aMOL@PiG_bgo6vG)vNbI5&4hqLYV=P{G6o{$HRifY~NB& zwOb~fQw(Ko%{h1H)6Fn~?xyU?t#jtQHrN!GnoH{w@0W*9a~>~oL}o8+=k;Th;K7wb z$y2wcZt@--7f}XU_|Da@EiM}pKw9&f*7c>sEH;2=ZYbXPaEPvyIXUp=_d_5k>P24Y z%(d!sYX6QU>P1B2NNDWBxV_7`HrC<$AnK%$tO?h+|E#3hFlL$xSLz@W^e1qE@l zWs%}o-|(cu)ZU}HxmWC+mu`Eb(TLu0y*C8(cGp79wNWa(Id~yD3SUo8h2z=WP--Pr z8U|CJb`2K;m0s$Zi((1RZOK9GWRJUC>s}c<_m4hwoS@$8}z+`4R6a(Cg{hX_YyZvr~nwJ)4^U z*YkF}YkaLmkuiFxD1B{9bEN^uVq1xqz;*x%WLGG^{|LJCNoz^4Ccj)zt)(5fChBGNG;So0XF@+aj0FC1a2U~SeS(3ilpM{E8!z&mqQnheHRDtz6WJb0#@CtI?dRZas#Zk4?}L4jyF>x9^%Q6;D+ zWYYG8&sE{e;C|z@%O??zaCJHhReEO6%;)Uz-YOt6SAT3PJ+pUTNYJxg(getyQE`Gz zsVr61@yTtm8g7y~UBD^XEMHZ#jWjQtbv1- z0QX63d)3mKeeF!F4!xi0J9})#?JGS-Q`LHu+a|1qxzcCI4bmwjkC;55EcWZccEj79 z-PXY$9u7{y^A9}~gkUJK>62df=x;^al>8H1<&7hK?O7KhWC$t*BM7sNQb%C?%sW-i!vN=9;}IYbzX-LN5D7!#sYcv z>^G#TYKXUtdt?4lJT19$fT&fx9m8@dZaD`ZnSbPi`CgBHv5Q?vaEjFi29>+N3U?R1 zdRZFVVCTdL}pykgdZ(;D1^GMjZmk%Taw| zHT}!+zOCkCTPZf4($!-$&?AXfOm^kAUw=;(W~=@z8aKGu;?*LkobG*=$Ie`SBv$Y% zgMeaGHjxE;y4Cy|ZzTPoDgMKH5Uc3|@w;wnb_?&f7bD80bO|d>O|SgAfz;N*n1a<( z)QH}inp1nwRR!+X$JvF!QjKOW`ox`ck22==g9Sn7lgosE7tT@_a=6~okB{Q5A%gP8 zXnDoQ?OzB*4=$8}?Imh{2PN%RDk>PcN*g%)v2>VsK+Peb?xdsQ>I(}y{120hdNsjT zDd$(V>Kga;j6qCuXh)@Ug=!x5Y2~dEQa%C?COjm*o@vH@|k2Ssy!lJ^r}P zUoBBN-(K=D+?&BXL~gaO3TwnsG3-589eB{6C1|84jp1au1`yj-jAEK2g-wv)$xrC; zpP0vO5)4c%Ex6Boa1xUMa(N0SE5K@POgTSY+(@Q?)%&?w&Mntk*y1an{P*()SlbWG z!{(FOvH$`;7Z&-U6ei>z?emx@hKXwn`Y{b;^OsX(A(bb`zxG>^zHg5QFvLDRne66H z3+1WnZLajqb{m6m2>QDTxbgKq4-U3j9hq3sp@VHlx65hK*dVG9SXTEsK4Gvciz$QWJXt;dY znk@r!q?A+Sa@O}u9A$biyLtiQ=@DZUXy3dXpD!f~bO;|i?6miny|>*~o23GMzdvmY z-FLk$>dmpz26iQi59f82JWo2P-eu6Mm`3hycl{o0qP_P@?eJ^zXv>^C@x8=#TDavu z;yj~QMestS2=+>jq*R+_VU6=~=i&9oYTaHle%Kx+-JgZp7Z#>_@#_9vl4K&CbflO} zypg$CEb+4;Dw~z_d3m_k)D3uDSJSOLb}P;H$_TP79Pc1->U-udnV6)Kw$vHdWTZZt z>Jo2bkh_X6bT_nja#Yd7Wq<<3Zl{{uagcR;`u=Vxg6oFx9I@#Is0_8o-V3QV>JNkL z2?>E@`dJ?WXmPbpd|IwN`8`-NL5!6wkDZo%Q-VIcu{LZHK0^D&z&jCcGV-0SrPt^~ z1_DVTvfdpVL7Rgt-A{AZ@~O1>cn%yp(X_V~EQLeqElGl}HvZ>^K85oS`^1hV1C=qI zq~UL!ds}}h%(>~eb(ZEhQshADe( znZN%M@tlR6J^SN6F5}d{%72ueC3&>%hmpnz`~*F=RC#xWU&4FzRGei)DVI5}`i8=W z=iCXN@YxCktSL)G-U+z!SgK?vbBJ<&dr31E6tdqa^OU%$KxCi-DTs@_LNw_GPOxhy zxzq@;(ngLDYQyk&UWvTyb~y%5F16i)>bGdHHpwq+Bn~H~&j({jqSFP0>q^ZEU0xc! zo#L&G^(wWVXf=a%{7&|6@iu@AFj4+|K;@5*3FDf%^a%Is~=f=hztitIO`=CoG)uJ^Z( z=S0h#l4(4-zRf0?^L0qRcsQ3ziCn*losXan$ySnufs4{ttS0-YZSkdi;}*IzV|;t^ z|1r;(d(!`5wpU!#Oh(ZR+b|SZ+*f0-Z)P)(M@gPBq-HvU>8$g_1Bnggh19G&^2O%B zvzKdzAY*>T733v+*@%MQ4HVU1%K{j94UYb{SDlXoUayQ1X7}QAH+Ikl0G7@5T`=^$ z#OH44I1Xn}S@7%Z%bk*!p4_STkv)FK^LvBB$*PbDyBcJzhKz6L$A+c>8i2S|JrMBh zlf~twEh!o7q4e1x$rkgoVxj!3e9Ns=D#BnY?x0>REQeCG{riGRiQ1yWY_&9v95_3C zwc}`Rn+sg;W~n6DyskSNh<6>*St+M}%U%AN?LTk$Z+39*7|;i=arDW z#KK5*VmxY<}EbCV?NaM;03EcZ_bl$J46P zOTUQH>|L9m=zW0-Y;W=;m4tGSr(`&4^o^y#FT+B#J?R#ry>_uJ#J8JCf`4la z&IeVzJLs5wTI7##s5(NsC2j3e^Amx{Ot5t-4vrLnhd9FE8S$J>%}281B*eRyf%C_o z+bxM1!vO=`q~v5UKxXC&ECP}^lT+}de0_jV2>{@501~Ffgdp(vKlbHyg)`8vK6MxV z>)pLQ=sSQ&K%y9=J{hVp#0P9|x7E3~IPnMI0s@$41|8Oerp}c_*t}7JDB`&((N=$~ zcTJ=Thp~vo&Pi*v8DUXS#3dv!l60k&ncDa!mvjSKfR?0(H8ecpKZz|};pB2RXIo!lb3s%u@ zV;m3wEyln3))ExEX&uN5<(iTUst?M-<$R{e{z|r}!3Hb<6<6>FF*Ujz(sok9#$RY#y}RZjgF10i}6Ha`3ncIqGI7wL+D4|HBwvOO3vG ztLGNf<%t{V-o*~A z;k8!6;!+EVt{D_A*}#-vh}sOwrnpgs0YHS`9lEC9e*wlmP(+sR@#P*)VcO^5Sb1?d zvPj3+N@-5*<6%JCi{YJ)Y9akWF`8|Cs;zirl49#k2=xs87(~cZC&|Mi&c_mcp}O zE3+jZBY}gW!m#^5Du%}-wLOD!4jpw+c*jwdW5cNOl@U|HXv%qC`ZbY|?dd=)gebj7 z#gfwoSh)y0x|O5}4RtW(A?3d-n1*a6L8&&8Mq90fYVi_G=@aXWzkg@Ig1vD}xV<&x z_XKlk-;tMt?9|t4z62K}@;wg>p{0QAyUzGC)(-Yf9iwL_ z0LLA_QQHU^35v@$_$B&8dEIW>RQ2pP4GWmE0#%Ee8fkh|fO|i1_~k{kf8Mz6y@IH~ z`xZv*8z3PsFFu)C2^@gOVUhnR8~_FZz1<5#6rhx5gz1wol_#$L7RSQ;Ni-WMNVD)4 zf&eDIclV+1(xC?n3;N&`lZ6v1F;mf_*-qkwiJ9DVkej7lua=jMnR5<{{W@&c0C>d&bQb7XfY&Kg-M-Lj>3Rh(Kv@!d(Xcg?p9=VK-3x5) zM?(*Omqj`hOF5=|qOP3mSfLPiLFdS>09`ofyAj}O{g zWTdgQ3~*FP4%k4Zk9qjR;Zq1{Mtkv?Vb0amm9) zB0A&X$25BI)HHJTv=~m;1JtjONW5RuQPFo*91jJ4BOgOa&mF?ruMs8D^cXkv~#pp2&8ZZ{Uj3VA?btL>Vq$IL< z+^qcAP?O&SxpEc?de^W3yz*Va-g|s027kdLXrQ1(2H#AKqT)nNy8{zoMP_q_B?AZS zqhKq*{Plp^|D}^-k{%-={jVCC8?K-(B za*gGH=MEE`hjSr7K;>|42BR`YpQ$QwxO3TA-N`5n&e}UgB@iDg`#5ORHJyB10}q~3 zYg~f{-iRxUL@i{%R6LLy!a44*L{&m-f-7701rvLg zdpDLEYcHJLzHqK6uOA2(D25AckgNzU{Q5lTgH@07LFCQ#kl-!f&U}N008CPR1<6}> z@8p;x8!o);T+2dv97NhToh@{jN-|bxx)@IkG^@1h>gZ0a#-*S7#G>j@V2svgREaJD zdM=l7Bc}KxHFKY_gmdr%j)=X8G0Ck&RVXr=+TMPwS7*&7X1n9rbFRSwo=?sJ>e1!l zRGhC600j=w#nl+~+H-Z3MsE-BQ*|2@)xZ@~l{33~k~LR^yLeZz^i{PRtv|>S6PxiH zb#tuGC$TJ9RS8YEuS;{EuW(5SXUws|N-jH@Fhkpsayek&A&3nl(D51JAWEZ$e7{g- zLEl2f*+MzzWNO`lCY=~PaLS&8><8J&H; ztSjak$q!#Jks6&`YTW2JcgcwiphwZAvF*96=*87n=W8EJ#&-=DZ=W910EZT*I!qHY)Fy9&3XBg_aw-(B8i|0b08_aUOH>aKO_Ink5-*^}K4b0*f6i7b z#oZvNvWf$V`a((I6DXkyDf+^c30gRb>utm;-iEei)}LCk{~|G7dBXrhL@<1Xfy?Sbx5B<4eOeN-SWx@=9Q``!9FQa_>)5MIW?L}d?!fq*d(-`x$md9Z$0CvGkU_4(bnYh+ zt}Ypv0i_IW2w&cg3#8c34IDZP{t+dGLq|d{48`OwTIco)G!pv5qEsNikqHRrdjisj@XE+jc`cuZKCcQOAQuJLdC-h16>LU2_X>>(Cw6Z3keI!SI=Za z?E?8F+i{)O+yf4M5q$WXJYK?{VA?tm8!f$;te!z(ze$o_%Wgx$DqOMj{kN6KqtXGf z$2J&>5@FNv4XvF%b7hR>Jtx4q~zB+ zW^)vn-p9??E9t2#3J);Q1T(OVe)eq->}(GVCxYxCo3=L`@!V(wW5_^I$N}>KX%s%p zwiEe!E&tj;y4gSg$KeRx9N`kOAv?J1_I)~uV8vhiK5xuLCSWf0i8V>tyj>v3ic~Jc zF#}e>e|{6q5T$EFTmFUz{}VNF^U76bshadKI5OgL^*iUGwXYEw=+;3gYvN`J_2@(f z!qa9B>ST_1Yt6#n8;Aiw0?1bxBx4{0?oxy_+Y&=wCWnmJgk|T2pZohkCQm?9G7=_= zZ;4s#6_*>Wng$h~pf#)@N<#QRrQ<)=k+b@px%uFxM;M8RZI`6dtCV&Mf2W!g40vKD zOQPtrY9eJ6#7(8sScqG_zKfgMu4=>AtMH32jkp!f&naIEm>cOfylaYQXM5N6{(i3T0HcW=KFwIh%~^#*iT8Te)5K_7VV%pU#})3007u? z+x%p(7apB0p1?b(nsEd5%nVi2d z+n0Z>lM^r7BK05Aj207*t`%Z?OAQV%l@pC-XA{^Is1Ot>Yx+Q7#B%v_p}=q`wyY)9 z87DYzGygyy6>R(VEO=^rBuejQJ-EpA2gAs>N-X;9T#j+RS@;}lrQW?%KJo=mT!eV{ z-h{#K0ofiRlJR5d zg#x=vXc=+muSJYSJq%UIV|P<1k^+sTRw4iB?%$dAzmm&|c&k_x z72EvjQo~I+!}Tz5E+SDUK9NXh2kQp`XE$Fs2tsPT( zH@!e<VfC#FF2?TzZ6= z!dsk>0{BNgorr(q@}&lUnX{{XFt9NCF5HT0Yf+if5ul);Xk2)A+&opZv|vS1NygYD zWJ4In5-4%O_ychRf`sWm&pPZxg*A>l+TC55;1iv!8y=aVxD%a*8c(<%H#lp2>-eJy z+p9d4z7n(hM%%Mp$v_f|><=|hFwa%#EG^6As@htX7TxOZCYTx(CnqNWATlyCFnGmt zU{(bc06P!|GqQ!V&Ixu3o_`!PZaPbScgmEy&G9MgBa6^#oK{G-X(Bm=*@W~B@V(f7 zN+bM>*tiKi>AyF(fuY~HsSnuDyXzn_G7^X>vhs?gOec)}C;O%JS{MJHgk*us$!tVi zoRoqBqOsLt$i*?K*5X$b43(l(rnycZm8?TZsA!s*goK3Q$?P8-em4dpU-bv7cl!*B z_YxVfL*`EYfr^l8(_m{C4#n5ftZn+7UV z+%3JCsRm2)1#*aOGyE_DgH*f*%hmLPywda1sJCS5d<{P zu9SWJZhzo~rJ$+wZli@*Ah3GkP%Xq2{} z7HpY_n;jC18HuGSsmKR2(t#}!0yoclJTCjNlR5n1@9#bm($Z)ArI)znU(S*$7+Mpj zTJJm0B>lK(=5zjo!aDW=5C=%PEnp&-rnghe{@%!&mTs^{akCkqt;^GttB9~4UZs2C zR2dUiTlk&K=7d&}Lv(I~a|>QzfV7;`z~Tj%0xuWw;V8(8mAK#U4O-4GdNG!c-^`OV zMUw#5u7`Fhuuv?hG6~X!g^|hyuRD^7v`qia}r#*Ok8WcThV8Y(txM z{I_u`dOOpLfy?C@mc| z|00U{=Y4Q-&_BJ0>jON8R>{|~f)l^HgHa{-qW{cFwp!C+`eQ#(y<9W%xD)>$BDIOq zGIBCn#9XyiU)s219p?L`E-BL&Lzw=Y5jEcKHlKJ%f7(u^kiD`1YWcOHY}#Byj7q78)4;M|;zCA=X)$nV zG4!+{T#=8ez*P|u!Sz!2m?C$~n@UPWFhXLhHt+bHdUb3X5*dPH5&1zS#>sh9^(x2| zf@gvgJffb*=Y&Tk#_#SpO_6nO)6u1rW4df1PH{2_-%&veG(k%zr{(vg2ii4dA02Z3 zPYZCk{iTugTQH(gLxe&-U?vRkSNDBk0A)IB0yv(@4g;EYhb0w*6Zo?M_+cyP z@d5v|+GOp}z5$Db^g}6$g^orzztGDMB4`R`#47l1U&VAHFM2w+)2Lh%Ws*ERvHg}h zfK07{MqJv;b$q8d(z~$1zn1ztP0r&_Ke1+Z* zFz&w86{tuAz-iP47YU7w98zc@)Qrgpj7S~SOCj4=5VI!2rkxIYqOlE8qD8cFq>ZQ- zs&2Wm%U=!A&OhLAd1;)goK5XQcyq^ zAj1&s?7&uNBVA4ji)x+VsN;R1ohQMzJA!?TO^MuLi44&7q{#N%F$0itne5drSzB9MBch_jQt5sqq@_K=XnuOKf@+Tp5WyYMA9y{QYBVw& zz{yUiqQtGzDa>g|!oh%8;Ktu)Y>aB$(EIlBEhIfos{Gk+_2b6 ze36F`2o3!j<9?+VuSuvN{?^2ZfPzA;Zy-sJ3#>fp6u|?Nlfemj7udI5h4tPmHgw^D zjK_xZcJEiMz)Gogh#*2Sl?}3K5=ZTH$m2&*OQlPw(ufes^E3FV`q0=sU3NP0g*A;Q zlF4S4kdqV3sPi`;)beUESB&I#xgPmnwG5h!j0y?%$PecGv~NK6$r<7Q_7SnuUuS$E zXKHS~wvHlHN9-D`#RDRFuP5uQB654?V`;mwwP&~sUsCe8_DL27G$_CLh5>_gM zZNB?VpM7lE-F^wwX`xZc!$P6{Xrhzb&_p+?4*|8PNuM34Cq*U6 z9sC-y-Q=kN;DkIwuKk=BhK+7~#FBS!>#O;47MJw>S?4?<*xb0%so&SP3@kRubEC zGdMnq%l#r$68;32Pzjj;B7nO;{hRD*okzmiG{v{Ug5lEjBlgUdxVNhnNT_LT89Lid zt||0+?mt$4Qv>v@Mi*_TBFx;4gueRT3DRbGJ`*2*&Etiv6xMEQQG-AdTw|ht9tG!B zwAV(HKqH4ZO8X#hD0STSSnrBjf@hSZXqyi!=RB?;ws~7@RSMMa5{&lU9V&H1Ytn!@ zP9lO4FN#5=IHKCM*cvo<8>~q4vIcuo^e;7XFn-lg6gvc(6?1I0YZsy%NHR3xFtGck zCOG|3_p=mt4u|&=@;?yuJ^hM_N^HtkUKFvO=znyvhpk6|$bH2Gh=k_LhOPXbl^z#d zB&xb34sA;{2oi&vL*Wn|dz0QND;JFN;I6nL>Ml8bNqNxn^n)!=_k$0{s|sH+g#&lz z)_Z}~WN+>_iWR$h9Ye!aEy&R!3Lj6tINxx zerIJ?k}6=z%fNEZhDkIh%n_AR7Dw(df2nZwcPy#R@b?~5*Mvx#v=Q(Tz{aL$R-7K-hIvo z4Th92`UCEr5wflmin2cQps&{W10y6~R6o*e04*5;FtNYp#otcdm&JZaY)V;&6mbP4 z2&aBZtdi-Dw4ik6!g@^M@e0PS=kg^0wLGvsWRf69ft5U*kSM8^!O~+cB7xKhg*Y-- z1`=4EibsS$FoyA-tY+-LN{$_cHA}y6WIa0dJM}(HIzR$yka(Jx$nV+c<9TaBu3Cq1 z0w{1hoYT2;MQ2tRSpFmMXszr^{6b`}BrvV&lQVR^0loAGI?lr;amhwAOfKaXsmr4P z3ESzVWkW*%n;9vAP(a6vvx?iLSO&S=3181u>jkm7A2ZzEG94X-QN6YisHXX8j}rXQ z8?NlNEHmusSw1t0;%A|c2QaMHj<%ioJq44zpPbdaAz zThL2%SsIzEdKqU z2qZ%HsN>TD6HVr=rPW+n6QH4s&3l3`PZ28r*WOn?#SwmM4({#}2AANjgG+D-?h-s$ z&|rf*gy8PM-Q9wP;K7~Xu7N>^onPI(cWeKG{j#U}Q+IWruJ?4kNBViraY^GaAqQ|- zU70&>K8dPPN+1I=L~Zy~CXFQZxo|9CTiX__#sNz`B9=8zdY>&i-Ozen`lRAJwgz~; ziO;yLHN4KAgO)I2Cw2Y(D(BFa%G+?EvrPQ~kgX2az8VCjNQA*HWXi%ozE{x}E%Bk&J(yzqPOkZWe7TYNQR}F0pW0Cq3GDyMRDX+zVWQ z=0|IR##0h>z;6g??2C_%*K<7EK-J*cOA_UiM{_o5@jQUmlIT1|(C0b%WvU9KQyCnY z>#y3O*~3Mrv(%gJiqfkJyB79Om}fPnL7bc@Ar`gNsPMAMXi3sP0&ZxkRkH?G+gZY3 zQ|=ii&_cu;F@@<7SH}Ay9~+pcqiNUEIR{p&g=N!~drZ^*sw#(5KTs>kO8xVt{*dGl zMHsdN;|Zg=S5KWcT}5cw)b6&6{wMtm8}@%Ba!0=)xJ zv!I`m3%WzX-7}Mbafo<@&v16I=e_e>i*K6`Bq-WbufT(TJN2T(mCLw`7ET zNv$PbNPph|HF{-i3j!1XLFdktI~a#WA1hD`yqwI>p3CoBPTuL=LZ9z^ZLO>d``^gPfKa7aWvkaVCz@t{hIGe<3u-ATB`|? z4yJvnKe?^HxDom;%VOlS&LI>hj-`i~x`irTDFXG%JS=xfp_B6{%7ur>8ILd zvi8Il6ai(#P6+`m1aFo;*Q?qpQOvD<85+}6HvIP1OR z&srdjd(ttzcR8Q$-vBTSCneX>E)hkxWuI#e=+*c`!8|t?wL+o*T`knj@-A6cy`UQ& zc6K5FuI6G0-NgzjfBNibgC=yX-vkh$(G`e*7E}GT8l%l5-%^N#5^LsRjeYM#6QhDK z!K1RQ?5&+RQAanXgdhAo?#|#uQFd0VETvs6MI7tFth~zP8h^bhK4wx~3yrFHOFlY< zHYa&Wym2d{K?B; z4@n}MA7bcxiuC>0eR}?V6@wj8qj8^fW@w99>2pW1xeJv=(Va<%&c#Q*R3_;3iLbPT z{=EAf*b7%{^2z4V>j&}hgBfFAO_}#Yf1p#|o6<^C@)XqNB(MZVfb)*LvH5qbIDL^z zzYsMm|GEq04WZWfv3MCGnXsmsXtiS$n$cuU$B<;2&N|ZvqZcR^Q7giD1d+AMB=b-r zM37leLW|v@yYhKt69+M{IyB&;_UO!v9_aU|EA*=HBp>7O zmv=;J3Q|Ci-*=Mf#I@F$+r@&et(n75z7Ue*jYgJo%*LYfT^)_$4qLXI(FYjUoq^>$ zT!6MV2^u_-<`2ons}rJtoLF%)?tt zlG?%RO%oMMFATDzaxtr#pgl=Do$PTxzp?i6CXaZXFjxH`alYZ5L8!BceAQMdqH0Cz zCJ@|SPF+RnZDK+sF<8sY%!qjuV^5UgxxjC!i^)uDDQQAv!W9}45))DYPkSV^hnbuq z_U?VoWx`2iMcy%$B(D9zD`;A5ZbQe!fj*n(L&)O~ zxom+y0!#`b2yU)@bUz^CCj0egj>6Y47WG?2+3zjry`V5;-F-hvnIjPf#~q8pquZMj zz4)$>Pfl0N*`+;_<5r~7?N+YRX_KLn`>ZOR4di!7`FFCQT&kYWK|6UWsNC7erfk`e z5fwF&b!Q;$$HLJNsCVi+pZk_7a%`}wdMvgxG(jbZ3bR<-R>n@ zL%L4wGt-1vd3vs-Iv`C5B^-u-IYxcX%T1YZ0#@`6sx!AaPD?J4$LB-3HlDEpC4^23 zvo(Dj?={_~Z8xm7_VK*~MO-E?7yD?`r-V(Zasz(6d=#q!ciMM6uY)H{O%2WsJD!_f zt*=WVJJ}ZeP$zzR`fN) z;p3Z;n6x~2-cUDf`7qy=o^94n`{d-TeYyS1G&7}Rt>?B=&qK$Lx`str zzCb+^Zn^I+f1QUNf-#W6kdUS#bo}Csik9ts#6r4PH4J&t}x!gWL#= zr|z&RcHgdwyQICC+PS^65a=}rM1w*V(pdL?>RGk=P#~+l^689T6oZSc zc+AHeg{cWAD0`!7NCDNR)r{75E6T*5Jjym%p!3o`^1?mKf#f=lkQIOAz#XMvp&SM8 zB!E74v)QuiH8%n74UM(K(W!Z2&E^YD^!@YyYg?EN*F{+lFU;dzO1V5<{L#RP>9 zE32~Ttnk@FH?8`+MKj-UbVhlDu(38l8*G`M(M~;Tx~=fgn-y1V{ipz#8&` z;yW;HCvp7lxdn7vVmR#tZqYv3Qcq-v)$}@@wBv;`Ac}Yf+mqfgG|H}vBs12JJNU;k z#j1Z~)4G1dHPS_`3GjPxGg=?6-5*D=E!9O=;H0y?X}F)}suy zHtr5(YohXvJ4g4S*aAg2=F8M_V|b_PdFk_k5>y(5h@nzewl=g?o<>&Iw$%Ph=f5Og zP(8@S@yP&F<|B)CVbKCNd8qR{yDSPr@JEzSCqN;o<9XNxa3@17o-fZ8EI!c z-vvtoV3^X80;$k-dmSB}Ut?npgFWb6Jy$Ry#njJwItgi5`8vxEE${JwFvt5y=qx)h zWi1!@LF@uZ^nz02$@;~mnQ1a{~^dsO^GUh*f4Z>PZ903IQZKW!2up3qEI;DGArBtpv5gszr~-E{yL%$3YAv~jAP+T+YWTsL+#R8#_FZ~|F-FWDs< z`Vcslh0uU6FD}O36Sj8Ao^(e)WHVp6NR1zeE zkuiuv9B^lX+DJBnQuoa)hQ655k^YJcT$%%XD0UxJx4zs7lrW1Qe|ja^2w`Gynp6Mg zgFom(`YkW;_s}w=PS&LZtH!8BCbpZnoVm?!h;I#!I`9Vf^uBJ5+J(J$q{lFk zjjk0coL5byrS3ayceq$F;8snT;IiAX$u|J>4pnS?q^?*-5IC+PHthO5bYJ0-9`kJ2?QeQ=sIrOx<~3f>no` z*|>MfbaY($ScV1Pc>fBI`F;_aR&G5DbHDJSG+J%y$egGB_&8F9&%%PIB|Bj!`%l#? zBDyVras8f+Y2o>|gX@};Xxe^j?vc8(mCV~NL#IP3$cf@y+1KlTk{ zqHUo3Pq*^X#$UgEuus}_0|qkV$Iow>waL>SV&SedHe7dO^$5yY{cIl^U93qwDj|sy zGSF2AG2ZlV#OJSlw~p~#`&D{q(AYjJGt%eW+;pRrDXvCTeEIR4~A2G4X5(D`bv~tzW=j%b@&FmjPIa#Z}PmsOZW6%#qV-{N4zaLDx1wYEF zh>{sHg8ibqZ_ceRd?(FbJJ&^v(@8s7EMsJ8Eu!Vmw&-IQ1E}BpIknIQ0y$`D6YX+k zY40DKJ6okMvS*D--)=Ixs@q7g($U9S z3%$KhEm?3W$vMo9LD_p%O?O$kQTik?=A;ElMdPhYGb64`PY};xBw!Td#1Xp+iX-Kg zM#dtiFUtpa!muMNAibXJgHu{dlDc2xFhn43M4gL~X%AMRUg-$Pe17fbmj(mc<8 zFFo{>{8qblzIAEg^j-j~q%Cx}Q36-Ls3DhD+DA>~$7Xq#72L@bZ`iB0B$&;mvEh}+ zz_aG1b~c@J{%zT9Ik<0D`4jfKS2Gv;bS5E4=dg>M;mMEcb=fibdTAnV?(%tfxolga zoTO1rjKw05&oDu#_bodzVpN}Pd=mHbd~B(djn{9?^9Mn>$4Y`3@3X<@83PWwx$>F%+Ew^Y_cn*jk4>>#7$xh|?MBP~#MYm4c<7`)Dc z#@(vyLzlP0h~{W#=0cy>76V8=FF>&`U;7dmi5CkO4B!I{x4mJ^=7VKNy(NN60co{s zqZ)90Ix_n|mNZ500-6KQo&2osBUb9KCvI<;6zC3LF#ftM^@7Q;qL)|phUGNe+zZ2b z%u9|Y>C%w$w-T;yq*FHksqaa=AoAcmh2~o9TSY(mJLjdtQ+Iabmb`W1Jwn98CS-iO zZUu}{f^)GhZJO&a|i06$~IGlNxw_#-SSW0{T?L> z_V?OPx1rkKrmI|5;))7MWPVyS`#`O&C}$9C8ZiUM8~so!&`)f@$jl)*1nLcbEItn} zVD0Hw@_oogcq?ajjQOY<*Uq^T=HRCDIDCkdc3c4Zz~D2@^RHqWfHr-czPV8g{<6#4 zh|^Cx;#dn90_kBt-AqGYKWaZbd|BHtf*qrGurx+VTQK7-SzTP}4f?tP>&Y9?SQaq) zqtpjw$lZ_Z1pXoD@Gu8MYxc`s;$97w8?O=X922_Zu(*k~ntO|wPA57GQo-Jknx5_V{piS>*Jpip07O=^S$R5>N)H=TDhl3tq$Al z2Gn=hu#^&QMyHXP;Bi-d8KCh}y*;jyFJ#n>lV}zu+j9I$mJV??9$nS6WdGUxv+K*I z)F*DwyFgdjLyXylK)2#YHp0IP`!cS+5YbuWC=5z@007rjQC3QOw1`+@cVpr0r`$6* z#cf4GHg9CHb3usv?fQX^;`*S|La6UFGX5aG08m#=8Zv+)7E3HtH2bejFfU%hlRN@j z2nkTn#Y1lG`PtPCI>%zRg*O7<-Drb~d~qveSR5Eyk^0c=K+l8l`0Kt++Qn&4Agz^% zKrbiulZaV3RiRXTX(xyP6Ctf)JG7*2H@(QfF5ia>x_HYC>w526O)%-8<`>sZLE5o*&5T z)f)1qgnz%vw07`GSoBtLf$0A)$)$E}2}lE2Ti zWiYl{Tl8XZ)JjU?x(FE8szsA@97{l@aD<-F@A$pF0=nDz&)3R-=RvqLK zs%K-)LJk-dAv6PX-^g#qR41#~0L!uB$L0A~x61np&Qs2!iHQsLo~mXKqHS@{JYmsQ zfn8pK5F&cY(5=#o7{}&EbK37;sW*94yNu;udf^?-3W_`NJ(bf6Zu&#(E%udCoHk-w zJ}>RSYD-egggZWL@djxi(!5gp^78Wjekp`6U$^M4X9gjkzz^c2ngb0!-tD)XSbb3o z`&+vc-*!K8xcfMwgW0m;+&jCE#dX7hSJ$1ILUpHvkcR147lnzKg23n5>t}D8@`Ig> zMZpq%H^SsJlW*M`wzB^ma$4S+E(j6!^-ZA+Hg&#Kp?<28u^LR;OWFf7>_e8CL;pz4 zE0^nA09xQ~G$xNOGFIh-;>K3QvUjdHF_n5W#PL!~o>55JaxvGBG2BNt09 zJjSBx2;MtR8Gu1~Ov*4qX>@2GMJHTT43V`Noy|g_-r8Fze6X_|901M?IW65kI*1da zQ!`Rv1@t|C0qd{6a1Pvcj+aFiBb!Nmr6W~Q1M|I$4}9f`67C$`MSoL-Mf)4phOB;F za0$X)dZw2uT8&xpn)n8+qbm7CwjfTS1}bb^*O#^$;k>&0Re;ND0wTZ;jN;|JoXJK~ z1kx;)jC$QRCGc2I=JV9#_vQ&Nw%!ELb-1HceCFHlymUVVstqW8QrlnO zMB@COaUIvQORM*Lcj8jc4|M4_f^{_fSyeAC0Dl%pT)YvMPH-4+wj5WZAF*R0GwZdk zjOuZj=Q==e)h&1?dQHU=RLSUKBzp7OEzX5?bh=1A;{+7U7GHot05TYcuUhQa>^4gm zWi-!4QcBv^5&7$oZd`hJ8(P7kvCdQXjBBIcwDTbq91~rjvX3exb7AzyC4XPVKi)zK zhtR?D(7wy%gL@`p?bx>Hu)DcW%;aw3H_n|%WRZ|iePqIg^e0l^X;wwwKn99X_$l%G zD{&6BS7#l$nM;ND6&&;$Pg!qw@GqBLqMB7C7BhwFgWnAwUdWYBbuAB0MqTd*5@3;b zZI1xn4p9tpn7;w@IuFGh7>rwX;f-U6gfp~w;u#g@*$vr!ca*mVJm+~TDC#7w zf?PW2qO);A$v2Gh5J9EIjK<;m6WHzYmUtQ57$pmzEl7!nuB4Iy zL;vU~tK#ZBf9~5VeS!u73nfu~49+zu4d7G}L|V__@`0#`(x}KGsE7!ti11gB{LN!4 zB%eR`%FC|B?c#J}`mo>5!rFi!!owMZANLhGO$8MERD;r^?DRgYm)l)kEm!Ns~)7=iTYNR1UqaOjca2RTBsKHNUqlngO48}9u_<|$-`pvCL zFB_BCk|aI#_CBM5t?M)}X5SC!9um4{NaEt!{Bq2M_vlO|(k;SbA@NFlnON%UNPoVt z-3^X$xZb ze_dte3}5_VV^7$e6UZ@zW^U^VVw$^^VWK}ml`)}2T0j5jV%ubR4bgoS{wZ2uz%%8i z8I1h+u1U`uMNacSh@t9gHbh?7fCnV#cO(WGh0EI4#Kd!j*mW_hL#tw)*wz_o#sfzm z%E04CoPR5a+IDaR1Lnxmg}5OD)c)c?csL3FEF7N>_Up;crK`z^Yf`s|al72vo-xl% zLoYlvmpkepj`-5!PHYBnp3BrBEArRqsQ-u;o**?zZPV$LjkO>)TNZK*CskZ^aA>0Y zy`*S+B{LdXX_pg-y$kH2Rr0ZwDYUg>2^X;7(j8MhHx-t)bR&p$;hg^NNO9Y_tL>Xl zsN?oK@FOArZ0_B1F21S6CUQ^k);ZeVT;6me8!BQ}W#Qs#R6y51>9Nw^DYwu5;xOP7 z9UUD)W@hHEX{T8HSEdYnsU>0sI`XOr{rA#_9BHZk(QIZEhzn_`%$dvjkGvkdG2N1| zVQtYtS)q3@#5A^*OgOOAzSBvWjk??#w(-H^Aw^i6jr80Yp~6K00RCCP%F_PBTd6s| zhga}(QM6g8*)0uc6@k)VIBIt4QQ8(oOiY+hfH+WF$MenBcJI^vA}4iBbf{<^w#>=) zoIfgJh=#d^#VkGL;{K(+5ibf#vnW1j6^Js)iHa=a9JKHV#62J zHsh~?t_?8{4^P(mPeI+haH(er1PKwrtX44*G9w3!tFjl-Br#siFOJ-%W*$hjLND+3 z?4qTN@Ph3#uk6LEIbNv@?b58pA_>>Q<+`Z|6{d6C#0)tJHm$i zG}?Jcf~wcu76o5wVh;9NXVv&0C)Tcvqc$r8cpaVk?PodtCTF5fuj81rGs^CUJ)VEZ zZpdn|aXhlIG^EW4!J7h)vk|AR#)qtlk((EvB=l4Ue#R$%(d6tRzAR!-zMAZeZhuKg z#{F{x0L-CZ%E^62;5fSVmv&uhR6z`&VOtSeF|K4&DAo-ZAc_^?JU`G#E-^hdl^XVp&2PFYt4Y{q)8f8`Mk|fiJaH5! zmtDFI0}k)(^wv?cE~BRn0pz4wC4kDxr8~RU-hW}I3*0wpW*9K@58Ok)ZvyrrRxhu> z10OKO9Vrd%QJj{ppBrBUUOM)`Th1H5%r;t53k>?}L) z%DOJ6bm}WZ?ME@}&({fz`Ip#FBskSh6)gRqV>y1dCB^i|1KsZQaB`FXGV5R z`yHl#b~T*t!joS6F&=Nhy2;XxCuN3>>;ddbHhMIw8fpis4ff0ANl~2F%WGj&i3gcs zSoBqEWf?1dd0^`9czB=l8aX=4&}LSAyt&;((5O|oLS)S+DToR1`o4-!Kvt-dqFX!o z;DWM!QY<2L)?eI zkvj z%CUwS<4+S{!#3oxq0&QKoVguoiSiB&9*S!jfn5_#-rk2Y&Vz@F*x+%?R37Iz((r5w z8<+z(ea}2o@ObuWLrz@4XBrsXU-o#ldw@fe7QLA}6=HwnT)<~Q&3Da>6cqjBu;G>a zSEL926RbFjfDNWZX%)vyBh?_<;uv$Qk%-KmsS!a85XMz5C|CN^2pV(tOHUO7dHNK* zW1*83_#d;=A&W*ILAJ57g!fU-BGKyK<=NWg{ye+Bk0s#(3p= zPWzO7niN5Gml}jfY1TNMrIm&!PFHNBECJv7{P=5+dAMO&etoSQ&0@;ra6Y7qBk%bA zMeKRZGzn9|sbdp1gy;nU{Sc0>S;=c_hD?9n?8{*8_nNe32SnArt zzwNIo=CLTZh49pQ#JCc1fd{g`QRAbGKG#gwAfW5Hr|}T!8b)mQ@VnptW>t5A%JktZ zAlHNp(ZOD r58?k=CRthg7&z1auP*BU@nS-OaGOMlLbno~0GKGssmaz#n}_@_`vYr{ diff --git a/docs/algorithms/Two-Pointers/Max_Distance.md b/docs/algorithms/Two-Pointers/Max_Distance.md deleted file mode 100644 index 8e71d7ab3..000000000 --- a/docs/algorithms/Two-Pointers/Max_Distance.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: practice-problems-on-two-pointers -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 3 -description: Here are some practice problems for the Two Pointers technique, including an implementation to find the maximum distance between two elements with a specific condition. -tags: [DSA, algorithms, two pointers] ---- - -## Problem: Max Distance with Two Pointers (C++) - -### Problem Statement: -Given an array `arr[]` of `N` positive integers, find the maximum value of `j - i` such that `arr[i] <= arr[j]`. The goal is to maximize the distance between the indices while ensuring the condition `arr[i] <= arr[j]` holds. - -### Approach: -This problem can be solved efficiently using the Two-Pointer Technique along with two auxiliary arrays: - - - `LMin[]`: Stores the minimum value from the start of the array up to index `i`. - - `RMax[]`: Stores the maximum value from index `j` to the end of the array. - -### Solution in C++: - -```cpp -#include -#include -#include // For std::max and std::min - -using namespace std; - -/* Utility Functions to get max and minimum of two integers */ -int max(int x, int y) { - return x > y ? x : y; -} - -int min(int x, int y) { - return x < y ? x : y; -} - -/* For a given array arr[], returns the maximum j – i such that arr[j] >= arr[i] */ -int maxIndexDiff(vector& arr, int n) { - int maxDiff; - int i, j; - - // Initialize auxiliary arrays - vector LMin(n); - vector RMax(n); - - /* Construct LMin[] such that LMin[i] stores the minimum value - from (arr[0], arr[1], ... arr[i]) */ - LMin[0] = arr[0]; - for (i = 1; i < n; ++i) - LMin[i] = min(arr[i], LMin[i - 1]); - - /* Construct RMax[] such that RMax[j] stores the maximum value - from (arr[j], arr[j+1], ... arr[n-1]) */ - RMax[n - 1] = arr[n - 1]; - for (j = n - 2; j >= 0; --j) - RMax[j] = max(arr[j], RMax[j + 1]); - - /* Traverse both arrays from left to right to find optimum j - i */ - i = 0, j = 0, maxDiff = -1; - while (j < n && i < n) { - if (LMin[i] <= RMax[j]) { - maxDiff = max(maxDiff, j - i); - j = j + 1; - } else { - i = i + 1; - } - } - - return maxDiff; -} - -/* Driver program to test above functions */ -int main() { - vector arr = { 9, 2, 3, 4, 5, 6, 7, 8, 18, 0 }; - int n = arr.size(); - int maxDiff = maxIndexDiff(arr, n); - cout << "\nMaximum distance: " << maxDiff << endl; - return 0; -} -``` diff --git a/docs/algorithms/Two-Pointers/Problem-Practice.md b/docs/algorithms/Two-Pointers/Problem-Practice.md deleted file mode 100644 index 58c6f56d7..000000000 --- a/docs/algorithms/Two-Pointers/Problem-Practice.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -id: Practice-Problems-on-two-pointers -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 3 -description: Here are some practice problems for the Two Pointers technique, divided into topic-wise and difficulty-wise categories. -tags: [DSA, algorithms, two pointers] ---- - -### Basic Two Pointers Problems: - -- [Two Sum](https://leetcode.com/problems/two-sum/) -- [3Sum](https://leetcode.com/problems/3sum/) -- [Container With Most Water](https://leetcode.com/problems/container-with-most-water/) -- [Remove Duplicates from Sorted Array](https://leetcode.com/problems/remove-duplicates-from-sorted-array/) -- [Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) - -### Advanced Two Pointers Problems: - -- [Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/) -- [Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) -- [Pair Sum in an Array](https://leetcode.com/problems/pair-sum-in-an-array/) -- [Minimum Size Subarray Sum](https://leetcode.com/problems/minimum-size-subarray-sum/) - -### Sliding Window with Two Pointers: - -- [Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) -- [Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) -- [Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) -- [Subarray Product Less Than K](https://leetcode.com/problems/subarray-product-less-than-k/) - -### Challenges: - -- [Maximum Area of Island](https://leetcode.com/problems/maximum-area-of-island/) -- [Find First and Last Position of Element in Sorted Array](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/) diff --git a/docs/algorithms/Two-Pointers/_category_.json b/docs/algorithms/Two-Pointers/_category_.json deleted file mode 100644 index 5195469a6..000000000 --- a/docs/algorithms/Two-Pointers/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Two Pointers Algorithms", - "position": 7, - "link": { - "type": "generated-index", - "description": "In this blog post, we'll explore the Two Pointers Algorithm, an efficient technique for solving problems related to arrays or strings." - } -} \ No newline at end of file diff --git a/docs/algorithms/Two-Pointers/imp-of-two-pointers.md b/docs/algorithms/Two-Pointers/imp-of-two-pointers.md deleted file mode 100644 index 0848a8416..000000000 --- a/docs/algorithms/Two-Pointers/imp-of-two-pointers.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: importance-of-two-pointers -sidebar_position: 2 -title: Importance of Two Pointers Technique -sidebar_label: Importance of Two Pointers -description: "The Two Pointers technique is an efficient algorithmic strategy used to solve various problems involving arrays or lists by utilizing two indices." -tags: [Algorithms, Two Pointers, Competitive Programming] ---- - -### Importance of Two Pointers Technique - -The Two Pointers technique is a powerful algorithmic approach widely used in computer science and programming. This method utilizes two indices, known as pointers, that traverse data structures simultaneously or at different speeds to optimize problem-solving. Below are key areas highlighting the importance of the Two Pointers technique: - -1. **Efficiency**: - - The Two Pointers technique allows for linear traversal of data structures, which significantly reduces the time complexity of algorithms by eliminating the need for nested loops in many scenarios. - -2. **Memory Optimization**: - - This technique is memory-efficient as it utilizes only a constant amount of space (a few pointers), reducing overhead compared to approaches requiring additional data structures like arrays or hash maps. - -3. **Simplifying Problem Logic**: - - The Two Pointers technique often simplifies the implementation of algorithms, making it easier to understand and maintain. It is particularly effective for problems involving pair searches or subarray manipulations. - -4. **Versatility**: - - This approach can be applied to various problems, including searching, sorting, and manipulating arrays or linked lists, establishing it as a fundamental technique in algorithm design. - -### Common Applications of Two Pointers - -1. **Pair Sum Problems**: - - Efficiently finding two numbers in a sorted array that sum up to a target value can be accomplished using the Two Pointers technique. - -2. **Sorting Problems**: - - Problems such as the Dutch National Flag problem leverage the Two Pointers approach to partition arrays based on specific conditions. - -3. **Subarray Problems**: - - Problems that require finding the longest or shortest subarrays with particular properties can be effectively solved using this technique. - -4. **Merging and Comparing**: - - The Two Pointers technique is commonly employed in algorithms for merging two sorted arrays or finding intersections between lists. - -### Example of Two Pointers Technique - -#### Problem: Two Sum in a Sorted Array - -**Example Implementation**: - -```python -def two_sum(arr, target): - left, right = 0, len(arr) - 1 - while left < right: - current_sum = arr[left] + arr[right] - if current_sum == target: - return (left, right) - elif current_sum < target: - left += 1 # Move the left pointer to the right - else: - right -= 1 # Move the right pointer to the left - return None - -# Example usage -arr = [1, 2, 3, 4, 6] -target = 6 -print(two_sum(arr, target)) # Output: (1, 3) since arr[1] + arr[3] = 2 + 4 = 6 -``` - -### Conclusion -The Two Pointers technique is an essential and efficient method in algorithm design that simplifies problem-solving in arrays and lists. By mastering this technique, programmers can optimize their solutions and enhance both performance and clarity in their code. Understanding when and how to apply the Two Pointers technique is crucial for effectively tackling various problems in competitive programming and real-world applications. \ No newline at end of file diff --git a/docs/algorithms/Two-Pointers/introduction-to-two-pointers.md b/docs/algorithms/Two-Pointers/introduction-to-two-pointers.md deleted file mode 100644 index 7de030bf6..000000000 --- a/docs/algorithms/Two-Pointers/introduction-to-two-pointers.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -id: two-pointers -title: Two Pointers Algorithm -sidebar_label: What is Two Pointers Algorithm? -sidebar_position: 1 -description: "In this blog post, we'll explore the Two Pointers Algorithm, an efficient technique for solving problems related to arrays or strings." -tags: [dsa, algorithms, two pointers] ---- - -## Two Pointers Algorithm - -![alt text](IntroductionToTwoPointers.png) - -### Definition: -The **Two Pointers** technique is a widely used algorithmic pattern that utilizes two pointers (or indices) to traverse a data structure, usually an array or a string. This approach is particularly useful for problems that require searching, comparing, or modifying elements based on specific conditions. - -### Characteristics: - -- **Pointer Definition**: - - Two pointers can start at different positions in the data structure and move towards each other (or in the same direction) based on the problem requirements. - -- **Efficiency**: - - The Two Pointers technique helps to reduce the time complexity by avoiding nested loops, which can lead to inefficient solutions. By incrementing or decrementing pointers based on certain conditions, we can often achieve a linear time complexity. - -- **Types of Two Pointers**: - - **Moving Inward**: Both pointers move towards each other (e.g., finding a pair that sums to a target). - - **Moving Outward**: Both pointers move in the same direction (e.g., finding subarrays or substrings). - -### Common Use Cases: - -- **Finding pairs in an array that sum to a target**. -- **Reversing a string**. -- **Merging two sorted arrays**. -- **Finding the longest substring with at most K distinct characters**. - -### Time Complexity: -- **O(n)**, where n is the size of the array or string. The two pointers ensure that we traverse the data structure only once. - -### Space Complexity: -- **O(1)**, as the approach typically uses a constant amount of extra space regardless of the input size. - -### C++ Implementation (Finding a Pair with a Given Sum): - -Let's take the example of finding two numbers in a sorted array that add up to a target sum. - -```cpp -#include -#include -using namespace std; - -pair findPairWithSum(const vector& arr, int target) { - int left = 0; - int right = arr.size() - 1; - - while (left < right) { - int current_sum = arr[left] + arr[right]; - - if (current_sum == target) { - return {arr[left], arr[right]}; // Pair found - } else if (current_sum < target) { - left++; // Move left pointer right to increase sum - } else { - right--; // Move right pointer left to decrease sum - } - } - - return {-1, -1}; // No pair found -} - -int main() { - vector arr = {1, 2, 3, 4, 6}; - int target = 5; - - pair result = findPairWithSum(arr, target); - if (result.first != -1) { - cout << "Pair found: " << result.first << ", " << result.second << endl; - } else { - cout << "No pair found." << endl; - } - - return 0; -} -``` - -### Explanation: -In this example, the `while` loop continues until the two pointers meet. -The sum of the elements at the two pointers is compared to the target. If they match, the pair is returned. If the current sum is less than the target, the left pointer is moved to the right to increase the sum. If the current sum is greater than the target, the right pointer is moved to the left to decrease the sum. -This ensures that we check each pair only once, resulting in an overall time complexity of **O(n)**. - -### Summary: -The Two Pointers technique is a versatile approach that optimizes many problems involving arrays and strings. By leveraging two pointers, we can reduce the time complexity from **O(n²)** (for nested loops) to **O(n)**, making our solutions more efficient and scalable. diff --git a/docs/algorithms/Yolo-Object-detection-ML-Algorithm.md b/docs/algorithms/Yolo-Object-detection-ML-Algorithm.md deleted file mode 100644 index 3d7e9f75e..000000000 --- a/docs/algorithms/Yolo-Object-detection-ML-Algorithm.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: yolo-object-detection-ml-algorithm -title: YOLO Object Detection ML Algorithm -sidebar_label: YOLO Object Detection ML Algorithm -sidebar_position: 15 -description: "YOLO (You Only Look Once) is a popular deep learning algorithm for real-time object detection that divides images into grid cells and predicts bounding boxes and class probabilities for each cell." -tags: [Computer Vision, Object Detection, Deep Learning, YOLO, CNN] ---- - -# YOLO Object Detection Algorithm - -## Overview -**YOLO (You Only Look Once)** is a high-performance, real-time object detection algorithm that processes an image in one shot. Unlike traditional sliding window approaches, YOLO divides the image into grid cells, with each cell predicting bounding boxes and class probabilities. This approach achieves high speed and accuracy, making YOLO ideal for real-time applications. - -## Problem Description -- **Input**: An image containing multiple objects to be detected. - - Each object belongs to a predefined class. - - The goal is to accurately draw bounding boxes around each object and classify them. -- **Output**: Bounding boxes and class labels for each object in the image, along with confidence scores. -- **Challenges**: Traditional algorithms are too slow for real-time detection, while YOLO optimizes efficiency by analyzing the entire image at once. - -## Solution Approach -The **YOLO algorithm** uses a **single convolutional neural network (CNN)**, dividing an image into an `S x S` grid where each cell predicts: -- Bounding boxes (with x, y coordinates, width, height, and confidence score) -- Class probabilities, which combine with confidence scores to determine object likelihood in each cell - -The YOLOv3 model, a popular version, refines object detections across scales to improve accuracy. - -### Key Steps -1. **Divide Image into Grid**: Split the image into `S x S` grid cells. Each cell is responsible for detecting objects whose centers fall within that cell. -2. **Bounding Box Prediction**: Each cell predicts multiple bounding boxes and confidence scores. -3. **Confidence Score Calculation**: Calculated as the probability of object presence * Intersection over Union (IoU) with the actual bounding box. -4. **Non-Max Suppression**: To remove redundant boxes, Non-Max Suppression (NMS) keeps only boxes with the highest confidence. - -## Code Example (YOLOv3 in PyTorch) -The following is a basic setup for using YOLOv3 in PyTorch to detect objects in an image. - -```python -import torch -import torchvision.transforms as T -from PIL import Image -from models.yolo import YOLOv3 # Example model, may require pre-trained weights - -def detect_objects(image_path, model, conf_threshold=0.5): - # Load and transform image - image = Image.open(image_path) - transform = T.Compose([T.Resize((416, 416)), T.ToTensor()]) - img = transform(image).unsqueeze(0) - - # Detect objects - model.eval() - with torch.no_grad(): - outputs = model(img) - - # Process outputs - boxes, labels, scores = [], [], [] - for output in outputs[0]: - if output[4] > conf_threshold: - boxes.append(output[:4].tolist()) - scores.append(output[4].item()) - labels.append(output[5].item()) - - return boxes, labels, scores - -# Example usage -model = YOLOv3(num_classes=80) # Initialize YOLO model -boxes, labels, scores = detect_objects("example_image.jpg", model) -print(boxes, labels, scores) # Bounding boxes, labels, confidence scores -``` -## Time Complexity -YOLO performs real-time detection by processing the image in a single forward pass. - -- **Time Complexity**: O(S²) - Each grid cell processes detections in constant time, and the number of cells scales with the grid size `S x S`. - -## Space Complexity -- **Space Complexity**: O(S² * B * C) - The space complexity depends on the number of cells (`S x S`), bounding boxes per cell (`B`), and classes (`C`), which are fixed parameters in the YOLO model. - -## Applications -- **Autonomous Vehicles**: YOLO enables real-time detection of pedestrians, vehicles, and obstacles for safe navigation. -- **Surveillance**: Used in CCTV systems to track and recognize individuals or objects in real time. -- **Augmented Reality**: Suitable for overlaying digital objects in real-world environments due to its high speed. -- **Robotics**: Robots use YOLO for object detection to understand and interact with their surroundings. - -## Conclusion -The YOLO algorithm is a fast, accurate solution for real-time object detection, achieving efficiency by analyzing the entire image at once with a single CNN pass. Its speed and accuracy make it popular for real-time applications in fields like robotics, autonomous vehicles, and surveillance. diff --git a/docs/algorithms/_category_.json b/docs/algorithms/_category_.json deleted file mode 100644 index d54b8ecd3..000000000 --- a/docs/algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Algorithms", - "position": 8, - "link": { - "type": "generated-index", - "description": "Learn the most important RoadMap for Basic Concepts of Data Structures and Algorithms." - } - } \ No newline at end of file diff --git a/docs/algorithms/backtracking-algorithms/Bron-Kerbosch-Algorithm.md b/docs/algorithms/backtracking-algorithms/Bron-Kerbosch-Algorithm.md deleted file mode 100644 index 2f108a363..000000000 --- a/docs/algorithms/backtracking-algorithms/Bron-Kerbosch-Algorithm.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: Bron-Kerbosch-Algorithm -sidebar_position: 3 -title: Bron-Kerbosch Algorithm -sidebar_label: Bron-Kerbosch Algorithm -description: "The Bron-Kerbosch algorithm is a backtracking algorithm used to find all maximal cliques in an undirected graph. Known for its efficiency, especially on sparse graphs, it is widely applied in social network analysis, bioinformatics, and computational chemistry. The algorithm can be optimized with pivoting to reduce recursive calls and improve performance." -tags: [graph-theory, bron-kerbosch, maximal-clique, backtracking, clique-detection, pivoting, optimization] ---- - -The **Bron-Kerbosch algorithm** is a backtracking algorithm used to find all maximal cliques in an undirected graph. A clique is a subset of vertices, all of which are adjacent to each other, and a maximal clique is a clique that cannot be extended by including an adjacent vertex. This algorithm is known for its recursive nature and efficiency in finding cliques in graphs without needing to search through all vertex subsets. - -## Definition - -The Bron-Kerbosch algorithm is a **recursive backtracking algorithm** that enumerates all maximal cliques in an undirected graph. By maintaining three sets during recursion, the algorithm explores all potential cliques and ensures that each maximal clique is discovered only once. - -## Characteristics - -- **Exactness**: The algorithm is exact and produces all maximal cliques without duplication. -- **Recursiveness**: It uses recursive backtracking with sets of vertices to manage the state at each step. -- **Efficiency**: The algorithm is highly efficient, especially for sparse graphs. -- **Pivoting**: The pivoting technique can be used to reduce the number of recursive calls, optimizing performance by reducing the search space. - -## Time Complexity - -The time complexity of the Bron-Kerbosch algorithm varies depending on the implementation: - -- **Without pivoting**: , where \(n\) is the number of vertices. -- **With pivoting**: The worst-case complexity remains `O(3^(n/3))`, but pivoting reduces the number of recursive calls in practice, making the algorithm faster on average. - -## Space Complexity - -The space complexity is **O(n + E)**, where \(n\) is the number of vertices and \(E\) is the number of edges. This is primarily due to storing the adjacency list or matrix and maintaining three sets (R, P, and X) in each recursive call. - -## Approach - -The Bron-Kerbosch algorithm follows these steps: - -1. **Initialize three sets**: - - **R**: The growing clique being constructed. - - **P**: The set of vertices that can still be added to the current clique. - - **X**: The set of vertices that have already been considered for the current clique. - -2. **Recursive Backtracking**: - - At each step, choose a vertex from \(P\) and add it to \(R\), forming a new potential clique. - - Recur with updated sets: - - **R** includes the chosen vertex. - - **P** is restricted to vertices adjacent to the new vertex. - - **X** is updated to avoid revisiting vertices. - -3. **Base Case**: - - If both \(P\) and \(X\) are empty, \(R\) is a maximal clique. - -4. **Pivot Optimization (Optional)**: - - Choose a pivot vertex to minimize the number of recursive calls by excluding vertices that are unlikely to form new cliques. - -## C++ Implementation - -```cpp title="Bron-Kerbosch Algorithm in C++" -#include -#include -#include -using namespace std; - -void bronKerbosch(set R, set P, set X, const vector>& graph) { - if (P.empty() && X.empty()) { - // Output the maximal clique found - cout << "Maximal Clique: "; - for (int v : R) cout << v << " "; - cout << endl; - return; - } - - set P_copy = P; - for (int v : P_copy) { - set newR = R, newP, newX; - newR.insert(v); - - for (int w : graph[v]) { - if (P.find(w) != P.end()) newP.insert(w); - if (X.find(w) != X.end()) newX.insert(w); - } - - bronKerbosch(newR, newP, newX, graph); - - P.erase(v); - X.insert(v); - } -} - -int main() { - int n = 5; // Number of vertices - vector> graph(n); - - // Define graph edges (example) - graph[0] = {1, 2}; - graph[1] = {0, 2, 3}; - graph[2] = {0, 1, 4}; - graph[3] = {1, 4}; - graph[4] = {2, 3}; - - bronKerbosch({}, {0, 1, 2, 3, 4}, {}, graph); - - return 0; -} -``` - -## Java Implementation - -```java title="Bron-Kerbosch Algorithm in Java" -import java.util.HashSet; -import java.util.Set; - -public class BronKerbosch { - public static void bronKerbosch(Set R, Set P, Set X, Set[] graph) { - if (P.isEmpty() && X.isEmpty()) { - System.out.println("Maximal Clique: " + R); - return; - } - - Set P_copy = new HashSet<>(P); - for (Integer v : P_copy) { - Set newR = new HashSet<>(R); - newR.add(v); - - Set newP = new HashSet<>(); - Set newX = new HashSet<>(); - for (Integer w : graph[v]) { - if (P.contains(w)) newP.add(w); - if (X.contains(w)) newX.add(w); - } - - bronKerbosch(newR, newP, newX, graph); - - P.remove(v); - X.add(v); - } - } - - public static void main(String[] args) { - int n = 5; // Number of vertices - Set[] graph = new Set[n]; - for (int i = 0; i < n; i++) graph[i] = new HashSet<>(); - - // Define graph edges (example) - graph[0].add(1); graph[0].add(2); - graph[1].add(0); graph[1].add(2); graph[1].add(3); - graph[2].add(0); graph[2].add(1); graph[2].add(4); - graph[3].add(1); graph[3].add(4); - graph[4].add(2); graph[4].add(3); - - Set R = new HashSet<>(); - Set P = new HashSet<>(); - for (int i = 0; i < n; i++) P.add(i); - Set X = new HashSet<>(); - - bronKerbosch(R, P, X, graph); - } -} -``` - -## Summary - -The Bron-Kerbosch algorithm efficiently finds all maximal cliques in a graph, making it useful in various fields such as social network analysis and bioinformatics. With optional pivoting, it is adaptable to dense and sparse graphs alike, offering high-performance clique detection for applications requiring maximal clique identification. diff --git a/docs/algorithms/backtracking-algorithms/_category_.json b/docs/algorithms/backtracking-algorithms/_category_.json deleted file mode 100644 index 4c3755461..000000000 --- a/docs/algorithms/backtracking-algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Backtracking Algorithms", - "position": 6, - "link": { - "type": "generated-index", - "description": "Backtracking is an essential algorithmic technique for solving problems recursively by trying to build a solution incrementally. Explore various backtracking algorithms and their applications in solving complex computational problems like N-Queens, Sudoku, Subset Sum, and more." - } -} diff --git a/docs/algorithms/backtracking-algorithms/backtracking-questions.md b/docs/algorithms/backtracking-algorithms/backtracking-questions.md deleted file mode 100644 index 1badac128..000000000 --- a/docs/algorithms/backtracking-algorithms/backtracking-questions.md +++ /dev/null @@ -1,478 +0,0 @@ ---- -id: backtracking-dsa -sidebar_position: 11 -title: Backtracking -sidebar_label: Backtracking -description: "In this blog post, we'll explore the backtracking algorithm, a powerful technique for solving combinatorial problems by building solutions incrementally." -tags: [dsa, algorithms, backtracking] ---- - -Welcome to this in-depth exploration of backtracking patterns! This guide is designed to help you master the art of backtracking through a curated collection of problems, explanations, and real-world applications. - -## Introduction to Backtracking - -Backtracking is a fundamental algorithmic technique for solving problems incrementally by trying out partial solutions and abandoning those that fail to satisfy the problem's constraints. It's particularly useful in solving combinatorial and constraint satisfaction problems. - -## Why Master Backtracking? - -Understanding backtracking is crucial for several reasons: - -1. **Flexibility**: Backtracking can solve a wide range of problems, from permutations and combinations to constraint satisfaction. -2. **Efficiency**: Although not always the fastest approach, backtracking can often prune large portions of the search space, improving performance. -3. **Problem-Solving Skills**: Mastering backtracking enhances your ability to think recursively and approach problems systematically. -4. **Interview Preparation**: Backtracking is a popular topic in technical interviews, appearing in questions from leading tech companies. -5. **Foundation for Advanced Algorithms**: Many advanced algorithms, including those used in artificial intelligence, rely on backtracking principles. - -## Backtracking Patterns - -### Pattern 1: Permutations and Combinations - -This pattern focuses on generating all possible arrangements or selections of a given set of elements. It covers: - -- Generating permutations of an array -- Generating combinations of a specific length -- Generating subsets (the power set) - -**Key Techniques**: -- Recursive function calls to build solutions -- Using a boolean array to track used elements -- Managing the depth of recursion for combinations - -#### Permutations and Combinations in detail - -Permutations and combinations are fundamental concepts in combinatorics used to count and arrange objects. These concepts are widely used in fields such as mathematics, computer science, and probability theory. - -#### Permutations - -**Definition:** A permutation is an arrangement of objects in a specific order. The order of the arrangement matters in permutations. - -#### Formula - -The number of permutations of `n` distinct objects taken `r` at a time is given by the formula: - -$$ -P(n, r) = \frac{n!}{(n - r)!} -$$ - -#### Example - -- **Problem:** How many ways can we arrange 3 letters from the set `{A, B, C}`? -- **Calculation:** The permutations are: - - ABC - - ACB - - BAC - - BCA - - CAB - - CBA -- **Result:** There are `6` permutations. - -#### Backtracking Code for Permutations - -```cpp -#include -#include -#include - -using namespace std; - -// Helper function to generate permutations -void backtrack(string& str, int start, vector& result) { - if (start == str.size()) { - result.push_back(str); // Add the current permutation to the result - return; - } - - for (int i = start; i < str.size(); i++) { - swap(str[start], str[i]); // Swap to create a new permutation - backtrack(str, start + 1, result); // Recur for the next character - swap(str[start], str[i]); // Backtrack to the previous state - } -} - -vector permute(string str) { - vector result; - backtrack(str, 0, result); - return result; -} - -int main() { - string str = "ABC"; - vector permutations = permute(str); - - cout << "Permutations of " << str << ": "; - for (const string& perm : permutations) { - cout << perm << " "; - } - cout << endl; - - return 0; -} -``` -### Combinations - -**Definition:** A combination is a selection of objects without considering the order. The order of selection does not matter in combinations. - -#### Formula - -The number of combinations of `n` distinct objects taken `r` at a time is given by the formula: - -$$ -C(n, r) = \frac{n!}{r!(n - r)!} -$$ - -#### Example - -- **Problem:** How many ways can we choose 2 letters from the set `{A, B, C}`? -- **Calculation:** The combinations are: - - AB - - AC - - BC -- **Result:** There are `3` combinations. - -#### Backtracking Code for Combinations - -```cpp -#include -#include - -using namespace std; - -// Helper function to generate combinations -void backtrack(int start, int n, int k, vector& tempList, vector>& result) { - if (tempList.size() == k) { - result.push_back(tempList); // Add the current combination to the result - return; - } - - for (int i = start; i <= n; i++) { - tempList.push_back(i); // Choose the current number - backtrack(i + 1, n, k, tempList, result); // Recur for the next number - tempList.pop_back(); // Backtrack to the previous state - } -} - -vector> combine(int n, int k) { - vector> result; - vector tempList; - backtrack(1, n, k, tempList, result); - return result; -} - -int main() { - int n = 3, k = 2; - vector> combinations = combine(n, k); - - cout << "Combinations of " << n << " choose " << k << ": "; - for (const auto& comb : combinations) { - cout << "{ "; - for (int num : comb) { - cout << num << " "; - } - cout << "} "; - } - cout << endl; - - return 0; -} -``` - - -### Pattern 2: Constraint Satisfaction Problems - -This pattern applies backtracking to problems with specific constraints that must be satisfied. It's useful for: - -- Solving the N-Queens problem -- Sudoku solver -- Graph coloring problems - -**Key Techniques**: -- Checking constraints before making a choice -- Backtracking upon hitting a dead end -- Using data structures to keep track of states - -#### Constraint Satisfaction Problems in detail - -**Definition:** A Constraint Satisfaction Problem (CSP) is a mathematical problem defined as a set of objects whose state must satisfy several constraints and conditions. CSPs involve finding values for variables from a specified domain while satisfying constraints between those variables. - -#### Components of CSP - -1. **Variables:** The entities we want to assign values to. -2. **Domains:** The possible values that each variable can take. -3. **Constraints:** Conditions that must be met for the variables to be valid. - -#### Example: Sudoku - -**Problem Statement:** A standard Sudoku puzzle is a classic example of a CSP. The objective is to fill a 9x9 grid with digits so that each column, each row, and each of the nine 3x3 subgrids contains all of the digits from 1 to 9. - -#### Components - -- **Variables:** Each empty cell in the Sudoku grid. -- **Domains:** The numbers 1 to 9. -- **Constraints:** - - Each number must appear only once in each row. - - Each number must appear only once in each column. - - Each number must appear only once in each 3x3 subgrid. - -#### Backtracking Algorithm for Sudoku - -```java -public class SudokuSolver { - - // Function to check if a number can be placed in a given cell - public static boolean isValid(int[][] board, int row, int col, int num) { - // Check if num is not in the current row - for (int x = 0; x < 9; x++) { - if (board[row][x] == num) { - return false; - } - } - - // Check if num is not in the current column - for (int x = 0; x < 9; x++) { - if (board[x][col] == num) { - return false; - } - } - - // Check if num is not in the current 3x3 box - int startRow = row - row % 3; - int startCol = col - col % 3; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (board[i + startRow][j + startCol] == num) { - return false; - } - } - } - return true; - } - - // Function to solve the Sudoku puzzle using backtracking - public static boolean solveSudoku(int[][] board) { - int[] emptyCell = findEmptyLocation(board); - if (emptyCell == null) { - return true; // Sudoku is solved - } - - int row = emptyCell[0]; - int col = emptyCell[1]; - for (int num = 1; num <= 9; num++) { // Try numbers 1-9 - if (isValid(board, row, col, num)) { - board[row][col] = num; // Assign num to the cell - - if (solveSudoku(board)) { // Recur to solve the rest - return true; - } - - board[row][col] = 0; // Reset if num doesn't lead to a solution - } - } - return false; // Backtrack - } - - // Function to find an empty location in the Sudoku board - public static int[] findEmptyLocation(int[][] board) { - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - if (board[i][j] == 0) { // 0 indicates an empty cell - return new int[]{i, j}; - } - } - } - return null; // No empty location found - } - - // Main function to run the Sudoku solver - public static void main(String[] args) { - // Example Sudoku Puzzle (0 represents empty cells) - int[][] sudokuBoard = { - {5, 3, 0, 0, 7, 0, 0, 0, 0}, - {6, 0, 0, 1, 9, 5, 0, 0, 0}, - {0, 9, 8, 0, 0, 0, 0, 6, 0}, - {8, 0, 0, 0, 6, 0, 0, 0, 3}, - {4, 0, 0, 8, 0, 3, 0, 0, 1}, - {7, 0, 0, 0, 2, 0, 0, 0, 6}, - {0, 6, 0, 0, 0, 0, 2, 8, 0}, - {0, 0, 0, 4, 1, 9, 0, 0, 5}, - {0, 0, 0, 0, 8, 0, 0, 7, 9} - }; - - if (solveSudoku(sudokuBoard)) { - System.out.println("Sudoku solved successfully!"); - for (int[] row : sudokuBoard) { - for (int num : row) { - System.out.print(num + " "); - } - System.out.println(); - } - } else { - System.out.println("No solution exists."); - } - } -} -``` - -#### Pathfinding and Maze Problems - -This pattern applies backtracking to navigate through grids or mazes. It covers: - -- Finding paths in mazes -- Solving the Rat in a Maze problem -- Exploring all possible paths in a grid - -**Key Techniques**: -- Recursively exploring adjacent cells -- Marking cells as visited -- Backtracking to explore alternative paths - -### Pattern 3: Pathfinding and Maze Problems - -**Definition:** Pathfinding problems involve finding a route from a starting point to a destination within a defined space, such as a grid or maze. These problems often require algorithms that can explore different paths while considering constraints like obstacles and boundaries. - -#### Components of Pathfinding Problems - -1. **Grid or Maze Representation:** Typically represented as a 2D array where cells may be passable (free space) or impassable (obstacles). -2. **Start and End Points:** The coordinates indicating the beginning and destination of the path. -3. **Movement Constraints:** Rules defining how the algorithm can traverse the grid (e.g., moving up, down, left, right). -4. **Pathfinding Algorithm:** An algorithm used to explore paths and determine the most efficient route. Common algorithms include Depth-First Search (DFS), Breadth-First Search (BFS), A*, and Dijkstra's algorithm. - -### Example: Finding a Path in a Maze - -### Problem Statement - -Given a maze represented as a 2D array, find a path from the starting position to the destination while avoiding obstacles. - -### Maze Representation - -- `0` represents open cells. -- `1` represents walls/obstacles. -- `S` (Start) is represented by the coordinates (0, 0). -- `E` (End) is represented by the coordinates (4, 4). - -Example Maze: - - -### Backtracking Algorithm for Pathfinding - -```java -import java.util.ArrayList; -import java.util.List; - -public class MazeSolver { - - // Function to check if a cell is valid for traversal - private static boolean isSafe(int[][] maze, int row, int col, boolean[][] visited) { - return (row >= 0 && row < maze.length) && (col >= 0 && col < maze[0].length) - && (maze[row][col] == 0 && !visited[row][col]); - } - - // Recursive function to find the path - private static boolean findPath(int[][] maze, int row, int col, List path, boolean[][] visited) { - // If the destination is reached - if (row == maze.length - 1 && col == maze[0].length - 1) { - path.add(new int[]{row, col}); - return true; - } - - // Check if the current cell is valid - if (isSafe(maze, row, col, visited)) { - visited[row][col] = true; // Mark the cell as visited - path.add(new int[]{row, col}); // Add the cell to the path - - // Explore in all possible directions (down, right, up, left) - if (findPath(maze, row + 1, col, path, visited) || // Down - findPath(maze, row, col + 1, path, visited) || // Right - findPath(maze, row - 1, col, path, visited) || // Up - findPath(maze, row, col - 1, path, visited)) { // Left - return true; - } - - // Backtrack: remove the cell from the path if no path is found - path.remove(path.size() - 1); - visited[row][col] = false; // Unmark the cell - } - return false; // No path found - } - - // Main function to solve the maze - public static void main(String[] args) { - int[][] maze = { - {0, 0, 1, 0, 0}, - {0, 0, 1, 0, 1}, - {0, 1, 0, 0, 0}, - {0, 1, 1, 1, 0}, - {0, 0, 0, 1, 0} - }; - - List path = new ArrayList<>(); - boolean[][] visited = new boolean[maze.length][maze[0].length]; - - if (findPath(maze, 0, 0, path, visited)) { - System.out.println("Path found: "); - for (int[] cell : path) { - System.out.print("(" + cell[0] + ", " + cell[1] + ") "); - } - } else { - System.out.println("No path exists."); - } - } -} -``` - -## Problem Collections - -### Pattern 1: Permutations and Combinations - -| Problem | Difficulty | Practice Link | Explanation | -|---------|------------|---------------|-------------| -| Permutations of a String | Medium | [LeetCode](https://leetcode.com/problems/permutations/) | [Explanation](https://takeuforward.org/data-structure/permutations-of-string/) | -| Combinations of k Elements | Medium | [LeetCode](https://leetcode.com/problems/combinations/) | [Explanation](https://takeuforward.org/data-structure/combinations-of-k-elements/) | -| Subsets | Medium | [LeetCode](https://leetcode.com/problems/subsets/) | [Explanation](https://takeuforward.org/data-structure/subsets/) | - -### Pattern 2: Constraint Satisfaction Problems - -| Problem | Difficulty | Practice Link | Explanation | -|---------|------------|---------------|-------------| -| N-Queens | Hard | [LeetCode](https://leetcode.com/problems/n-queens/) | [Explanation](https://takeuforward.org/data-structure/n-queens-problem/) | -| Sudoku Solver | Hard | [LeetCode](https://leetcode.com/problems/sudoku-solver/) | [Explanation](https://takeuforward.org/data-structure/sudoku-solver/) | -| Graph Coloring | Hard | [GeeksforGeeks](https://www.geeksforgeeks.org/m-coloring-problem-using-backtracking/) | [Explanation](https://takeuforward.org/data-structure/graph-coloring-problem-using-backtracking/) | - -### Pattern 3: Pathfinding and Maze Problems - -| Problem | Difficulty | Practice Link | Explanation | -|---------|------------|---------------|-------------| -| Rat in a Maze | Medium | [GeeksforGeeks](https://www.geeksforgeeks.org/rat-in-a-maze-backtracking-2/) | [Explanation](https://takeuforward.org/data-structure/rat-in-a-maze/) | -| Word Search | Medium | [LeetCode](https://leetcode.com/problems/word-search/) | [Explanation](https://takeuforward.org/data-structure/word-search/) | -| Unique Paths | Medium | [LeetCode](https://leetcode.com/problems/unique-paths/) | [Explanation](https://takeuforward.org/data-structure/unique-paths/) | - -## Real-World Applications - -Backtracking and its patterns find applications in various real-world scenarios: - -1. **Puzzle Solving**: Solving puzzles like Sudoku, crosswords, and logic puzzles. -2. **Game Development**: Implementing algorithms for pathfinding and AI behavior in games. -3. **Scheduling Problems**: Finding optimal schedules that satisfy constraints (e.g., job scheduling). -4. **Network Design**: Solving problems in network topology and resource allocation. -5. **Cryptography**: Breaking ciphers through exhaustive search methods. -6. **Route Planning**: Finding the best routes in logistics and transportation. - -## Benefits of Mastering Backtracking - -By working through these problems and understanding the patterns, you'll gain: - -1. **Improved Problem-Solving Skills**: Develop a systematic approach to breaking down complex problems. -2. **Enhanced Recursive Thinking**: Learn to think recursively and apply it to various scenarios. -3. **Interview Readiness**: Build confidence in tackling a wide range of coding challenges. -4. **Efficiency Mindset**: Cultivate an intuition for designing efficient solutions in your daily coding tasks. -5. **Foundation for Advanced Topics**: Prepare yourself for more complex algorithmic concepts and data structures. - -## How to Use This Guide - -1. Start with the basic permutation generation in Pattern 1. -2. Progress through each pattern, solving problems of increasing difficulty. -3. For each problem: - - Attempt to solve it independently. - - If stuck, refer to the provided explanation. - - After solving, compare your solution with the optimal approach. -4. Reflect on the patterns and techniques used in each problem. -5. Try to apply these patterns to new, unseen problems to reinforce your learning. diff --git a/docs/algorithms/backtracking-algorithms/hamilton-path-cyle.md b/docs/algorithms/backtracking-algorithms/hamilton-path-cyle.md deleted file mode 100644 index db81d6bb6..000000000 --- a/docs/algorithms/backtracking-algorithms/hamilton-path-cyle.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -id: hamiltonian-path-cycle -sidebar_position: 2 -title: Hamiltonian Path and Cycle -sidebar_label: Hamiltonian Path and Cycle -description: "Hamiltonian Path and Cycle problems are a classic graph theory problem where the task is to find a path or cycle that visits every vertex exactly once. These problems are NP-complete and are widely used in various applications such as route planning, logistics, and genome sequencing." -tags: [graph-theory, hamiltonian-cycle, backtracking] ---- - -## Hamiltonian Path and Cycle - -The **Hamiltonian Path** is a path in an undirected or directed graph that visits each vertex exactly once. A **Hamiltonian Cycle** (or Circuit) is a Hamiltonian Path that starts and ends at the same vertex, forming a cycle. These problems are NP-complete and have numerous applications, particularly in areas such as route optimization, logistics, and bioinformatics. - -### What is a Hamiltonian Path? - -In simple terms, a Hamiltonian Path is a path in a graph where each vertex is visited exactly once. If such a path exists, the graph is called a Hamiltonian Graph. If the path forms a cycle, where the first and last vertex are the same, it is called a Hamiltonian Cycle. - -### Key Features of Hamiltonian Path and Cycle Problems - -1. **NP-complete Problem**: Both the Hamiltonian Path and Cycle problems are NP-complete, meaning no polynomial-time algorithm is known to solve them for arbitrary graphs. - -2. **Backtracking Approach**: A popular way to solve the Hamiltonian problems is by using backtracking. This involves trying to construct the solution one step at a time and abandoning paths that fail to satisfy the required conditions. - -3. **Cycle Condition**: For a Hamiltonian Cycle, the solution must form a cycle, i.e., the path should return to the starting vertex. - -### How Does Backtracking Solve the Hamiltonian Path Problem? - -1. **Recursive Structure**: - The problem is solved by recursively visiting vertices, starting from an arbitrary vertex and keeping track of visited vertices to avoid revisiting them. - -2. **Base Case**: - The recursion stops when all vertices are visited. If a path is found, it is returned as a solution. If the current path leads to a dead-end, the algorithm backtracks by removing the last vertex from the path and trying another one. - -3. **Cycle Check**: - In the case of Hamiltonian Cycle, after visiting all vertices, an additional check is made to see if the last vertex in the path is adjacent to the first vertex. - -### Step-by-Step Backtracking Example: Hamiltonian Cycle - -Consider a graph represented by an adjacency matrix. We aim to find a Hamiltonian Cycle in this graph. - -**Algorithm**: - -1. Start from the first vertex and mark it as visited. -2. Try to find the next vertex that hasn't been visited and is connected to the current vertex. -3. If all vertices are visited and there is an edge from the last vertex to the first, a cycle is found. -4. If no such vertex is found, backtrack and try a different path. - -```cpp -#include -#include -using namespace std; - -bool isSafe(int v, vector>& graph, vector& path, int pos) { - // Check if current vertex and the last vertex in path are adjacent - if (graph[path[pos - 1]][v] == 0) { - return false; - } - - // Check if the current vertex has already been included in the path - for (int i = 0; i < pos; i++) { - if (path[i] == v) { - return false; - } - } - - return true; -} - -bool hamiltonianCycleUtil(vector>& graph, vector& path, int pos, int N) { - // Base case: If all vertices are in the path, check if there is an edge to the start vertex - if (pos == N) { - return graph[path[pos - 1]][path[0]] == 1; - } - - // Try different vertices as next candidates in the Hamiltonian Cycle - for (int v = 1; v < N; v++) { - if (isSafe(v, graph, path, pos)) { - path[pos] = v; // Add vertex v to the path - - if (hamiltonianCycleUtil(graph, path, pos + 1, N)) { - return true; // If cycle is found, return true - } - - path[pos] = -1; // Backtrack - } - } - - return false; // No cycle found -} - -void hamiltonianCycle(vector>& graph, int N) { - vector path(N, -1); - path[0] = 0; // Start from the first vertex - - if (!hamiltonianCycleUtil(graph, path, 1, N)) { - cout << "No Hamiltonian Cycle exists" << endl; - return; - } - - // Print the Hamiltonian Cycle - cout << "Hamiltonian Cycle: "; - for (int i = 0; i < N; i++) { - cout << path[i] << " "; - } - cout << path[0] << endl; // Print the first vertex again to complete the cycle -} - -int main() { - // Example graph represented as an adjacency matrix - vector> graph = {{0, 1, 0, 1, 0}, - {1, 0, 1, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 0, 0, 1}, - {0, 1, 1, 1, 0}}; - - int N = graph.size(); - hamiltonianCycle(graph, N); - - return 0; -} - -``` \ No newline at end of file diff --git a/docs/algorithms/backtracking-algorithms/imp-of-backtracking.md b/docs/algorithms/backtracking-algorithms/imp-of-backtracking.md deleted file mode 100644 index 67df8b3a3..000000000 --- a/docs/algorithms/backtracking-algorithms/imp-of-backtracking.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -id: importance-of-backtracking -sidebar_position: 2 -title: Importance of Backtracking -sidebar_label: Importance of Backtracking -description: "Backtracking is a systematic algorithmic method for solving problems where you need to explore all possible configurations (solution candidates) and discard those that fail to satisfy the given constraints. It is widely used to solve constraint satisfaction problems such as puzzles, combinatorial optimization problems, and decision problems." -tags: [CSPs, Optimization] ---- - -### Importance of Backtracking Algorithms - -1. **Solving Constraint Satisfaction Problems (CSPs)**: - Backtracking is a go-to technique for solving problems that involve a set of constraints, such as Sudoku, crosswords, and puzzles. It systematically searches for solutions and eliminates configurations that don’t meet the criteria early on, which makes it efficient for such problems. - -2. **Combinatorial Search**: - Backtracking is ideal for combinatorial problems, such as finding all subsets of a set, generating permutations, or solving problems where you have to find a particular arrangement of elements that satisfies given constraints. - -3. **Optimization**: - In problems like the N-Queens problem or traveling salesperson problem (TSP), backtracking can be combined with techniques like branch-and-bound to further improve efficiency by cutting off search branches early. - -4. **Efficiently Navigating Large Search Spaces**: - Backtracking helps navigate large search spaces without having to examine every possibility by pruning unfeasible solutions early on. diff --git a/docs/algorithms/backtracking-algorithms/m-coloring.md b/docs/algorithms/backtracking-algorithms/m-coloring.md deleted file mode 100644 index 70643da12..000000000 --- a/docs/algorithms/backtracking-algorithms/m-coloring.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: m-coloring-problem -sidebar_position: 1 -title: M-Coloring Problem -sidebar_label: M-Coloring Problem -description: "The M-Coloring problem is a backtracking algorithm where the task is to assign colors to vertices of a graph so that no two adjacent vertices share the same color. The goal is to find if it is possible to color the graph using at most M colors." -tags: [backtracking, graph-coloring, constraint satisfaction] ---- - -## M-Coloring Problem - -The M-Coloring problem is a classic constraint satisfaction problem where the task is to color the vertices of a graph using at most M colors such that no two adjacent vertices have the same color. This problem can be solved using backtracking by exploring all possible color assignments and ensuring that constraints are not violated. - -### Problem Definition - -Given an undirected graph with **N** vertices and **E** edges, the task is to find a way to assign colors to each vertex such that no two adjacent vertices share the same color. You are allowed to use a maximum of **M** different colors. - -### Key Features of the M-Coloring Problem - -1. **Constraint Satisfaction**: Each vertex must be assigned one of the **M** colors, and no two adjacent vertices should have the same color. -2. **Backtracking Approach**: The algorithm tries to color one vertex at a time. If a valid coloring is found for the current vertex, it proceeds to color the next vertex. If not, it backtracks to try a different color for the previous vertex. - -3. **Feasibility Check**: At each step, we check if assigning a particular color to a vertex is valid by ensuring that none of its adjacent vertices have the same color. - -### How the M-Coloring Problem Works - -The problem is solved using a backtracking algorithm that tries to assign colors to vertices one by one. If a color assignment leads to a conflict, the algorithm backtracks and tries a different color. - -### Algorithm Steps - -1. Assign the first vertex a color from the available **M** colors. -2. Recursively assign colors to the remaining vertices, ensuring that no adjacent vertices share the same color. -3. If a vertex cannot be assigned any color without violating the constraint, backtrack to the previous vertex and try a different color. -4. Continue this process until either all vertices are colored or it is determined that no valid coloring exists with **M** colors. - -### Step-by-Step Example - -Consider a graph with **4 vertices** and the following adjacency matrix: - -We want to color this graph using at most 3 colors. - -### C++ Code Implementation - -```cpp -#include -#include -using namespace std; - -// Function to check if the current color assignment is safe for vertex v -bool isSafe(int v, vector>& graph, vector& color, int c) { - for (int i = 0; i < graph.size(); i++) { - if (graph[v][i] && color[i] == c) // Check adjacency and color constraint - return false; - } - return true; -} - -// A recursive utility function to solve M Coloring problem -bool graphColoringUtil(vector>& graph, int m, vector& color, int v) { - if (v == graph.size()) // All vertices are colored - return true; - - // Try different colors for vertex v - for (int c = 1; c <= m; c++) { - if (isSafe(v, graph, color, c)) { - color[v] = c; // Assign color c to vertex v - - // Recur to assign colors to the rest of the vertices - if (graphColoringUtil(graph, m, color, v + 1)) - return true; - - color[v] = 0; // Backtrack if no solution found - } - } - - return false; // Return false if no coloring is possible -} - -// Function to solve the M Coloring problem -bool graphColoring(vector>& graph, int m) { - vector color(graph.size(), 0); // Initialize all vertices with no color - - // Call the utility function to solve the problem - if (!graphColoringUtil(graph, m, color, 0)) { - cout << "No solution exists for " << m << " colors." << endl; - return false; - } - - // Print the solution - cout << "Solution exists for " << m << " colors:" << endl; - for (int i = 0; i < graph.size(); i++) { - cout << "Vertex " << i << " -> Color " << color[i] << endl; - } - return true; -} - -int main() { - // Example graph represented by adjacency matrix - vector> graph = {{0, 1, 1, 1}, - {1, 0, 1, 0}, - {1, 1, 0, 1}, - {1, 0, 1, 0}}; - int m = 3; // Number of colors - graphColoring(graph, m); - return 0; -} - -``` - - -### JavaScript Code Implementation - -```javascript -function isSafe(v, graph, color, c) { - // Check if the current color assignment is safe for vertex v - for (let i = 0; i < graph.length; i++) { - if (graph[v][i] === 1 && color[i] === c) { // Check adjacency and color constraint - return false; - } - } - return true; -} - -function graphColoringUtil(graph, m, color, v) { - // All vertices are colored - if (v === graph.length) { - return true; - } - - // Try different colors for vertex v - for (let c = 1; c <= m; c++) { - if (isSafe(v, graph, color, c)) { - color[v] = c; // Assign color c to vertex v - - // Recur to assign colors to the rest of the vertices - if (graphColoringUtil(graph, m, color, v + 1)) { - return true; - } - - color[v] = 0; // Backtrack if no solution found - } - } - - return false; // Return false if no coloring is possible -} - -function graphColoring(graph, m) { - const color = Array(graph.length).fill(0); // Initialize all vertices with no color - - // Call the utility function to solve the problem - if (!graphColoringUtil(graph, m, color, 0)) { - console.log(`No solution exists for ${m} colors.`); - return false; - } - - // Print the solution - console.log(`Solution exists for ${m} colors:`); - for (let i = 0; i < graph.length; i++) { - console.log(`Vertex ${i} -> Color ${color[i]}`); - } - return true; -} - -// Example graph represented by adjacency matrix -const graph = [ - [0, 1, 1, 1], - [1, 0, 1, 0], - [1, 1, 0, 1], - [1, 0, 1, 0] -]; -const m = 3; // Number of colors -graphColoring(graph, m); -``` - -### Explanation of the Code - -1. **`isSafe` Function**: Checks whether it's safe to assign a color `c` to vertex `v` by ensuring that no adjacent vertices have the same color. - -2. **`graphColoringUtil` Function**: A recursive utility function that tries to color the graph. If it successfully colors all vertices, it returns `true`. If it can't color a vertex with any of the available colors, it backtracks. - -3. **`graphColoring` Function**: Initializes the `color` array and calls the utility function. It also prints the results or indicates that no solution exists. - -4. **Example Graph**: The adjacency matrix defines a graph with 4 vertices, and the program attempts to color it using up to 3 colors. - diff --git a/docs/algorithms/backtracking-algorithms/what-is-backtracking.md b/docs/algorithms/backtracking-algorithms/what-is-backtracking.md deleted file mode 100644 index 3efb9f150..000000000 --- a/docs/algorithms/backtracking-algorithms/what-is-backtracking.md +++ /dev/null @@ -1,299 +0,0 @@ ---- -id: what-is-Backtracking -sidebar_position: 1 -title: What is Backtracking Algorithms? -sidebar_label: What is Backtracking? -description: "Backtracking is a systematic algorithmic method for solving problems where you need to explore all possible configurations (solution candidates) and discard those that fail to satisfy the given constraints. It is widely used to solve constraint satisfaction problems such as puzzles, combinatorial optimization problems, and decision problems." -tags: [backtracking, memoisation, pruning] ---- - -## Backtracking Algorithms - -Backtracking is a systematic algorithmic method for solving problems where you need to explore all possible configurations (solution candidates) and discard those that fail to satisfy the given constraints. It is widely used to solve constraint satisfaction problems such as puzzles, combinatorial optimization problems, and decision problems. - -### What is Backtracking? - -Backtracking works by building a solution incrementally, one piece at a time, and removes those solutions that fail to satisfy the constraints of the problem at any stage. This process is repeated until the algorithm either finds a solution or exhausts all possibilities. It is often implemented using recursion, exploring each branch of a problem space and "backtracking" once a dead-end is encountered. - -### Key Features of Backtracking - -1. **Incremental Construction**: Backtracking builds solutions one step at a time. After each step, the algorithm checks whether the partial solution still has a chance of leading to a valid solution. - -2. **Backtrack on Failure**: If the current partial solution violates the problem constraints or can't possibly lead to a complete solution, the algorithm discards the last step (backtracks) and tries a different option. - -3. **Recursive Exploration**: The solution space is explored recursively, and backtracking can be viewed as a depth-first search (DFS) across the solution space. - -4. **Pruning**: Backtracking employs pruning techniques that help discard entire sections of the search tree that cannot lead to valid solutions, thus optimizing performance. - - -### How Does Backtracking Work? - -1. **Recursive Structure**: - Backtracking is implemented using recursive function calls. At each stage, the function explores possible solutions by iterating through available options and makes a decision for the current step. - -2. **Base Case**: - The recursive function has a base case that checks if a solution has been found or if the problem has reached an unsolvable state. If a solution is found, it is returned; otherwise, the function backtracks by undoing the last decision and trying a different option. - -3. **Pruning**: - The key optimization in backtracking is to "prune" unnecessary paths early. For example, in a problem like the N-Queens problem, if placing a queen leads to a conflict, the algorithm doesn't explore further down that branch and instead backtracks to a previous step. - -### Step-by-Step Backtracking Example: N-Queens Problem - -In the N-Queens problem, the task is to place N queens on an NxN chessboard such that no two queens attack each other. This means no two queens should share the same row, column, or diagonal. - -**Algorithm**: - -1. Start placing queens in the first column. -2. For each row, place a queen if it doesn’t conflict with any other queen. -3. Move to the next column and repeat step 2. -4. If all queens are placed, a solution is found. -5. If placing a queen leads to a conflict, backtrack and try a different row for the previous queen. -6. Continue this process until all possible placements have been tried. - -#### C++ Code Implementation - -```cpp -#include -#include -using namespace std; - -bool isSafe(vector>& board, int row, int col, int N) { - // Check row on left side - for (int i = 0; i < col; i++) { - if (board[row][i]) return false; - } - - // Check upper diagonal on left side - for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) { - if (board[i][j]) return false; - } - - // Check lower diagonal on left side - for (int i = row, j = col; j >= 0 && i < N; i++, j--) { - if (board[i][j]) return false; - } - - return true; -} - -bool solveNQueensUtil(vector>& board, int col, int N) { - if (col >= N) return true; // All queens are placed - - for (int i = 0; i < N; i++) { - if (isSafe(board, i, col, N)) { - board[i][col] = 1; // Place queen - - if (solveNQueensUtil(board, col + 1, N)) { - return true; // Found solution - } - - board[i][col] = 0; // Backtrack - } - } - - return false; // No solution found -} - -void solveNQueens(int N) { - vector> board(N, vector(N, 0)); - - if (!solveNQueensUtil(board, 0, N)) { - cout << "Solution does not exist" << endl; - return; - } - - // Print solution - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) { - cout << board[i][j] << " "; - } - cout << endl; - } -} - -int main() { - int N = 8; // Size of the chessboard (8x8) - solveNQueens(N); - return 0; -} -``` - -#### JavaScript Code Implementation - -```javascript -function isSafe(board, row, col, N) { - // Check row on the left side - for (let i = 0; i < col; i++) { - if (board[row][i]) return false; - } - - // Check upper diagonal on the left side - for (let i = row, j = col; i >= 0 && j >= 0; i--, j--) { - if (board[i][j]) return false; - } - - // Check lower diagonal on the left side - for (let i = row, j = col; j >= 0 && i < N; i++, j--) { - if (board[i][j]) return false; - } - - return true; -} - -function solveNQueensUtil(board, col, N) { - if (col >= N) return true; // All queens are placed - - for (let i = 0; i < N; i++) { - if (isSafe(board, i, col, N)) { - board[i][col] = 1; // Place queen - - if (solveNQueensUtil(board, col + 1, N)) { - return true; // Found solution - } - - board[i][col] = 0; // Backtrack - } - } - - return false; // No solution found -} - -function solveNQueens(N) { - const board = Array.from({ length: N }, () => Array(N).fill(0)); // Initialize N x N board - - if (!solveNQueensUtil(board, 0, N)) { - console.log("Solution does not exist"); - return; - } - - // Print solution - for (let i = 0; i < N; i++) { - console.log(board[i].join(" ")); // Print each row - } -} - -// Example usage -const N = 8; // Size of the chessboard (8x8) -solveNQueens(N); -``` - -### Explanation of the Code - -1. **`isSafe` Function**: Checks if it's safe to place a queen at the specified position (row, col) by checking: - - The current row on the left side for other queens. - - The upper diagonal on the left side. - - The lower diagonal on the left side. - -2. **`solveNQueensUtil` Function**: A recursive utility function that attempts to place queens column by column: - - If all queens are placed (`col >= N`), it returns `true`. - - For each row in the current column, it checks if placing a queen is safe. - - If it's safe, it places the queen and recursively tries to place queens in the next column. - - If placing leads to no solution, it backtracks by removing the queen. - -3. **`solveNQueens` Function**: Initializes the chessboard and calls the utility function. If no solution exists, it prints a message. Otherwise, it prints the board configuration. - -4. **Example Usage**: The code is set to solve the 8-Queens problem by default, but you can change the value of `N` to solve for different sizes. - - -### Pseudocode for the N-Queens Problem -Here is the pseudocode that represents the backtracking approach used to solve the N-Queens problem: - -``` -function solveNQueens(board, col): - if col >= N: - return True # All queens are placed - - for each row in 0 to N-1: - if isSafe(board, row, col): - placeQueen(board, row, col) - - if solveNQueens(board, col + 1): - return True # Proceed with placing queens in next columns - - removeQueen(board, row, col) # Backtrack and remove queen - - return False # No valid position for this column - -function isSafe(board, row, col): - # Check if no queen can attack this position from the left-side rows, upper diagonal, and lower diagonal - return True if safe, else False - -``` - -### Backtracking vs Other Algorithms - -**Backtracking vs Dynamic Programming**: -While backtracking explores all possible solutions by trial and error, dynamic programming uses memoization to store solutions to overlapping subproblems. Dynamic programming is generally faster for optimization problems but can consume more space. - -**Backtracking vs Greedy Algorithms**: -Backtracking is more flexible as it explores multiple paths to find an optimal solution, while greedy algorithms make the locally optimal choice at each stage and hope to find a global optimum, which does not always work for complex problems. - -**Backtracking vs Brute Force**: -Brute force explores all possible configurations without any intelligent pruning of the search space. Backtracking intelligently cuts off infeasible paths, which makes it more efficient than brute force for most problems. - -**Real-world Applications of Backtracking Algorithms Sudoku Solver**: -Solving Sudoku puzzles by placing numbers in a 9x9 grid while ensuring each row, column, and 3x3 sub-grid contains unique numbers from 1-9. - -**Knight’s Tour Problem**: -Finding a tour for a knight on a chessboard where the knight visits every square exactly once. - -**Mazes and Pathfinding**: -Backtracking can be used to explore all possible paths through a maze and find a path that leads to the goal. - -**Subset Sum Problem**: -Backtracking is useful for determining if a subset of a set of numbers sums to a specific value. - -**Crossword Puzzle Solver**: -Filling a crossword grid with words from a list such that they fit in accordance with the constraints of the puzzle. - -**Permutation and Combination Generation**: -Generating all possible permutations and combinations of a set, used in tasks like password cracking or generating sequences for testing. - -### Optimizing Backtracking Algorithms -Backtracking can be made more efficient with the following techniques: - -1. **Pruning**: Use pruning strategies to cut off branches early in the search tree. This can drastically reduce the number of possibilities the algorithm needs to explore. - -2. **Memoization**: Store intermediate results of the backtracking to avoid recomputing for subproblems that have been solved before. - -3. **Heuristic Search**: Employ heuristic strategies like Minimum Remaining Values (MRV) to choose the next variable with the fewest legal values left in problems like Sudoku or other constraint satisfaction problems. - -### Common Backtracking Problems -Below are a few popular backtracking problems that are widely used in competitive programming and interviews: - -- **Rat in a Maze**: -Find a path for a rat to reach the destination in a maze where some cells are blocked. - -- **M Coloring Problem**: -Assign colors to vertices of a graph such that no two adjacent vertices have the same color. - -- **Hamiltonian Path**: -Find a path in a graph that visits each vertex exactly once. - -- **Subset Generation**: -Generate all possible subsets of a given set. - -- **Tug of War Problem**: -Divide a set into two subsets such that the difference between their sums is as small as possible. - -### Pros and Cons of Backtracking -**Pros**: -1. **Flexibility**: Can be applied to a wide variety of problems. -Systematic Exploration: Explores all possibilities and guarantees a solution if one exists. -2. **Pruning**: Reduces the search space by eliminating infeasible solutions early. -3. **Simplicity**: Often easy to implement and understand. - -**Cons**: - -1. **Performance**: Can be slow for large search spaces as the worst-case time complexity is exponential. -2. **Memory Intensive**: In problems with deep recursion, backtracking can be memory intensive. - -### Conclusion -Backtracking is a powerful technique for solving a wide variety of problems, especially in combinatorial optimization and constraint satisfaction. While it can be slower than other algorithms like dynamic programming for certain problems, its systematic exploration of all possibilities makes it highly effective for problems where pruning can significantly reduce the search space. With the right optimizations, backtracking can provide elegant solutions to some of the most challenging problems in computer science and real-world applications. - -Whether you're solving puzzles, designing algorithms for games, or facing a tough technical interview, mastering backtracking will give you an edge in problem-solving and algorithm design. - -### References - -- [Backtracking Blog - By Ajay Dhangar](https://ajay-dhangar.github.io/backtracking/) -- [GeeksForGeeks - Backtracking Introduction](https://www.geeksforgeeks.org/backtracking-algorithms/) diff --git a/docs/algorithms/greedy-algorithms/Fractional_Knapsack.md b/docs/algorithms/greedy-algorithms/Fractional_Knapsack.md deleted file mode 100644 index de5bb4de0..000000000 --- a/docs/algorithms/greedy-algorithms/Fractional_Knapsack.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: fractional-knapsack-1 -title: Fractional Knapsack Problem 1 -sidebar_label: Fractional Knapsack -description: "In this post, we'll explore the Fractional Knapsack Problem, a greedy algorithm used to maximize the value of items that can be fit into a knapsack with a weight limit." -tags: [dsa, algorithms, greedy algorithms, optimization problems] ---- - -### Definition: -The Fractional Knapsack Problem is an optimization problem that aims to maximize the total value of items placed in a knapsack of fixed capacity, where the items can be divided into smaller fractions. Unlike the 0/1 Knapsack Problem, where items must either be fully taken or left, in the fractional version, parts of an item can be taken to fill the knapsack optimally. - -### Characteristics: -- **Greedy Approach**: - The fractional knapsack problem is solved using a greedy algorithm. Items are selected based on their value-to-weight ratio, prioritizing items with the highest ratio until the knapsack is full. - -- **Divisibility**: - In this problem, items can be broken into smaller pieces, meaning you can take fractions of an item if it helps in maximizing the total value. - -### Steps Involved: -1. **Sort by Value-to-Weight Ratio**: - First, sort the items in decreasing order of their value-to-weight ratio. - -2. **Greedily Add Items**: - Starting from the item with the highest ratio, add as much of it as possible to the knapsack. - -3. **Fractional Item Addition**: - If an item can't fit entirely, add the fraction of it that fits, and stop when the knapsack is full. - -### Problem Statement: -Given `n` items, each with a weight and value, determine the maximum value that can be obtained by filling a knapsack with a capacity of `W` using the fractional approach. - -### Time Complexity: -- **Best, Average, and Worst Case: $O(n \log n)$** - The time complexity is dominated by the sorting step, where `n` is the number of items. - -### Space Complexity: -- **Space Complexity: $O(n)$** - The space complexity arises from storing the weights, values, and fractions of the items. - -### Example: -Consider the following items: -- Items: `{(value, weight)} = {(60, 10), (100, 20), (120, 30)}` -- Knapsack capacity: `W = 50` - -Step-by-Step Execution: - -1. **Sort by value-to-weight ratio**: - - Item 1: `60/10 = 6` - - Item 2: `100/20 = 5` - - Item 3: `120/30 = 4` - Sorted order: Item 1, Item 2, Item 3. - -2. **Add items to knapsack**: - - Add all of Item 1 (weight 10, value 60). - - Add all of Item 2 (weight 20, value 100). - - Add 2/3 of Item 3 (weight 20, value 80). - -Total value = 60 + 100 + 80 = 240. - -### C++ Implementation: -```cpp -#include -#include -#include -using namespace std; - -struct Item { - int value, weight; - Item(int v, int w) : value(v), weight(w) {} -}; - -// Comparator function to sort by value-to-weight ratio -bool compare(Item a, Item b) { - double r1 = (double)a.value / a.weight; - double r2 = (double)b.value / b.weight; - return r1 > r2; -} - -double fractionalKnapsack(int W, vector& items) { - sort(items.begin(), items.end(), compare); - double totalValue = 0.0; - - for (Item& item : items) { - if (W >= item.weight) { - totalValue += item.value; - W -= item.weight; - } else { - totalValue += item.value * ((double) W / item.weight); - break; - } - } - return totalValue; -} - -int main() { - int W = 50; - vector items = {{60, 10}, {100, 20}, {120, 30}}; - cout << "Maximum value in Knapsack = " << fractionalKnapsack(W, items); - return 0; -} -``` - -### Summary: -The Fractional Knapsack Problem is an efficient optimization problem that can be solved using a greedy approach. By selecting items with the highest value-to-weight ratio, the total value in the knapsack can be maximized. This algorithm is useful in resource allocation and financial investments where fractional quantities are allowed. diff --git a/docs/algorithms/greedy-algorithms/Huffman-coding.md b/docs/algorithms/greedy-algorithms/Huffman-coding.md deleted file mode 100644 index 08a93cc61..000000000 --- a/docs/algorithms/greedy-algorithms/Huffman-coding.md +++ /dev/null @@ -1,139 +0,0 @@ ---- - -id: huffman-coding -title: Huffman Coding Algorithm -sidebar_label: Huffman Coding -description: "In this blog post, we'll explore Huffman Coding, a popular lossless data compression algorithm that assigns variable-length codes to input characters based on their frequencies." -tags: [dsa, algorithms, greedy algorithms, compression] - ---- - -### Definition: - -Huffman Coding is a lossless data compression algorithm used to compress data in an optimal way by assigning shorter codes to more frequent characters and longer codes to less frequent ones. It works by constructing a binary tree where the most frequent characters have the shortest binary representations, leading to optimal compression. - -### Characteristics: - -- **Greedy Approach**: - Huffman Coding uses a greedy strategy to build the binary tree. Starting with individual characters and their frequencies, the algorithm greedily selects the two least frequent nodes, merges them into a new node, and repeats the process until a single tree is formed. Each path from the root to a leaf node gives the binary code for a character. - -1. **Calculate Frequencies**: - Count the frequency of each character in the input data. - -2. **Build a Priority Queue**: - Insert all characters into a priority queue (min-heap) based on their frequencies, with the least frequent characters having the highest priority. - -3. **Construct Huffman Tree**: - Repeatedly take two nodes with the lowest frequencies from the priority queue, merge them, and insert the resulting node back into the queue. This process continues until only one node (the root of the Huffman tree) remains. - -4. **Generate Codes**: - Traverse the tree to assign binary codes to characters, with left edges representing a "0" and right edges representing a "1". - -### Problem Statement: - -Given a set of characters and their corresponding frequencies, the task is to build a Huffman tree and generate a binary code for each character such that the total length of the encoded data is minimized. The objective is to compress the input data by replacing each character with its Huffman code. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(N \log N)$** - The time complexity is dominated by the operations on the priority queue (heap), which requires $O(\log N)$ for insertion and extraction. Since there are N nodes to process, the overall complexity is $O(N \log N)$. - -### Space Complexity: - -- **Space Complexity: $O(N)$** - The space complexity is $O(N)$ due to the storage requirements for the priority queue, the Huffman tree, and the encoded character map. - -### Example: - -Consider the following input: - -Characters: `{a, b, c, d, e}` -Frequencies: `{5, 9, 12, 13, 16}` - -Step-by-Step Execution: - -1. **Create Priority Queue (Min-Heap)**: - Insert characters with their frequencies into the min-heap: - - `a(5), b(9), c(12), d(13), e(16)` - -2. **Construct Huffman Tree**: - - Extract the two lowest frequencies (`a=5` and `b=9`), merge them into a new node with frequency `14`. - - Insert the new node back into the min-heap: `{c(12), d(13), e(16), merged(14)}` - - Repeat the process until the entire tree is constructed: - - Merge `c(12)` and `d(13)` into a node with frequency `25`. - - Merge the nodes with frequencies `14` and `16` into `30`. - - Merge `25` and `30` to get the final root with frequency `55`. - -3. **Assign Codes**: - - Traverse the Huffman Tree and assign binary codes to each character: - - `a = 1100`, `b = 1101`, `c = 100`, `d = 101`, `e = 0` - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -// Huffman Tree Node -struct Node { - char data; - int freq; - Node *left, *right; - Node(char data, int freq) { - left = right = nullptr; - this->data = data; - this->freq = freq; - } -}; - -// Comparison object for priority queue -struct compare { - bool operator()(Node* l, Node* r) { - return l->freq > r->freq; - } -}; - -// Print Huffman Codes -void printCodes(Node* root, string str) { - if (!root) return; - if (root->data != '$') cout << root->data << ": " << str << "\n"; - printCodes(root->left, str + "0"); - printCodes(root->right, str + "1"); -} - -// Main Huffman Coding Function -void huffmanCoding(char data[], int freq[], int size) { - priority_queue, compare> minHeap; - - for (int i = 0; i < size; ++i) - minHeap.push(new Node(data[i], freq[i])); - - while (minHeap.size() != 1) { - Node *left = minHeap.top(); minHeap.pop(); - Node *right = minHeap.top(); minHeap.pop(); - - Node* top = new Node('$', left->freq + right->freq); - top->left = left; - top->right = right; - minHeap.push(top); - } - - printCodes(minHeap.top(), ""); -} - -int main() { - char data[] = { 'a', 'b', 'c', 'd', 'e' }; - int freq[] = { 5, 9, 12, 13, 16 }; - - int size = sizeof(data) / sizeof(data[0]); - huffmanCoding(data, freq, size); - - return 0; -} -``` - -### Summary: - -Huffman Coding is a widely used greedy algorithm that provides optimal data compression by assigning variable-length codes to characters based on their frequencies. The algorithm constructs a binary tree to represent the characters, ensuring that the most frequent characters have the shortest codes. It is used in file compression formats such as ZIP and in transmission protocols. The algorithm runs in $O(N \log N)$ time, making it efficient for practical use cases in data compression and communication systems. \ No newline at end of file diff --git a/docs/algorithms/greedy-algorithms/Job-sequencing-problem.md b/docs/algorithms/greedy-algorithms/Job-sequencing-problem.md deleted file mode 100644 index 57051b451..000000000 --- a/docs/algorithms/greedy-algorithms/Job-sequencing-problem.md +++ /dev/null @@ -1,130 +0,0 @@ ---- - -id: job-sequencing -title: Job Sequencing Algorithm -sidebar_label: Job Sequencing -description: "In this blog post, we'll explore the Job Sequencing problem, a classical greedy algorithm that schedules jobs within their deadlines to maximize profit." -tags: [dsa, algorithms, greedy algorithms, scheduling] - ---- - -### Definition: - -Job Sequencing is a problem in which we aim to schedule a set of jobs, each with a deadline and profit, to maximize the total profit while ensuring that all scheduled jobs are completed before their respective deadlines. It uses a greedy approach to prioritize jobs with higher profits and attempts to place each job within the latest possible available time slot, avoiding conflicts. - -### Characteristics: - -- **Greedy Approach**: - Job Sequencing employs a greedy strategy to maximize profit. It first sorts the jobs by their profits in descending order, then attempts to assign each job to a time slot before its deadline if available. - -1. **Sort by Profit**: - Arrange the jobs in descending order of profit, prioritizing higher-profit jobs. - -2. **Assign Jobs to Slots**: - For each job, try to assign it to the latest available slot before its deadline. If no such slot is free, discard the job. - -3. **Maximize Profit**: - By selecting jobs with the highest profit first and assigning them to valid slots, the algorithm ensures that the total profit is maximized. - -### Problem Statement: - -Given `N` jobs, where each job has a profit and a deadline, the goal is to schedule as many jobs as possible such that each job is finished before its deadline and the total profit is maximized. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(N \log N)$** - Sorting the jobs by profit takes $O(N \log N)$. Assigning each job to a slot takes $O(N)$ in the worst case, making the overall time complexity $O(N \log N)$. - -### Space Complexity: - -- **Space Complexity: $O(N)$** - The space complexity is $O(N)$ due to the storage needed for tracking available slots and storing the job sequence. - -### Example: - -Consider the following input: - -Jobs: `{Job1, Job2, Job3, Job4, Job5}` -Deadlines: `{2, 1, 2, 1, 3}` -Profits: `{100, 19, 27, 25, 15}` - -Step-by-Step Execution: - -1. **Sort by Profit**: - Arrange jobs in descending order of profit: - - `Job1(100), Job3(27), Job4(25), Job2(19), Job5(15)` - -2. **Assign Jobs to Slots**: - - Assign `Job1` to the latest available slot before its deadline (Slot 2). - - Assign `Job3` to the latest available slot before its deadline (Slot 2 is taken, assign to Slot 1). - - Assign `Job4` to the latest available slot before its deadline (Slot 1 is taken, discard). - - Assign `Job2` to Slot 1 (Slot 1 is taken, discard). - - Assign `Job5` to Slot 3. - -3. **Final Sequence**: - - Job Sequence: `{Job3, Job1, Job5}` - - Total Profit: $27 + 100 + 15 = 142$ - -### C++ Implementation: - -```cpp -#include -#include -using namespace std; - -// A structure to represent a job -struct Job { - int id; // Job ID - int deadline; // Deadline of job - int profit; // Profit if the job is completed -}; - -// Function to schedule jobs to maximize profit -bool comparison(Job a, Job b) { - return (a.profit > b.profit); -} - -void jobSequencing(Job arr[], int n) { - // Sort jobs by decreasing order of profit - sort(arr, arr + n, comparison); - - int result[n]; // To store result (sequence of jobs) - bool slot[n]; // To keep track of free time slots - - // Initialize all slots as free - for (int i = 0; i < n; i++) slot[i] = false; - - // Iterate through all given jobs - for (int i = 0; i < n; i++) { - // Find a free slot for this job (starting from the last possible slot) - for (int j = min(n, arr[i].deadline) - 1; j >= 0; j--) { - // If the slot is free, assign this job to the slot - if (slot[j] == false) { - result[j] = i; // Add this job to result - slot[j] = true; // Mark this slot as occupied - break; - } - } - } - - // Print the result - for (int i = 0; i < n; i++) { - if (slot[i]) { - cout << "Job " << arr[result[i]].id << " "; - } - } - cout << endl; -} - -int main() { - Job arr[] = { {1, 2, 100}, {2, 1, 19}, {3, 2, 27}, {4, 1, 25}, {5, 3, 15} }; - int n = sizeof(arr) / sizeof(arr[0]); - jobSequencing(arr, n); - return 0; -} -``` - -### Summary: - -Job Sequencing is an efficient greedy algorithm for scheduling jobs with deadlines to maximize profit. By selecting jobs in descending order of profit and assigning them to the latest possible time slots, it ensures maximum profit. The time complexity of the algorithm is $O(N \log N)$, making it suitable for practical scheduling and optimization problems in various fields like production management and task scheduling. - diff --git "a/docs/algorithms/greedy-algorithms/Prim\342\200\231s-Minimum-Spanning-Tree.md" "b/docs/algorithms/greedy-algorithms/Prim\342\200\231s-Minimum-Spanning-Tree.md" deleted file mode 100644 index dfde122e6..000000000 --- "a/docs/algorithms/greedy-algorithms/Prim\342\200\231s-Minimum-Spanning-Tree.md" +++ /dev/null @@ -1,149 +0,0 @@ ---- -id: prims-mst -title: Prim's Minimum Spanning Tree (MST) Algorithm -sidebar_label: Prim's MST -description: "In this blog post, we'll explore Prim's Algorithm, a greedy algorithm used to find the Minimum Spanning Tree (MST) of a weighted undirected graph." -tags: [dsa, algorithms, greedy algorithms, graph algorithms] ---- - -### Definition: -Prim's Minimum Spanning Tree (MST) is a greedy algorithm that finds the Minimum Spanning Tree for a weighted undirected graph. The MST is a subset of the graph that includes all the vertices and the minimum possible total edge weight without forming any cycles. Prim's algorithm starts with an arbitrary node and grows the MST by adding the shortest edge from the tree to a new vertex, ensuring all vertices are eventually included. - -### Characteristics: -- **Greedy Approach**: - Prim's algorithm is a greedy algorithm that always selects the smallest edge connecting a vertex in the MST to a vertex outside the MST. This process continues until all vertices are included. - -- **Graph Representation**: - Prim's algorithm can be implemented using an adjacency matrix or an adjacency list, with priority queues (min-heaps) used to efficiently retrieve the next minimum edge. - -- **Connectivity Requirement**: - The graph must be connected; otherwise, an MST cannot be formed for the entire graph. - -### Steps Involved: -1. **Initialize**: - Start with an arbitrary vertex, mark it as part of the MST, and initialize the cost of reaching each vertex with the weight of the edges. - -2. **Pick the Minimum Edge**: - Select the edge with the smallest weight that connects a vertex in the MST to a vertex outside the MST. - -3. **Add to MST**: - Add the selected vertex to the MST, update the weights of the adjacent vertices, and repeat until all vertices are included. - -### Problem Statement: -Given a connected weighted graph, find the Minimum Spanning Tree (MST) using Prim's algorithm. The objective is to minimize the sum of the edge weights in the spanning tree while ensuring that all vertices are included and no cycles are formed. - -### Time Complexity: -- **Best, Average, and Worst Case: $O(E \log V)$** - The time complexity depends on the priority queue operations for retrieving and updating the minimum edge, where $E$ is the number of edges, and $V$ is the number of vertices. Using a binary heap, the complexity is $O(E \log V)$. - -### Space Complexity: -- **Space Complexity: $O(V)$** - The space complexity is dominated by the storage of the graph's adjacency list and the auxiliary arrays for tracking the MST. - -### Example: -Consider the following graph: -``` - 2 3 - A---B-------C - | / | - 6| /1 5| - |/ | - D-----------E - 4 -``` -Vertices: `{A, B, C, D, E}` -Edges: `{(A-B, 2), (A-D, 6), (B-C, 3), (B-D, 1), (C-E, 5), (D-E, 4)}` - -Step-by-Step Execution: - -1. **Start from vertex A**: - - Include vertex A in the MST. - - Select edge A-B (weight 2) as the minimum. - -2. **Add vertex B to the MST**: - - Select edge B-D (weight 1) as the minimum. - -3. **Add vertex D to the MST**: - - Select edge D-E (weight 4) as the minimum. - -4. **Add vertex E to the MST**: - - Select edge B-C (weight 3) as the minimum. - -5. **Add vertex C to the MST**: - Now all vertices are included, and the MST is formed with total weight = 2 + 1 + 4 + 3 = 10. - -### C++ Implementation: -```cpp -#include -#include -#include -using namespace std; - -// Pair structure: (weight, vertex) -typedef pair PII; - -void primMST(vector>& adj, int V) { - priority_queue, greater> pq; - vector key(V, INT_MAX); // Used to store the minimum weight for each vertex - vector inMST(V, false); // To track vertices in MST - vector parent(V, -1); // To store MST edges - int src = 0; // Start from vertex 0 - pq.push({0, src}); - key[src] = 0; - - while (!pq.empty()) { - int u = pq.top().second; - pq.pop(); - inMST[u] = true; - - // Traverse all adjacent vertices of u - for (auto &edge : adj[u]) { - int v = edge.second; - int weight = edge.first; - - // If v is not in MST and weight of (u, v) is smaller than key[v] - if (!inMST[v] && key[v] > weight) { - key[v] = weight; - pq.push({key[v], v}); - parent[v] = u; // Track the MST path - } - } - } - - // Output the MST - cout << "Edges in MST:\n"; - for (int i = 1; i < V; i++) { - cout << parent[i] << " - " << i << " : " << key[i] << "\n"; - } -} - -int main() { - int V = 5; // Number of vertices - vector> adj(V); - - // Graph with weighted edges - adj[0].push_back({2, 1}); // A-B - adj[1].push_back({2, 0}); // B-A - - adj[0].push_back({6, 3}); // A-D - adj[3].push_back({6, 0}); // D-A - - adj[1].push_back({3, 2}); // B-C - adj[2].push_back({3, 1}); // C-B - - adj[1].push_back({1, 3}); // B-D - adj[3].push_back({1, 1}); // D-B - - adj[2].push_back({5, 4}); // C-E - adj[4].push_back({5, 2}); // E-C - - adj[3].push_back({4, 4}); // D-E - adj[4].push_back({4, 3}); // E-D - - primMST(adj, V); - return 0; -} -``` - -### Summary: -Prim's MST algorithm is an efficient greedy approach to finding the Minimum Spanning Tree in a weighted undirected graph. By selecting the smallest edge at each step, it ensures that the MST is built with the least total weight, avoiding cycles. The time complexity of the algorithm is $O(E \log V)$, making it suitable for large, dense graphs. Prim's algorithm is used in various network design applications, including telecommunications, electrical grids, and transportation networks. \ No newline at end of file diff --git a/docs/algorithms/greedy-algorithms/Problem-Practice.md b/docs/algorithms/greedy-algorithms/Problem-Practice.md deleted file mode 100644 index 6f6d7c418..000000000 --- a/docs/algorithms/greedy-algorithms/Problem-Practice.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: Practice-Problems-on-greedy-algorithms -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 2 -description: Practice problems for Greedy Algorithms, categorized by difficulty and topic. These problems help in understanding the practical application of greedy strategies in solving algorithmic challenges. -tags: [DSA, algorithms, greedy] ---- - -## Practice Problems on Greedy Algorithms - -Greedy algorithms are a type of algorithmic strategy where decisions are made step-by-step, taking the most optimal choice at each stage, hoping that the end result is the best overall solution. While greedy algorithms may not always guarantee the most optimal solution for all problems, they often work well for a variety of optimization problems. Here’s a collection of problems to help you practice and sharpen your skills in greedy algorithms. These problems are categorized by difficulty level, allowing you to progressively build your understanding. - ---- - -### Basic Problems: - -These problems introduce you to foundational greedy techniques and focus on simple scenarios where a locally optimal choice leads to the globally optimal solution. Ideal for beginners, these problems help you build intuition for identifying when greedy algorithms can be applied effectively. - -- **[Activity Selection Problem](https://leetcode.com/problems/maximum-number-of-non-overlapping-intervals/):** - The classic interval scheduling problem where you must select the maximum number of non-overlapping intervals. This is a fundamental example of applying greedy choices to select the most optimal sequence of activities. - -- **[Coin Change](https://leetcode.com/problems/coin-change/):** - Solve the minimum number of coins required to make a certain amount. While this problem is often solved using dynamic programming, it can also introduce you to scenarios where greedy strategies might work. - -- **[Assign Cookies](https://leetcode.com/problems/assign-cookies/):** - Distribute cookies to children in the most optimal way by satisfying as many children as possible with the given resources. This problem highlights resource allocation techniques using greedy methods. - -- **[Jump Game](https://leetcode.com/problems/jump-game/):** - Determine if you can reach the last index of an array based on jump lengths. This problem tests your ability to make greedy decisions based on the farthest point you can reach at each step. - -- **[Minimum Platforms](https://leetcode.com/problems/minimum-platforms/):** - Find the minimum number of platforms required at a railway station to accommodate trains without any overlap in their schedules. This problem is an application of interval management using greedy algorithms. - ---- - -### Intermediate Problems: - -Once you've grasped the basics, these problems offer more complex scenarios where greedy strategies can be applied. They may involve multiple decisions or constraints, requiring a deeper understanding of when and how to apply the greedy method. - -- **[Interval Scheduling Maximization](https://leetcode.com/problems/non-overlapping-intervals/):** - This problem is similar to activity selection but with additional constraints. You need to remove the minimum number of intervals to prevent overlaps, requiring you to make choices that maximize the number of remaining intervals. - -- **[Huffman Coding](https://www.geeksforgeeks.org/huffman-coding-greedy-algo-3/):** - A popular application of greedy algorithms, Huffman coding generates the most efficient (shortest) prefix-free binary codes for characters based on their frequencies. It demonstrates how greedy algorithms can optimize compression techniques. - -- **[Maximum Profit in Job Scheduling](https://leetcode.com/problems/maximum-profit-in-job-scheduling/):** - Schedule jobs to maximize profit, considering job durations and deadlines. This problem requires careful planning to balance job selections and maximize earnings over time. - -- **[Gas Station](https://leetcode.com/problems/gas-station/):** - Determine if you can complete a circular route given a certain amount of gas at each station and the distance between them. This problem requires you to optimize your decisions to ensure you never run out of fuel. - -- **[Partition Labels](https://leetcode.com/problems/partition-labels/):** - Partition a string into as many parts as possible such that each letter appears in at most one part. This problem showcases how greedy algorithms can be used to create optimal divisions with specific constraints. - ---- - -### Advanced Problems: - -These are more challenging problems that require a solid understanding of greedy techniques. They often involve multiple layers of decision-making and constraints that demand careful consideration and application of the greedy approach. - -- **[Minimum Number of Arrows to Burst Balloons](https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/):** - Given a number of balloons, determine the minimum number of arrows required to burst all of them. This problem builds upon interval management techniques and introduces complexity in the form of overlapping intervals. - -- **[Candy](https://leetcode.com/problems/candy/):** - Distribute candy to children based on their ratings in a way that satisfies certain conditions. This problem tests your ability to apply greedy choices to balance multiple constraints over an entire sequence. - -- **[Merge Intervals](https://leetcode.com/problems/merge-intervals/):** - Merge overlapping intervals into as few as possible. It’s another variation of the interval scheduling problem but with the added complexity of modifying intervals as they overlap. - -- **[Stickers to Spell Word](https://leetcode.com/problems/stickers-to-spell-word/):** - Given a set of stickers and a target word, determine the minimum number of stickers needed to form the word. This problem challenges you to apply greedy choices in the context of resource management. - -- **[Find Minimum in Rotated Sorted Array II](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/):** - Find the minimum element in a rotated sorted array that may contain duplicates. This problem is a test of how greedy algorithms can be applied to search and optimization problems. - ---- - -### Challenges: - -For those looking to push their limits, these problems present even more difficult scenarios where the optimal greedy strategy may not be immediately obvious. They require a deep understanding of both the problem and the algorithmic strategy to succeed. - -- **[Minimum Cost to Hire K Workers](https://leetcode.com/problems/minimum-cost-to-hire-k-workers/):** - Hire workers with different skill levels and wages, while minimizing the cost of hiring exactly K workers. This problem involves balancing multiple factors, such as skill-to-wage ratios, using a greedy strategy. - -- **[Job Sequencing Problem](https://www.geeksforgeeks.org/job-sequencing-problem/):** - Given a set of jobs, each with a deadline and profit, find the sequence of jobs that maximizes profit while adhering to the deadlines. This is a classic scheduling problem requiring the application of greedy choices to optimize profits. - -- **[Largest Number](https://leetcode.com/problems/largest-number/):** - Rearrange a list of numbers to form the largest possible number. This problem tests how greedy algorithms can be applied to sorting and number manipulation in order to maximize the result. - ---- - -These problems are excellent practice for interviews and competitive programming, where greedy algorithms are frequently used. Be sure to analyze the problem constraints carefully to ensure that a greedy approach will lead to the optimal solution. Happy coding! diff --git a/docs/algorithms/greedy-algorithms/_category_.json b/docs/algorithms/greedy-algorithms/_category_.json deleted file mode 100644 index f858eda7f..000000000 --- a/docs/algorithms/greedy-algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Greedy Algorithms", - "position": 7, - "link": { - "type": "generated-index", - "description": "Greedy algorithms are a paradigm for solving optimization problems. The main idea behind a greedy algorithm is to make a sequence of choices, each of which looks the best at the moment. It chooses the optimal solution at every step with the hope that these local optimal choices will lead to a global optimal solution." - } -} diff --git a/docs/algorithms/greedy-algorithms/activity-selection.md b/docs/algorithms/greedy-algorithms/activity-selection.md deleted file mode 100644 index a7b0c9443..000000000 --- a/docs/algorithms/greedy-algorithms/activity-selection.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: activity-selection -title: Activity Selection Problem -sidebar_label: Activity Selection -description: "In this blog post, we'll explore the Activity Selection Problem, a classic greedy algorithm used to select the maximum number of activities that don't overlap." -tags: [dsa, algorithms, greedy algorithms, activity selection] ---- - -### Definition: - -The Activity Selection Problem is about selecting the maximum number of activities that don't overlap, given their start and finish times. The goal is to maximize the number of activities that can be performed by a single person or machine. - -### Characteristics: - -- **Greedy Approach**: - The greedy approach selects the next activity that finishes first, ensuring that the maximum number of activities are completed. This is done by: - 1. **Sorting Activities**: - Sort the activities based on their finish times. - 2. **Selecting Activities**: - Iterate through the sorted activities and select an activity if it starts after or when the last selected activity finishes. - -### Problem Statement: - -You are given `N` activities, each with a start time `s_i` and finish time `f_i`. Your task is to select the maximum number of activities that can be performed by a single person or machine. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(N \log N)$** - The dominant operation is sorting the activities based on their finish times. - -### Space Complexity: - -- **Space Complexity: $O(1)$** - Only a constant amount of extra space is required. - -### Example: - -Consider the following activities: - -- Activity 1: Start = 0, Finish = 6 -- Activity 2: Start = 1, Finish = 4 -- Activity 3: Start = 3, Finish = 5 -- Activity 4: Start = 5, Finish = 7 -- Activity 5: Start = 8, Finish = 9 -- Activity 6: Start = 5, Finish = 9 - -**Step-by-Step Execution:** - -1. **Sort by Finish Times**: - - Activity 2 (1, 4) - - Activity 3 (3, 5) - - Activity 4 (5, 7) - - Activity 1 (0, 6) - - Activity 5 (8, 9) - - Activity 6 (5, 9) - -2. **Select Activities**: - - Select Activity 2: (1, 4) - - Select Activity 4: (5, 7) - - Select Activity 5: (8, 9) - -Thus, the maximum number of activities that can be selected is 3. - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -struct Activity { - int start, finish; -}; - -bool compare(Activity a, Activity b) { - return a.finish < b.finish; -} - -void activitySelection(vector& activities) { - sort(activities.begin(), activities.end(), compare); - - int n = activities.size(); - cout << "Selected Activities: " << endl; - - // The first activity always gets selected - int i = 0; - cout << "(" << activities[i].start << ", " << activities[i].finish << ") "; - - // Check the rest of the activities - for (int j = 1; j < n; j++) { - if (activities[j].start >= activities[i].finish) { - cout << "(" << activities[j].start << ", " << activities[j].finish << ") "; - i = j; // Update the last selected activity - } - } -} - -int main() { - vector activities = {{0, 6}, {1, 4}, {3, 5}, {5, 7}, {8, 9}, {5, 9}}; - activitySelection(activities); - return 0; -} -``` \ No newline at end of file diff --git a/docs/algorithms/greedy-algorithms/commonly-asked-greedy-questions.md b/docs/algorithms/greedy-algorithms/commonly-asked-greedy-questions.md deleted file mode 100644 index dc80ff177..000000000 --- a/docs/algorithms/greedy-algorithms/commonly-asked-greedy-questions.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -id: commonly-asked-greedy-questions -title: Commonly asked Greedy questions -sidebar_label: Commonly asked Greedy questions -description: "This document explores various commonly greedy algorithm patterns, highlighting their definitions, characteristics, and common applications." -tags: [dsa, faq, algorithms, greedy algorithms] ---- - -## 1. Huffman Coding - -### Definition: -Huffman Coding is a method used for lossless data compression. It assigns variable-length codes to input characters, with shorter codes assigned to more frequent characters. - -### Characteristics: -- **Building a Min-Heap**: Create a min-heap to store characters and their frequencies. -- **Tree Structure**: Combine the two least frequent nodes iteratively to build a binary tree. -- **Prefix Codes**: The binary representation of characters is derived from the tree, ensuring that no code is a prefix of another. - -### Applications: -- Data compression (e.g., ZIP files) -- Encoding for transmission - ---- - -## 2. Prim’s Algorithm - -### Definition: -Prim’s Algorithm finds the Minimum Spanning Tree (MST) for a weighted undirected graph. - -### Characteristics: -- **Start with a Single Vertex**: Initialize the tree with one vertex. -- **Add the Cheapest Edge**: At each step, add the cheapest edge connecting a vertex in the tree to one outside it. -- **Repeat**: Continue until all vertices are included in the MST. - -### Applications: -- Network design -- Approximation algorithms for NP-hard problems - ---- - -## 3. Kruskal’s Algorithm - -### Definition: -Kruskal’s Algorithm is another method to find the Minimum Spanning Tree of a graph. - -### Characteristics: -- **Sort Edges**: Begin by sorting all edges in ascending order of their weight. -- **Add Edges**: Add edges to the MST one by one, ensuring no cycles are formed using union-find data structures. -- **Complete MST**: Repeat until you have `V-1` edges (where `V` is the number of vertices). - -### Applications: -- Network routing -- Cluster analysis - ---- - -## 4. Fractional Knapsack Problem - -### Definition: -The Fractional Knapsack Problem allows taking fractions of an item to maximize the total value in a knapsack. - -### Characteristics: -- **Value-to-Weight Ratio**: Calculate the ratio for each item. -- **Sorting**: Sort items by their value-to-weight ratio. -- **Greedy Selection**: Add as much of the highest ratio item as possible until the knapsack is full. - -### Applications: -- Resource allocation -- Budget management - ---- - -## 5. Coin Change Problem - -### Definition: -The Coin Change Problem aims to find the minimum number of coins needed to make a certain amount using given denominations. - -### Characteristics: -- **Greedy Approach**: Use the largest denomination first. -- **Reduction**: Continue until the remaining amount is zero. -- **Optimality**: Works optimally for standard denominations (like US coins). - -### Applications: -- Currency exchange -- Financial transactions - ---- - -## 6. Minimum Number of Platforms - -### Definition: -The Minimum Number of Platforms problem determines how many platforms are required at a railway station to accommodate all trains at their arrival and departure times. - -### Characteristics: -- **Sorting Events**: Sort arrival and departure times. -- **Tracking Platforms**: Use a greedy approach to track the number of trains at any given time and update the platform requirement. - -### Applications: -- Scheduling at transportation hubs -- Event management - ---- - -## 7. Staircase Problem - -### Definition: -The Staircase Problem involves finding the number of ways to reach the top of a staircase with `N` steps when you can take either 1 or 2 steps at a time. - -### Characteristics: -- **Recurrence Relation**: The number of ways to reach the nth step can be defined as `ways(n) = ways(n-1) + ways(n-2)`. -- **Dynamic Programming**: Although greedy, can also be solved using dynamic programming for optimization. - -### Applications: -- Combinatorial problems -- Dynamic programming practice - ---- - -## 8. Best Time to Buy and Sell Stock - -### Definition: -This problem involves determining the maximum profit you can achieve by buying and selling a stock once, given an array of stock prices. - -### Characteristics: -- **Tracking Minimum Price**: Keep track of the minimum price encountered so far. -- **Calculating Profit**: For each price, calculate the potential profit and update the maximum profit if it exceeds the current maximum. - -### Applications: -- Stock market analysis -- Financial modeling - ---- - -## 9. Minimize Maximum Distance to Assign Tasks - -### Definition: -Given a set of workers and tasks, this problem aims to assign tasks in a way that minimizes the maximum distance any worker has to travel. - -### Characteristics: -- **Sorting**: Sort workers and tasks based on their distances. -- **Greedy Assignment**: Assign tasks to the nearest available worker to minimize the maximum distance. - -### Applications: -- Task scheduling -- Logistics optimization - ---- - -## 10. Rearranging Coins Problem - -### Definition: -This problem involves determining if you can rearrange a set of coins to satisfy specific conditions or form valid sequences. - -### Characteristics: -- **Greedy Grouping**: Use a greedy approach to group or arrange coins based on given criteria. -- **Condition Checking**: Ensure conditions are met after each rearrangement or assignment. - -### Applications: -- Resource management -- Game theory - ---- - -These greedy algorithms and patterns demonstrate efficient problem-solving techniques for various applications in computer science and operations research. diff --git a/docs/algorithms/greedy-algorithms/fractional-knapsack.md b/docs/algorithms/greedy-algorithms/fractional-knapsack.md deleted file mode 100644 index d518d27a1..000000000 --- a/docs/algorithms/greedy-algorithms/fractional-knapsack.md +++ /dev/null @@ -1,179 +0,0 @@ ---- -id: fractional-knapsack-2 -title: Fractional Knapsack Problem 2 -sidebar_label: Fractional Knapsack -description: "In this blog post, we'll explore the Fractional Knapsack Problem, a greedy algorithm used to maximize the value of items that can be carried in a knapsack with a weight limit." -tags: [dsa, algorithms, greedy algorithms, knapsack problem, javascript, c++] ---- - - -### Definition: - -The Fractional Knapsack Problem is a variation of the classic knapsack problem where we can take fractions of an item. The objective is to maximize the total value of items carried in a knapsack with a given capacity. In contrast to the 0/1 Knapsack Problem, where you must either take the entire item or leave it, the fractional knapsack allows you to take any portion of an item. - -### Characteristics: - -- **Greedy Approach**: - The greedy approach selects items based on their value-to-weight ratio, taking as much of the item as possible starting with the one that has the highest ratio, until the knapsack reaches its capacity. - To solve the Fractional Knapsack Problem, we use the greedy approach with the value-to-weight ratio as the heuristic: -1. **Sort Items by Value-to-Weight Ratio:** - For each item, compute the ratio `v_i / w_i` (value divided by weight). Sort the items in decreasing order of this ratio. Items with a higher value-to-weight ratio will be selected first, as they offer the most value per unit of weight. -2. **Select Items Greedily:** - Start with the item that has the highest value-to-weight ratio and add it to the knapsack. If the item fits entirely, include it. If it doesn't, take the fraction of the item that fits in the remaining capacity of the knapsack. Continue this process until the knapsack is full or no more items can be added. - -- **Fractional Items**: - - Unlike the 0/1 knapsack, where only whole items can be taken, here fractions of items are allowed. If an item cannot be entirely included, a fraction of it is added proportional to the remaining capacity. - -- **Unbounded Solution**: - - This problem allows for the selection of the most valuable fractions of items, leading to the optimal solution in a greedy manner. - -### Problem Statement: - -You are given `N` items, each with a given weight `w_i` and value `v_i`, and a knapsack with a maximum capacity `W`. The objective is to maximize the total value of the items placed in the knapsack. However, in the Fractional Knapsack Problem, you are allowed to take fractions of an item. Your goal is to find the optimal way to fill the knapsack to maximize the total value without exceeding the capacity `W`. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(N log N)$** -The dominant operation is sorting the items based on their value-to-weight ratio, which takes $O(N log N)$, where N is the number of items. - -### Space Complexity: - -- **Space Complexity: $O(N)$** -Space is required for the list of items and auxiliary data structures for sorting, resulting in $O(N)$ space complexity. - -### Example: - -Consider the following example where we have three items: - -- Item 1: Value = 60, Weight = 10 -- Item 2: Value = 100, Weight = 20 -- Item 3: Value = 120, Weight = 30 -The capacity of the knapsack is `W = 50`. - -Step-by-Step Execution: - -1. Value-to-Weight Ratios: -- Item 1: `60/10=6` -- Item 2: `100/20=5` -- Item 3: `120/30=4` - -2. Sort by Ratios: -Based on the value-to-weight ratio, the items are already sorted as: -- Item 1 (ratio = 6) -- Item 2 (ratio = 5) -- Item 3 (ratio = 4) - -3. Add Items to the Knapsack: -- Item 1: Add the whole item since its weight is 10, which is less than the knapsack's remaining capacity (50). Total weight now = 10, total value = 60. -- Item 2: Add the whole item since its weight is 20. Total weight now = 30, total value = 160. -- Item 3: Only 20 units of weight can be added (since the remaining capacity is 20). So, we take a fraction of Item 3: -`Value added from Item 3 = 120/30 × 20 = 80` -Total weight now = 50, total value = 240. - -Thus, the maximum value that can be obtained is 240. - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -struct Item { - int value, weight; - Item(int value, int weight) : value(value), weight(weight) {} -}; - -bool compare(Item a, Item b) { - double r1 = (double)a.value / a.weight; - double r2 = (double)b.value / b.weight; - return r1 > r2; -} - -double fractionalKnapsack(int W, vector& items) { - sort(items.begin(), items.end(), compare); - - int currentWeight = 0; - double totalValue = 0.0; - - for (Item item : items) { - if (currentWeight + item.weight <= W) { - currentWeight += item.weight; - totalValue += item.value; - } else { - int remainingWeight = W - currentWeight; - totalValue += item.value * ((double)remainingWeight / item.weight); - break; - } - } - - return totalValue; -} - -int main() { - int W = 50; // Capacity of knapsack - vector items = { - {60, 10}, {100, 20}, {120, 30} - }; - - double maxValue = fractionalKnapsack(W, items); - cout << "Maximum value we can obtain: " << maxValue << endl; - - return 0; -} -``` - -### JavaScript Implementation -```js -class Item { - constructor(value, weight) { - this.value = value; - this.weight = weight; - } -} - -// Comparison function to sort items based on value/weight ratio -function compare(a, b) { - let r1 = a.value / a.weight; - let r2 = b.value / b.weight; - return r1 > r2 ? -1 : 1; -} - -// Function to calculate the maximum value we can obtain in the fractional knapsack problem -function fractionalKnapsack(W, items) { - items.sort(compare); // Sort items by value/weight ratio - - let currentWeight = 0; - let totalValue = 0.0; - - for (let item of items) { - if (currentWeight + item.weight <= W) { - currentWeight += item.weight; - totalValue += item.value; - } else { - let remainingWeight = W - currentWeight; - totalValue += item.value * (remainingWeight / item.weight); - break; - } - } - - return totalValue; -} - -// Example Usage -let W = 50; // Capacity of the knapsack -let items = [ - new Item(60, 10), - new Item(100, 20), - new Item(120, 30) -]; - -let maxValue = fractionalKnapsack(W, items); -console.log("Maximum value we can obtain: " + maxValue); - -``` - -### Summary: - -The Fractional Knapsack Problem is a classic example of a greedy algorithm. It efficiently maximizes the value of the items that can be carried in the knapsack by selecting items based on their value-to-weight ratio. This algorithm is especially useful when fractional items can be taken and provides the optimal solution with a time complexity of $O(N log N)$. The fractional knapsack finds applications in resource allocation, budget management, and similar optimization problems. diff --git a/docs/algorithms/greedy-algorithms/greedy-theory.md b/docs/algorithms/greedy-algorithms/greedy-theory.md deleted file mode 100644 index 163ff1d12..000000000 --- a/docs/algorithms/greedy-algorithms/greedy-theory.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -id: greedy-algorithms-2 -title: greedy Algorithms -sidebar_label: Greedy Algorithms -sidebar_position: 1 -description: Greedy algorithms are a class of algorithms that make the optimal choice at each step with the hope of finding the global optimum -tags: [Competitive Programming,greedy approach,optimization] ---- -# Greedy Algorithms - Theory - -## Introduction - -Greedy algorithms are a paradigm for solving optimization problems. The main idea behind a greedy algorithm is to make a sequence of choices, each of which looks the best at the moment. It chooses the optimal solution at every step with the hope that these local optimal choices will lead to a global optimal solution. - -Unlike dynamic programming, where you solve every subproblem and then combine the solutions to form the optimal solution for the entire problem, greedy algorithms directly pick what seems to be the best option at each decision point. - -### Characteristics of Greedy Algorithms - -1. **Greedy Choice Property**: A globally optimal solution can be arrived at by making locally optimal choices. The algorithm assumes that by choosing the optimal solution at each step, the overall solution will be optimal. - -2. **Optimal Substructure**: A problem has an optimal substructure if an optimal solution to the problem can be constructed efficiently from optimal solutions of its subproblems. This is necessary for a greedy algorithm to be valid. - -3. **Non-Overlapping Subproblems**: Greedy algorithms generally work well when subproblems don’t overlap (like in dynamic programming), which allows making decisions based only on local information. - -### How Greedy Algorithms Work - -- **Step 1: Greedy Choice**: At each step, choose the best possible option available. This is a local optimization. -- **Step 2: Reduce Problem Size**: After making the choice, reduce the problem size. The remaining subproblem must also satisfy the properties of the greedy approach. -- **Step 3: Repeat**: Repeat the greedy choice step until the problem is reduced to a simple base case. - -### Applications of Greedy Algorithms - -Greedy algorithms are applied to a variety of problems, especially in optimization scenarios: - -1. **Activity Selection Problem**: Selecting the maximum number of activities that don't overlap. -2. **Huffman Coding**: A compression algorithm used for lossless data compression. -3. **Kruskal's and Prim's Algorithm**: Used to find the Minimum Spanning Tree (MST) in a graph. -4. **Dijkstra's Algorithm**: Used to find the shortest path from one source to all other vertices in a graph. - -### Advantages of Greedy Algorithms - -1. **Simple to Implement**: Greedy algorithms are generally easier to code and understand because they follow a straightforward approach. -2. **Efficient**: They tend to run faster compared to other algorithms like dynamic programming due to their simple structure. -3. **Optimal Solutions (if applicable)**: For certain problems, greedy algorithms do give an optimal solution. - -### Limitations - -- **Not Always Optimal**: Greedy algorithms do not guarantee an optimal solution for all problems. In some cases, they might only provide a suboptimal solution. -- **Problem-Specific**: Greedy algorithms work well for problems with specific properties, like the greedy choice property and optimal substructure. Without these properties, greedy algorithms may fail to find the best solution. - -### Greedy vs. Dynamic Programming - -| **Feature** | **Greedy Algorithm** | **Dynamic Programming** | -|--------------------------|------------------------------------------------|---------------------------------------------------| -| **Choice** | Greedy algorithms make a local optimal choice | DP solves all subproblems and combines solutions. | -| **Structure** | No overlapping subproblems | Overlapping subproblems are recomputed. | -| **Use** | Simple and efficient for specific problems | Used for complex problems where greedy fails. | -| **Examples** | Kruskal's MST, Huffman Coding, Dijkstra's | Longest Common Subsequence, Matrix Chain Multiplication | - -### Conclusion - -Greedy algorithms are an efficient approach to solving many problems. However, their applicability is limited to problems that satisfy specific properties like the greedy choice property and optimal substructure. If these properties are absent, dynamic programming or other algorithms should be considered. diff --git a/docs/algorithms/kadane-algorithm/_category_.json b/docs/algorithms/kadane-algorithm/_category_.json deleted file mode 100644 index 901484b18..000000000 --- a/docs/algorithms/kadane-algorithm/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Kadane's Algorithm", - "position": 10, - "link": { - "type": "generated-index", - "description": "Learn the most important and widely used concepts of Kadane's Algorithm." - } - } \ No newline at end of file diff --git a/docs/algorithms/kadane-algorithm/kadane-algo.md b/docs/algorithms/kadane-algorithm/kadane-algo.md deleted file mode 100644 index 90555bb9a..000000000 --- a/docs/algorithms/kadane-algorithm/kadane-algo.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: kadanes-algorithm -sidebar_position: 16 -title: "Kadane's Algorithm" -sidebar_label: Maximum Subarray Sum ---- - -### Definition: - -Kadane's Algorithm is an efficient algorithm to find the maximum sum of a contiguous subarray in an array of integers. It operates by iterating through the array while keeping track of the current subarray sum and the maximum sum encountered so far. - -### Characteristics: - -- **Single-Pass Algorithm**: - The algorithm processes the array in a single pass: - - It iteratively updates the maximum sum of the subarray ending at each position. -- **Linear Time Complexity**: - The algorithm runs in O(N) time, where N is the number of elements in the array. -- **Constant Space Complexity**: - It only requires a few extra variables, resulting in O(1) space complexity. - -### Time Complexity: - -- **Best Case: $O(N)$** - The algorithm processes each element once during the traversal. -- **Average Case: $O(N)$** - It consistently runs in linear time for any arrangement of elements. -- **Worst Case: $O(N)$** - Regardless of the input distribution, the time complexity remains linear. - -### Space Complexity: - -- **Space Complexity: $O(1)$** - The algorithm uses a constant amount of extra space. - -### Approach: - -The algorithm follows these steps: - -1. **Initialization**: - - Initialize two variables `max_current` and `max_global` with the value of the first element. -2. **Traverse the Array**: - - For each element (starting from the second), update `max_current` as the maximum of the current element or the sum of `max_current` and the current element. - - Update `max_global` to be the maximum of `max_global` and `max_current`. -3. **Result**: - - `max_global` holds the maximum sum of the contiguous subarray. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -class Solution { -public: - // Function to find the maximum sum of a contiguous subarray - int maxSubArray(vector& nums) { - int max_current = nums[0], max_global = nums[0]; - - for (int i = 1; i < nums.size(); i++) { - // Update max_current to include current element or start fresh from current element - max_current = max(nums[i], max_current + nums[i]); - - // Update max_global if the current subarray sum is higher - max_global = max(max_global, max_current); - } - - return max_global; - } -}; - -int main() { - vector nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; - - // Create an instance of Solution class - Solution sol; - - // Find the maximum sum of the contiguous subarray - int max_sum = sol.maxSubArray(nums); - - // Print the result - cout << "The maximum sum of the contiguous subarray is: " << max_sum << endl; - - return 0; -} -``` \ No newline at end of file diff --git a/docs/algorithms/mathematics-algorithms/_category_.json b/docs/algorithms/mathematics-algorithms/_category_.json deleted file mode 100644 index 275ec2253..000000000 --- a/docs/algorithms/mathematics-algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Mathematical Algorithms", - "position": 7, - "link": { - "type": "generated-index", - "description": "Mathematical algorithms are essential in computer science for solving problems that require mathematical computations and reasoning. These algorithms are foundational in various applications, from cryptography to statistical analysis, and play a significant role in competitive programming." - } -} \ No newline at end of file diff --git a/docs/algorithms/mathematics-algorithms/discrete-logarithm.md b/docs/algorithms/mathematics-algorithms/discrete-logarithm.md deleted file mode 100644 index 157c96774..000000000 --- a/docs/algorithms/mathematics-algorithms/discrete-logarithm.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: discrete-logarithm -title: "Discrete Logarithm" -sidebar_label: "Discrete Logarithm Problem" -sidebar_position: 6 -description: "An overview of the Discrete Logarithm problem and its applications in cryptography." -tags: [number theory, modular arithmetic, cryptography, competitive programming] ---- - -## Discrete Logarithm Problem - -**Definition:** - -The Discrete Logarithm problem is the reverse of the modular exponentiation problem. Given integers $a$, $b$, and $p$, the discrete logarithm problem involves finding an integer $x$ such that: - -$[a^x = b \ (\text{mod} \ p)]$ - -In simpler terms, we seek to determine the exponent $x$ such that raising $a$ to the power of $x$ modulo $p$ equals $b$. Mathematically, this can be expressed as: - -$[x = \log_a b \ (\text{mod} \ p)]$ - -This problem is considered **computationally hard** for large values of \( p \), which forms the basis of several cryptographic systems, such as the **Diffie-Hellman Key Exchange** and the **ElGamal encryption system**. - -### Code -**Code Implementation in Python:** - -```python -def discrete_logarithm(a, b, p): - """Brute-force approach to solve the discrete logarithm problem. - - Args: - a: The base integer. - b: The result of a^x mod p. - p: The modulus. - - Returns: - The exponent x such that a^x ≡ b (mod p), or -1 if no solution is found. - """ - for x in range(p): - if pow(a, x, p) == b: - return x - return -1 -``` -**Code Implementation in C++:** -```cpp -#include -using namespace std; - -int discrete_logarithm(int a, int b, int p) { - // Brute-force approach - for (int x = 0; x < p; x++) { - if (pow(a, x) % p == b % p) { - return x; - } - } - return -1; -} - -int main() { - int a = 5, b = 3, p = 23; - int x = discrete_logarithm(a, b, p); - if (x != -1) { - cout << "The discrete logarithm x such that " << a << "^x ≡ " << b << " (mod " << p << ") is " << x << endl; - } else { - cout << "No solution found." << endl; - } - return 0; -} -``` -**Code Implementation in Java:** -```java -import java.util.Scanner; - -public class DiscreteLogarithm { - public static int discreteLogarithm(int a, int b, int p) { - for (int x = 0; x < p; x++) { - if (Math.pow(a, x) % p == b % p) { - return x; - } - } - return -1; - } - - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - - System.out.print("Enter the base (a): "); - int a = scanner.nextInt(); - - System.out.print("Enter the result (b): "); - int b = scanner.nextInt(); - - System.out.print("Enter the modulus (p): "); - int p = scanner.nextInt(); - - int result = discreteLogarithm(a, b, p); - - if (result != -1) { - System.out.println("The discrete logarithm is: " + result); - } else { - System.out.println("No solution found."); - } - } -} -``` -### Explanation of the Code: -**discrete_logarithm** : This function brute-forces the solution by checking all possible values of -$x$ until it finds one that satisfies -$a^x = b \ (\text{mod} \ p)$. -This is inefficient for large -$p$, and other algorithms like Baby-step Giant-step or Pollard's Rho can be used to solve this problem more efficiently. - -**Main Functions**: In both the C++ and Java versions, the program prompts the user to enter values for -$a$, -$b$, and -$p$, and then attempts to find -$x$ using the discrete logarithm function. - -### Example Usage: -Run the program and enter the values for -$a$, $b$, and -$p$. -For example, if you enter $a$=5, $b$=3, and -$p$=23, the output will be the value of -$x$ that satisfies the equation. - -### Applications in Cryptography: -The Discrete Logarithm problem has several critical applications in modern cryptographic systems: - -Diffie-Hellman Key Exchange: The Diffie-Hellman Key Exchange protocol uses the discrete logarithm problem to enable secure key exchange over an insecure channel without revealing the key to a third party. - -ElGamal Encryption: ElGamal encryption relies on the hardness of solving the discrete logarithm problem to provide secure encryption of messages. - -Digital Signatures: Some digital signature schemes, like the Digital Signature Algorithm (DSA), are based on the difficulty of the discrete logarithm problem, ensuring the security of the signatures. - -Public-Key Cryptosystems: Public-key systems that rely on discrete logarithms are secure because of the computational difficulty of solving the problem, making it an essential foundation of modern cryptography. \ No newline at end of file diff --git a/docs/algorithms/mathematics-algorithms/euclidean-algorithm.md b/docs/algorithms/mathematics-algorithms/euclidean-algorithm.md deleted file mode 100644 index 56e573e46..000000000 --- a/docs/algorithms/mathematics-algorithms/euclidean-algorithm.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: euclidean-algorithm -title: Euclidean Algorithm in Number Theory -sidebar_label: Euclidean Algorithm -sidebar_position: 1 -description: Explanation and implementation of the Euclidean Algorithm to find the GCD of two numbers. -tags: [number-theory, gcd, algorithms] ---- - -# Euclidean Algorithm - -The Euclidean Algorithm is an efficient method for finding the Greatest Common Divisor (GCD) of two integers. It uses the principle that the GCD of two numbers does not change if the larger number is replaced by its remainder when divided by the smaller number. - -## Steps to Implement -1. Divide the larger number by the smaller number and find the remainder. -2. Replace the larger number with the smaller number and the smaller number with the remainder. -3. Repeat until the remainder is 0. The non-zero remainder is the GCD. - -## Code Examples - -### C++ Implementation - -```cpp -#include -using namespace std; - -int gcd(int a, int b) { - while (b != 0) { - int remainder = a % b; - a = b; - b = remainder; - } - return a; -} - -int main() { - int a, b; - cout << "Enter two integers: "; - cin >> a >> b; - cout << "GCD of " << a << " and " << b << " is: " << gcd(a, b) << endl; - return 0; -} -``` - -### Python Implementation - -```python -def gcd(a, b): - while b != 0: - a, b = b, a % b - return a - -if __name__ == "__main__": - a = int(input("Enter the first integer: ")) - b = int(input("Enter the second integer: ")) - print(f"GCD of {a} and {b} is: {gcd(a, b)}") -``` - -## Example Walkthrough - -### Example 1: GCD of 56 and 98 -1. $ 98 \mod 56 = 42 $ -2. $ 56 \mod 42 = 14 $ -3. $ 42 \mod 14 = 0 $ - -$ \text{GCD} = 14 $ - -### Example 2: GCD of 101 and 103 -1. $ 103 \mod 101 = 2 $ -2. $ 101 \mod 2 = 1 $ -3. $ 2 \mod 1 = 0 $ - -$ \text{GCD} = 1 $ - -## Applications and Use Cases -- **Simplifying Fractions**: Reducing fractions to their simplest form. -- **Cryptography**: Used in algorithms like RSA for key generation. -- **Divisibility Problems**: Essential in modular arithmetic and number theory. - -## Math Representation - -$ a = b \times q + r $ - -where $ q $ is the quotient and $ r $ is the remainder. - -## Diagrams - -```mermaid -graph TD; - A[Start] --> B[Input two integers a and b]; - B --> C{Is b = 0?}; - C -- Yes --> D[Output a as the GCD]; - C -- No --> E[Compute remainder: a % b]; - E --> F[Set a = b, b = remainder]; - F --> C; - D --> G[End]; -``` - -## Conclusion -The Euclidean Algorithm is a fundamental technique in number theory for efficiently finding the Greatest Common Divisor (GCD) of two integers. By repeatedly applying the division and remainder operation, it significantly reduces the problem size, making it an optimal solution for GCD calculations. - -This algorithm not only forms the basis for many mathematical and computational applications, such as simplifying fractions and cryptographic algorithms, but it also introduces important concepts in algorithm design like iteration and efficiency. Understanding and implementing the Euclidean Algorithm helps build a solid foundation in number theory and algorithmic thinking. diff --git a/docs/algorithms/mathematics-algorithms/fermat-little-theorem.md b/docs/algorithms/mathematics-algorithms/fermat-little-theorem.md deleted file mode 100644 index 163fed561..000000000 --- a/docs/algorithms/mathematics-algorithms/fermat-little-theorem.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -id: fermat-little-theorem -title: "Fermat's Little Theorem" -sidebar_label: "Fermat's Little Theorem MMI" -sidebar_position: 5 -description: "A comprehensive guide to calculating the modular multiplicative inverse using Fermat's Little Theorem." -tags: [number theory, modular arithmetic, cryptography,competitive progrmaing] ---- - -## Modular Multiplicative Inverse Using Fermat's Little Theorem - -**Definition:** - -The modular multiplicative inverse of an integer `a` modulo `m` is an integer `b` such that `a * b ≡ 1 (mod m)`. In other words, `b` is the inverse of `a` in the ring of integers modulo `m`. - -**Fermat's Little Theorem for Modular Inverses:** - -Fermat's Little Theorem provides a direct way to calculate the modular multiplicative inverse of `a` modulo `p` when `p` is a prime number. It states that: -$a^{(p-2)} ≡ a^{(-1)}$ -This means that raising `a` to the power of `p-2` modulo `p` gives you the modular multiplicative inverse of `a`. - - - -### Code -**Code Implementation (Python):** - -```python -def modular_exponentiation(base, exponent, mod): - """Calculates the modular exponentiation of base^exponent mod mod efficiently. - - Args: - base: The base number. - exponent: The exponent. - mod: The modulus. - - Returns: - The result of base^exponent mod mod. - """ - - result = 1 - while exponent > 0: - if exponent % 2 == 1: - result = (result * base) % mod - base = (base * base) % mod - exponent //= 2 - return result - -def modular_inverse(a,   - p): - """Calculates the modular multiplicative inverse of a modulo p using Fermat's Little Theorem.in O(logn) - - Args: - a: The base number. - p: The prime modulus. - - Returns: - The modular multiplicative inverse of a modulo p, or None if it doesn't exist. - """ - - if p <= 1: - raise ValueError("Modulus must be a prime number greater than 1.") - return modular_exponentiation(a, p - 2, p) - - ``` - -**Code Implementation (C++):** - -```cpp - -include "bits/stdc++.h> - -using namespace std; - -int modular_exponentiation(int base, int exponent, int mod) { - int result = 1; - while (exponent > 0) { - if (exponent % 2 == 1) { - result = (result * base) % mod; - } - base = (base * base) % mod; - exponent /= 2; - } - return result; -} - -int modular_inverse(int a, int p) { - if (p <= 1) { - throw invalid_argument("Modulus must be a prime number greater than 1."); - } - return modular_exponentiation(a, p - 2, p); -} - -int main() { - int a = 3; - int p = 7; - - int inverse = modular_inverse(a, p); - cout << "The modular multiplicative inverse of " << a << " modulo " << p << " is " << inverse << endl; - - return 0; -} -``` -**Code Implementation (Java):** - -```java -import java.util.Scanner; - -public class FermatsLittleTheorem { - public static int modular_exponentiation(int base, int exponent, int mod) { - int result = 1; - while (exponent > 0) { - if (exponent % 2 == 1) { - result = (result * base) % mod; - } - base = (base * base) % mod; - exponent /= 2; - } - return result;   - - } - - public static int modular_inverse(int a, int p) { - if (p <= 1) { - throw new IllegalArgumentException("Modulus must be a prime number greater than 1."); - } - return modular_exponentiation(a, p - 2, p); - } - - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - - System.out.print("Enter the value of a: "); - int a = scanner.nextInt(); - - System.out.print("Enter   - the prime modulus p: "); - int p = scanner.nextInt(); - - int inverse = modular_inverse(a, p); - System.out.println("The modular multiplicative inverse of " + a + " modulo " + p + " is " + inverse); - } -} -``` -Explanation of the Code: - -modular_exponentiation: This function efficiently calculates the modular exponentiation of base^exponent mod mod using the repeated squaring algorithm. -modular_inverse: This function calculates the modular multiplicative inverse of a modulo p using Fermat's Little Theorem. -It first checks if p is a prime number greater than 1. -If so, it calculates $a^{(p-2)}$ mod p using the modular_exponentiation function. -The result is the modular multiplicative inverse of a modulo p. -main: This is the main function where the program execution starts. It prompts the user to enter values for a and p, calculates the modular inverse using the modular_inverse function, and prints the result. -Example Usage: - -Run the Java program and enter the values of a and p. For example, if you enter a = 3 and p = 7, the output will be: - -The modular multiplicative inverse of 3 modulo 7 is 5 - -Sources and related content - - - -### Applications in Competitive Programming -Fermat's Little Theorem has several practical applications in competitive programming: - -1. Modular Exponentiation -Efficiently calculating large powers modulo a prime: Fermat's Little Theorem can be used to reduce the exponent modulo a prime before performing the exponentiation. This can significantly improve the efficiency of calculations involving large exponents. -2. Finding Modular Inverses -Calculating modular inverses efficiently: For prime moduli, Fermat's Little Theorem provides a direct method to find the modular inverse of an element. This is crucial for solving problems involving modular division or solving linear congruences. -3. Solving Diophantine Equations -Solving linear congruences: Fermat's Little Theorem can be used to solve linear congruences of the form ax ≡ b (mod p) where p is a prime number. -4. Cryptography -RSA Algorithm: Fermat's Little Theorem forms the basis of the RSA public-key encryption algorithm. It is used to generate the public and private keys, as well as to perform encryption and decryption. - diff --git a/docs/algorithms/mathematics-algorithms/gcd-lcm.md b/docs/algorithms/mathematics-algorithms/gcd-lcm.md deleted file mode 100644 index aedee5546..000000000 --- a/docs/algorithms/mathematics-algorithms/gcd-lcm.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -id: gcd-lcm -sidebar_position: 4 -title: Greatest Common Divisor (GCD) and Least Common Multiple (LCM) -sidebar_label: GCD and LCM -description: "Greatest Common Divisor (GCD) and Least Common Multiple (LCM) are fundamental algorithms for divisibility." -tags: [gcd, lcm, number theory, algorithms] ---- - -# Greatest Common Divisor (GCD) and Least Common Multiple (LCM) - -The **Greatest Common Divisor (GCD)** and **Least Common Multiple (LCM)** are fundamental algorithms in number theory used to determine the divisibility relationships between integers. - -## Greatest Common Divisor (GCD) - -### Definition - -The **GCD** of two integers is the largest positive integer that divides both numbers without leaving a remainder. It is often used to simplify fractions and solve problems involving divisibility. - -### Algorithm - -The **Euclidean algorithm** is the most efficient method for computing the GCD. It works on the principle that the GCD of two numbers also divides their difference. - -#### Steps: -1. Given two integers $a$ and $b$ : - - If $b$ = 0, then $GCD(a, b)$ = a - - Otherwise, $GCD(a, b)$ = $GCD(b,a \ mod \ b ).$ - -### Time Complexity - -- The time complexity of the Euclidean algorithm is $( O(log(min(a, b)))).$ - -## Least Common Multiple (LCM) - -### Definition - -The **LCM** of two integers is the smallest positive integer that is divisible by both numbers. It is often used in problems involving fractions and synchronization of cycles. - -### Relationship with GCD - -The LCM can be calculated using the GCD with the following formula: - -$LCM(a, b)$ = $\dfrac{a \times b}{\text{GCD}(a, b)}$. - -### Time Complexity - -- The time complexity for calculating the LCM is $O(log(min(a, b)))$ due to the GCD calculation. - -## Implementations - -### C++ - -```cpp -#include -using namespace std; - -int gcd(int a, int b) { - while (b != 0) { - int temp = b; - b = a % b; - a = temp; - } - return a; -} - -int lcm(int a, int b) { - return (a / gcd(a, b)) * b; -} - -int main() { - int a = 12, b = 15; - cout << "GCD: " << gcd(a, b) << endl; - cout << "LCM: " << lcm(a, b) << endl; - return 0; -} -``` -### Java -```java -public class GCDLCM { - public static int gcd(int a, int b) { - while (b != 0) { - int temp = b; - b = a % b; - a = temp; - } - return a; - } - - public static int lcm(int a, int b) { - return (a / gcd(a, b)) * b; - } - - public static void main(String[] args) { - int a = 12, b = 15; - System.out.println("GCD: " + gcd(a, b)); - System.out.println("LCM: " + lcm(a, b)); - } -} -``` -### Python -```python -def gcd(a, b): - while b != 0: - a, b = b, a % b - return a - -def lcm(a, b): - return abs(a * b) // gcd(a, b) - -a = 12 -b = 15 -print("GCD:", gcd(a, b)) -print("LCM:", lcm(a, b)) -``` -### Pseudo Code -``` -function gcd(a, b): - while b != 0: - temp = b - b = a mod b - a = temp - return a - -function lcm(a, b): - return (a / gcd(a, b)) * b -``` -### Conclusion -The Greatest Common Divisor (GCD) and Least Common Multiple (LCM) are essential algorithms in number theory that help in understanding the divisibility of integers. Their efficient computation using the Euclidean algorithm and the relationship between GCD and LCM makes them powerful tools in both theoretical and practical applications. \ No newline at end of file diff --git a/docs/algorithms/mathematics-algorithms/imp-of-mathematics.md b/docs/algorithms/mathematics-algorithms/imp-of-mathematics.md deleted file mode 100644 index db9ba45d8..000000000 --- a/docs/algorithms/mathematics-algorithms/imp-of-mathematics.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: importance-of-mathematics -sidebar_position: 2 -title: Importance of Mathematical Algorithms -sidebar_label: Importance of Mathematics -description: "Mathematical algorithms are essential for solving various computational problems and are widely used in both theoretical computer science and practical applications. They underpin many algorithms used in competitive programming and other fields." -tags: [Mathematics, Algorithms, Competitive Programming] ---- - -### Importance of Mathematical Algorithms - -Mathematical algorithms are foundational to computer science and programming. They provide essential tools and methods for solving a wide range of problems effectively and efficiently. Below are key areas highlighting their importance: - -1. **Solving Number Theory Problems**: - - **Prime Number Algorithms**: Algorithms like the Sieve of Eratosthenes efficiently find all prime numbers up to a specified integer. They are crucial in cryptographic applications and help in generating secure keys. - - **Greatest Common Divisor (GCD)**: The Euclidean algorithm efficiently computes the GCD of two integers, which is fundamental in simplifying fractions and solving Diophantine equations. - - **Modular Arithmetic**: Algorithms for modular exponentiation (like the method of successive squaring) are vital in cryptographic protocols (e.g., RSA) and help in solving congruences. - -2. **Computational Geometry**: - - **Convex Hull Algorithms**: Algorithms such as Graham's scan and Jarvis's march are used to determine the convex hull of a set of points. They are applicable in computer graphics and geographic information systems (GIS). - - **Intersection Problems**: Algorithms for detecting intersections between geometric shapes are crucial in computer graphics, robotics, and simulations. - -3. **Graph Theory Applications**: - - **Shortest Path Algorithms**: Algorithms like Dijkstra's and Bellman-Ford are essential for finding the shortest paths in weighted graphs, applicable in navigation systems and network routing. - - **Minimum Spanning Trees (MST)**: Algorithms like Kruskal’s and Prim’s help find the MST of a graph, which is useful in network design to minimize costs. - -4. **Dynamic Programming**: - - **Optimal Substructure**: Many dynamic programming algorithms, such as the Knapsack problem and Longest Common Subsequence, utilize mathematical principles to break problems down into simpler subproblems, enabling efficient solutions. - - **Counting Problems**: Problems that involve counting distinct arrangements, paths, or combinations often rely on mathematical principles and combinatorial analysis. - -5. **Optimization Problems**: - - **Linear Programming**: The Simplex algorithm and Interior Point methods are used to solve linear programming problems, which are common in operations research and economics to maximize or minimize objective functions subject to constraints. - - **Integer Programming**: Mathematical algorithms help in solving problems where variables must be integers, which is crucial in scheduling and resource allocation problems. - -6. **Statistical Analysis**: - - **Regression Algorithms**: Algorithms for linear regression and logistic regression rely on statistical principles to model relationships between variables, essential for data analysis and machine learning. - - **Hypothesis Testing**: Mathematical algorithms facilitate testing statistical hypotheses, which is fundamental in experimental design and decision-making processes. - -7. **Algorithm Design and Analysis**: - - **Complexity Analysis**: A solid understanding of mathematical concepts is essential for analyzing the time and space complexity of algorithms, allowing programmers to optimize performance and resource utilization. - - **Asymptotic Notation**: Mathematical notation like Big O, Omega, and Theta are used to describe algorithm efficiency and performance characteristics. - -8. **Cryptography**: - - **Public Key Cryptography**: Algorithms like RSA and Diffie-Hellman rely heavily on number theory and modular arithmetic. Understanding these algorithms is crucial for designing secure communication systems. - - **Hash Functions**: Cryptographic hash functions (e.g., SHA-256) utilize mathematical principles to provide data integrity and security. - -9. **Real-world Applications**: - - **Financial Modeling**: Algorithms are employed to create predictive models for stock prices and economic trends, using mathematical principles like stochastic calculus. - - **Engineering Simulations**: Mathematical algorithms help solve differential equations in simulations of physical systems, such as fluid dynamics or structural analysis. - -10. **Educational Value**: - - **Critical Thinking**: Mastering mathematical algorithms enhances critical thinking and problem-solving skills, essential for tackling complex challenges in computer science and engineering. - - **Foundation for Advanced Topics**: A solid grasp of mathematical algorithms is crucial for understanding advanced topics in computer science, such as artificial intelligence, machine learning, and data mining. - -### Conclusion - -Mathematical algorithms are integral to the field of data structures and algorithms, providing essential tools for solving complex problems efficiently. Their applications extend beyond computer science into various domains, making them invaluable in fields ranging from finance to engineering. By mastering mathematical algorithms, programmers can enhance their problem-solving skills and prepare themselves for challenges in competitive programming and real-world scenarios. The knowledge of these algorithms is not only beneficial for academic success but also for career advancement in the tech industry. diff --git a/docs/algorithms/mathematics-algorithms/modular-arithmetic.md b/docs/algorithms/mathematics-algorithms/modular-arithmetic.md deleted file mode 100644 index 0aa379a2e..000000000 --- a/docs/algorithms/mathematics-algorithms/modular-arithmetic.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -id: modular-arithmetic -sidebar_position: 7 -title: Modular Arithmetic -sidebar_label: Modular Arithmetic -description: "Modular arithmetic is a fundamental concept in mathematics, essential for cryptography and number theory." -tags: [modular arithmetic, cryptography, number theory, algorithms] ---- - -# Modular Arithmetic - -**Modular Arithmetic** is a system of arithmetic for integers where numbers wrap around after reaching a certain value called the modulus. It is a crucial concept in various fields, especially in cryptography and number theory. - -## Core Concepts - -### Modulus -- The modulus $m$ is the integer at which numbers wrap around. -- For any integer $a$, the expression $a \mod m$ gives the remainder of the division of $a$ by $m$. - -### Basic Operations - -1. **Addition :** $(a + b) \mod m$ - Example: $(7 + 5) \mod 10 = 2$ - - **Code**: - #### C++ - ```cpp - int modular_add(int a, int b, int m) { - return (a + b) % m; - } - ``` - #### Java - ```java - public static int modularAdd(int a, int b, int m) { - return (a + b) % m; - } - ``` - #### Python - ```py - def modular_add(a, b, m): - return (a + b) % m - ``` - #### **Time Complexity**: $O(1)$ -2. **Subtraction** : $(a - b) \mod m$ - Example: $(3 − 4) \mod 5 = 4$ - - **Code**: - #### C++ - ```cpp - int modular_sub(int a, int b, int m) { - return (a - b + m) % m; // ensure non-negative result - } - - ``` - #### Java - ```java - public static int modularSub(int a, int b, int m) { - return (a - b + m) % m; // ensure non-negative result - } - ``` - #### Python - ```py - def modular_sub(a, b, m): - return (a - b + m) % m # ensure non-negative result - ``` - #### **Time Complexity**: $O(1)$ -3. **Multiplication:**: - $(a \times b) \mod m$ - Example: $(4 \times 3) \mod 5 = 2$ - - **Code**: - #### C++ - ```cpp - int modular_mul(int a, int b, int m) { - return (a * b) % m; - } - - ``` - #### Java - ```java - public static int modularMul(int a, int b, int m) { - return (a * b) % m; - } - - ``` - #### Python - ```py - def modular_mul(a, b, m): - return (a * b) % m - ``` - #### **Time Complexity**: $O(1)$ -4. **Exponentiation:** - $(a^b) \mod m$ - Example: $(2^3) \mod 5 = 3$ - - - - **Code**: - #### C++ - ```cpp - int modular_pow(int base, int exp, int mod) { - int result = 1; - base = base % mod; - while (exp > 0) { - if (exp % 2 == 1) { - result = (result * base) % mod; - } - exp = exp >> 1; // equivalent to exp //= 2 - base = (base * base) % mod; - } - return result; - } - - - ``` - #### Java - ```java - public static int modularPow(int base, int exp, int mod) { - int result = 1; - base = base % mod; - while (exp > 0) { - if ((exp & 1) == 1) { - result = (result * base) % mod; - } - exp >>= 1; // equivalent to exp /= 2 - base = (base * base) % mod; - } - return result; - } - - - ``` - #### Python - ```py - def modular_pow(base, exp, mod): - result = 1 - base = base % mod - while exp > 0: - if (exp % 2) == 1: - result = (result * base) % mod - exp //= 2 - base = (base * base) % mod - return result - - ``` - #### **Time Complexity**: $O( log \ b)$ - -### Conclusion -Modular arithmetic is a powerful tool in mathematics with significant applications in cryptography, computer science, and number theory. Understanding its core operations and properties is essential for working with modern cryptographic systems and algorithms. \ No newline at end of file diff --git a/docs/algorithms/mathematics-algorithms/sieve-of-eratosthenes.md b/docs/algorithms/mathematics-algorithms/sieve-of-eratosthenes.md deleted file mode 100644 index 6734a0463..000000000 --- a/docs/algorithms/mathematics-algorithms/sieve-of-eratosthenes.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -id: sieve-of-eratosthenes -sidebar_position: 3 -title: Sieve of Eratosthenes -sidebar_label: Sieve of Eratosthenes -description: "The Sieve of Eratosthenes is an efficient algorithm to find all prime numbers up to a given limit." -tags: [sieve of eratosthenes, prime numbers, algorithms, number theory] ---- - -# Sieve of Eratosthenes - -The **Sieve of Eratosthenes** is an ancient algorithm used to find all prime numbers up to a specified integer. It is efficient and easy to implement, making it one of the most popular algorithms for generating a list of primes. - -## Algorithm - -### Steps: -1. Create a list of consecutive integers from 2 to $n$ (the limit). -2. Start with the first prime number $p=2$. -3. Mark all multiples of $p$ (from $p^2$ to $n$) as composite (not prime). -4. Find the next number in the list that is not marked. This number is the next prime $p$. -5. Repeat steps 3 and 4 until $p^2$ is greater than $n$. -6. The numbers that remain unmarked in the list are all the prime numbers up to $n$. - -### Example - -To find all prime numbers up to 30: -- Start with the list: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30] -- Mark multiples of 2: [2, 3, X, 5, X, 7, X, 9, X, 11, X, 13, X, 15, X, 17, X, 19, X, 21, X, 23, X, 25, X, 27, X, 29, X] -- Mark multiples of 3: [2, 3, X, 5, X, 7, X, X, X, 11, X, 13, X, X, 17, X, 19, X, X, X, 23, X, 25, X, X, X, 29, X] -- Continue this process until all multiples of primes are marked. -- The unmarked numbers are: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29. - -## Time Complexity - -- The time complexity of the Sieve of Eratosthenes is $O(n \log(\log(n)))$, where $n$ is the limit up to which prime numbers are generated. This makes it very efficient for large values of $n$.. - -## Space Complexity - -- The space complexity is $O(n)$ due to the array used to mark the prime numbers. - -## Implementations - -### C++ - -```cpp -#include -#include -using namespace std; - -void sieveOfEratosthenes(int n) { - vector isPrime(n + 1, true); - isPrime[0] = isPrime[1] = false; // 0 and 1 are not prime numbers - - for (int p = 2; p * p <= n; p++) { - if (isPrime[p]) { - for (int i = p * p; i <= n; i += p) { - isPrime[i] = false; // Mark multiples of p as non-prime - } - } - } - - cout << "Prime numbers up to " << n << " are: "; - for (int i = 2; i <= n; i++) { - if (isPrime[i]) { - cout << i << " "; - } - } - cout << endl; -} - -int main() { - int n = 30; // Limit - sieveOfEratosthenes(n); - return 0; -} -``` -### Java -```java -import java.util.Arrays; - -public class SieveOfEratosthenes { - public static void sieve(int n) { - boolean[] isPrime = new boolean[n + 1]; - Arrays.fill(isPrime, true); - isPrime[0] = isPrime[1] = false; // 0 and 1 are not prime numbers - - for (int p = 2; p * p <= n; p++) { - if (isPrime[p]) { - for (int i = p * p; i <= n; i += p) { - isPrime[i] = false; // Mark multiples of p as non-prime - } - } - } - - System.out.print("Prime numbers up to " + n + " are: "); - for (int i = 2; i <= n; i++) { - if (isPrime[i]) { - System.out.print(i + " "); - } - } - System.out.println(); - } - - public static void main(String[] args) { - int n = 30; // Limit - sieve(n); - } -} -``` -### Python - -```python -def sieve_of_eratosthenes(n): - is_prime = [True] * (n + 1) - is_prime[0], is_prime[1] = False, False # 0 and 1 are not prime numbers - - for p in range(2, int(n**0.5) + 1): - if is_prime[p]: - for i in range(p * p, n + 1, p): - is_prime[i] = False # Mark multiples of p as non-prime - - print(f"Prime numbers up to {n} are: ", end="") - for i in range(2, n + 1): - if is_prime[i]: - print(i, end=" ") - print() - -n = 30 # Limit -sieve_of_eratosthenes(n) -``` -### Pseudo Code -``` -function sieveOfEratosthenes(n): - create an array isPrime[0...n] and initialize all entries as true - isPrime[0] = isPrime[1] = false // 0 and 1 are not prime numbers - - for p from 2 to sqrt(n): - if isPrime[p] is true: - for i from p^2 to n with step p: - isPrime[i] = false // Mark multiples of p as non-prime - - print "Prime numbers up to n are:" - for i from 2 to n: - if isPrime[i] is true: - print i -``` -### Conclusion -The Sieve of Eratosthenes is an efficient and straightforward algorithm for finding all prime numbers up to a given limit. Its simplicity and efficiency make it a favorite among computer scientists and mathematicians for generating prime numbers in various applications. \ No newline at end of file diff --git a/docs/algorithms/mathematics-algorithms/sweep-line-algorithm.md b/docs/algorithms/mathematics-algorithms/sweep-line-algorithm.md deleted file mode 100644 index 2bcf0ceb2..000000000 --- a/docs/algorithms/mathematics-algorithms/sweep-line-algorithm.md +++ /dev/null @@ -1,265 +0,0 @@ ---- -id: sweep-line-algorithm -title: "Sweep Line Algorithm" -sidebar_label: "Sweep Line Algorithm" -sidebar_position: 6 -description: "A comprehensive guide to understanding and implementing the sweep line algorithm for computational geometry." -tags: [computational geometry, algorithms, competitive programming] ---- - -The Sweep Line Algorithm is a powerful approach used in computational geometry to solve problems involving geometric figures (e.g., finding intersections, computing areas, etc.). The idea is to "sweep" a vertical line across the plane from left to right and process events as they occur. - -### Key Concepts: - -1. Event Points: These are the key positions in the plane where important changes happen. These might include the start or end of a line, or an intersection between two objects. -2. Active Set: As the sweep line moves, it maintains an active set of objects (e.g., lines, segments) that intersect the current position of the sweep line. - - -### Code Implementation - -The following code snippets demonstrate the implementation of the Sweep Line Algorithm in Python, C++, and Java. The algorithm is used to find intersections among a set of line segments by sweeping a line across the plane. - - - - -```python -import heapq - -class Event: - def __init__(self, x, start, segment): - self.x = x - self.start = start - self.segment = segment - - def __lt__(self, other): - return self.x < other.x or (self.x == other.x and self.start > other.start) - -def sweep_line(segments): - """Sweep line algorithm to find intersections in a set of line segments. - - Args: - segments: A list of tuples representing line segments (x1, y1, x2, y2). - - Returns: - A list of intersection points. - """ - events = [] - for seg in segments: - x1, y1, x2, y2 = seg - events.append(Event(x1, True, seg)) - events.append(Event(x2, False, seg)) - - heapq.heapify(events) - active_segments = [] - intersections = [] - - while events: - event = heapq.heappop(events) - - if event.start: - active_segments.append(event.segment) - else: - active_segments.remove(event.segment) - - # Check for intersections among active segments - for i in range(len(active_segments)): - for j in range(i + 1, len(active_segments)): - inter = find_intersection(active_segments[i], active_segments[j]) - if inter: - intersections.append(inter) - - return intersections - -def find_intersection(seg1, seg2): - """Helper function to check if two line segments intersect. - - Args: - seg1: First line segment. - seg2: Second line segment. - - Returns: - The intersection point if it exists, otherwise None. - """ - # Implement the logic to check for intersection and calculate the intersection point - pass - -# Example Usage -segments = [(1, 1, 5, 5), (1, 5, 5, 1)] -intersections = sweep_line(segments) -print(f"Intersections: {intersections}") -``` - - - - - -```cpp -#include -#include -#include -#include - -using namespace std; - -struct Segment { - int x1, y1, x2, y2; -}; - -struct Event { - int x; - bool start; - Segment segment; - - bool operator<(const Event& other) const { - return x < other.x || (x == other.x && start > other.start); - } -}; - -vector> sweep_line(vector& segments) { - vector events; - - for (auto& seg : segments) { - events.push_back({seg.x1, true, seg}); - events.push_back({seg.x2, false, seg}); - } - - sort(events.begin(), events.end()); - - set active_segments; - vector> intersections; - - for (auto& event : events) { - if (event.start) { - active_segments.insert(event.segment); - } else { - active_segments.erase(event.segment); - } - - // Check for intersections in active set - for (auto it1 = active_segments.begin(); it1 != active_segments.end(); ++it1) { - for (auto it2 = next(it1); it2 != active_segments.end(); ++it2) { - if (auto inter = find_intersection(*it1, *it2)) { - intersections.push_back(*inter); - } - } - } - } - - return intersections; -} - -pair* find_intersection(const Segment& seg1, const Segment& seg2) { - // Intersection logic here - return nullptr; -} - -int main() { - vector segments = {{1, 1, 5, 5}, {1, 5, 5, 1}}; - vector> intersections = sweep_line(segments); - - cout << "Intersections found:\n"; - for (auto& inter : intersections) { - cout << inter.first << ", " << inter.second << endl; - } - - return 0; -} -``` - - - - - -```java -import java.util.*; - -class Segment { - int x1, y1, x2, y2; - - public Segment(int x1, int y1, int x2, int y2) { - this.x1 = x1; - this.y1 = y1; - this.x2 = x2; - this.y2 = y2; - } -} - -class Event implements Comparable { - int x; - boolean start; - Segment segment; - - public Event(int x, boolean start, Segment segment) { - this.x = x; - this.start = start; - this.segment = segment; - } - - @Override - public int compareTo(Event other) { - if (this.x != other.x) return this.x - other.x; - return Boolean.compare(other.start, this.start); - } -} - -public class SweepLineAlgorithm { - public static List sweepLine(Segment[] segments) { - PriorityQueue events = new PriorityQueue<>(); - List intersections = new ArrayList<>(); - - for (Segment segment : segments) { - events.add(new Event(segment.x1, true, segment)); - events.add(new Event(segment.x2, false, segment)); - } - - Set activeSegments = new HashSet<>(); - - while (!events.isEmpty()) { - Event event = events.poll(); - - if (event.start) { - activeSegments.add(event.segment); - } else { - activeSegments.remove(event.segment); - } - - for (Segment seg1 : activeSegments) { - for (Segment seg2 : activeSegments) { - if (seg1 != seg2) { - int[] intersection = findIntersection(seg1, seg2); - if (intersection != null) { - intersections.add(intersection); - } - } - } - } - } - return intersections; - } - - public static int[] findIntersection(Segment seg1, Segment seg2) { - // Intersection logic here - return null; - } - - public static void main(String[] args) { - Segment[] segments = { new Segment(1, 1, 5, 5), new Segment(1, 5, 5, 1) }; - List intersections = sweepLine(segments); - - System.out.println("Intersections:"); - for (int[] inter : intersections) { - System.out.println(inter[0] + ", " + inter[1]); - } - } -} -``` - - - - - -### Applications in Competitive Programming: - -1. Finding Segment Intersections: Used to detect where line segments cross, which is important in geometry-based problems. -2. Computing the Union of Rectangles: Calculate the area covered by a union of several rectangles. -3. Closest Pair of Points: Efficiently find the closest pair of points in a 2D plane. diff --git a/docs/algorithms/mathematics-algorithms/what-is-mathematical-algorithms.md b/docs/algorithms/mathematics-algorithms/what-is-mathematical-algorithms.md deleted file mode 100644 index 7f06c88d1..000000000 --- a/docs/algorithms/mathematics-algorithms/what-is-mathematical-algorithms.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -id: mathematical-algorithms -sidebar_position: 1 -title: What is Mathematical Algorithms? -sidebar_label: What is Mathematical Algorithms? -description: "Mathematical Algorithms play a crucial role in solving complex problems efficiently in both DSA and competitive programming." -tags: [dsa, algorithms, mathematics, competitive programming] ---- - -## Mathematical Algorithms - -Mathematical algorithms are fundamental to computer science and are utilized to solve problems that require mathematical reasoning and computations. They are pivotal in various applications, including cryptography, statistical analysis, optimization, and algorithmic design. - -### Importance of Mathematical Algorithms - -Mathematical algorithms are vital for several reasons: - -1. **Efficiency**: They optimize problem-solving by minimizing computational resources, leading to faster solutions. -2. **Complexity Reduction**: They simplify complex problems into manageable subproblems, facilitating easier solutions. -3. **Real-World Applications**: Mathematical algorithms have extensive applications in fields such as finance, engineering, machine learning, and data analysis. -4. **Competitive Advantage**: Mastery of mathematical algorithms gives participants in competitive programming a significant edge in solving problems quickly and effectively. -5. **Foundation for Advanced Topics**: A robust understanding of mathematical algorithms is necessary for exploring more complex topics, such as graph theory, dynamic programming, and machine learning. - -### Common Mathematical Algorithms - -Here are some commonly used mathematical algorithms: - -- **Euclidean Algorithm**: Efficiently computes the greatest common divisor (GCD) of two numbers. -- **Sieve of Eratosthenes**: Finds all prime numbers up to a specified integer efficiently. -- **Fast Exponentiation**: Quickly calculates large powers of numbers, essential in cryptographic applications. -- **Fibonacci Sequence**: Efficient algorithms for calculating Fibonacci numbers using matrix exponentiation or memoization. -- **Combinatorial Algorithms**: Techniques for calculating combinations, permutations, and other combinatorial structures. -- **Linear Programming**: Optimizes a linear objective function subject to linear constraints. -- **Graph Algorithms**: Algorithms such as Dijkstra's and Bellman-Ford for solving shortest path problems. - -### Mathematical Problems and Coding Implementations - -#### 1. **Euclidean Algorithm** - -**Problem**: Given two integers, find their greatest common divisor (GCD). - -**Python Implementation**: -```python -def gcd(a, b): - while b: - a, b = b, a % b - return a - -# Example usage -print(gcd(48, 18)) # Output: 6 -``` - -**C++ Implementation**: -```C++ -#include -using namespace std; - -int gcd(int a, int b) { - while (b != 0) { - int temp = b; - b = a % b; - a = temp; - } - return a; -} - -int main() { - cout << gcd(48, 18) << endl; // Output: 6 - return 0; -} -``` - -#### 2. **Sieve of Eratosthenes** -**Problem**: Find all prime numbers up to a given limit n. - -**Python Implementation**: -```python -def sieve_of_eratosthenes(n): - primes = [True] * (n + 1) - p = 2 - while p * p <= n: - if primes[p]: - for i in range(p * p, n + 1, p): - primes[i] = False - p += 1 - return [p for p in range(2, n + 1) if primes[p]] - -# Example usage -print(sieve_of_eratosthenes(30)) # Output: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - -``` - -**C++ Implementation**: -```C++ -#include -#include -using namespace std; - -vector sieve_of_eratosthenes(int n) { - vector primes(n + 1, true); - vector primeNumbers; - for (int p = 2; p * p <= n; p++) { - if (primes[p]) { - for (int i = p * p; i <= n; i += p) - primes[i] = false; - } - } - for (int p = 2; p <= n; p++) { - if (primes[p]) - primeNumbers.push_back(p); - } - return primeNumbers; -} - -int main() { - vector primes = sieve_of_eratosthenes(30); - for (int prime : primes) - cout << prime << " "; // Output: 2 3 5 7 11 13 17 19 23 29 - return 0; -} - -``` - -#### 3. **Fast Exponentiation** -**Problem**: Compute x^n efficiently for large n. - -**Python Implementation**: -```python -def fast_exponentiation(x, n): - if n == 0: - return 1 - half = fast_exponentiation(x, n // 2) - return half * half if n % 2 == 0 else half * half * x - -# Example usage -print(fast_exponentiation(2, 10)) # Output: 1024 - -``` - -**C++ Implementation**: -```C++ -#include -using namespace std; - -long long fast_exponentiation(long long x, long long n) { - if (n == 0) return 1; - long long half = fast_exponentiation(x, n / 2); - return half * half * (n % 2 ? x : 1); -} - -int main() { - cout << fast_exponentiation(2, 10) << endl; // Output: 1024 - return 0; -} -``` - -### Applications in Competitive Programming - -In competitive programming, mathematical algorithms are frequently applied to solve various types of problems, including: - -- **Number Theory Problems**: Many challenges require efficient solutions for operations involving primes, GCDs, or modular arithmetic. -- **Geometry**: Algorithms for computational geometry, such as determining convex hulls or calculating areas, are common in competitions. -- **Graph Theory**: Mathematical principles underpin graph algorithms, which are essential for solving problems related to network flows, connectivity, and pathfinding. -- **Dynamic Programming**: Many dynamic programming problems utilize mathematical principles, especially those that involve counting or optimization. - -### Conclusion - -Mathematical algorithms form a critical component of data structures and algorithms, significantly influencing both theoretical computer science and practical applications. Mastering these algorithms enhances problem-solving skills and equips programmers to tackle complex challenges in competitive programming and real-world scenarios. They are invaluable tools in various fields, from finance to engineering, and their mastery is essential for any aspiring computer scientist or programmer. diff --git a/docs/algorithms/memoisation-algorithms/_category_.json b/docs/algorithms/memoisation-algorithms/_category_.json deleted file mode 100644 index d277f11d1..000000000 --- a/docs/algorithms/memoisation-algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Memoization Algorithms", - "position": 7, - "link": { - "type": "generated-index", - "description": "Memoization is an optimization technique used primarily to speed up recursive algorithms by caching previously computed results. It is widely used in dynamic programming to avoid redundant calculations, significantly improving performance for problems such as the Fibonacci sequence, shortest paths, and other combinatorial problems." - } -} diff --git a/docs/algorithms/memoisation-algorithms/imp-of-memoisation.md b/docs/algorithms/memoisation-algorithms/imp-of-memoisation.md deleted file mode 100644 index e7e28158a..000000000 --- a/docs/algorithms/memoisation-algorithms/imp-of-memoisation.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: memoization -sidebar_position: 2 -title: Importance of Memoization -sidebar_label: Importance of Memoization -description: "Memoization is an essentail part for optimization technique used to improve the efficiency of recursive algorithms by storing previously computed results." -tags: [algorithms, memoization, optimization] ---- - -## Memoization - -Memoization is a powerful optimization technique primarily used in algorithms that involve recursion. It works by storing the results of expensive function calls and reusing those results when the same inputs occur again. This approach significantly improves the performance of recursive algorithms, particularly in problems involving overlapping subproblems, such as those commonly found in dynamic programming. - -### Importance of Memoization - -1. **Efficiency Improvement**: - - By caching results, memoization reduces the time complexity of algorithms, converting exponential time complexity into polynomial time complexity in many cases. - -2. **Reducing Redundant Computations**: - - Memoization avoids unnecessary recalculations of previously computed results, leading to significant savings in computational resources. - -3. **Facilitating Recursive Solutions**: - - It enables straightforward recursive solutions to problems that would otherwise be inefficient, allowing programmers to use a more intuitive approach without sacrificing performance. - -4. **Dynamic Programming Foundation**: - - Memoization is a critical concept in dynamic programming, serving as the basis for many dynamic programming algorithms that optimize recursive solutions. - -### Common Applications of Memoization - -- **Fibonacci Sequence**: - - Calculating Fibonacci numbers can be optimized using memoization to avoid redundant calculations. - -- **Combinatorial Problems**: - - Problems such as the number of ways to climb stairs or partition numbers can benefit from memoization to speed up the computation. - -- **Shortest Path Problems**: - - In algorithms like Dijkstra’s, memoization can cache results for previously calculated shortest paths to improve efficiency. - -- **Dynamic Programming Problems**: - - Many classic dynamic programming problems, such as the Knapsack problem or Longest Common Subsequence, leverage memoization to enhance performance. - -### Example of Memoization - -#### Problem: Calculate Fibonacci Numbers - -**Recursive Implementation without Memoization**: - -```python -def fibonacci(n): - if n <= 1: - return n - return fibonacci(n - 1) + fibonacci(n - 2) - -# Example usage -print(fibonacci(10)) # Output: 55 -``` - -**Recursive Implementation with Memoization**: - -```python -def fibonacci_memo(n, memo={}): - if n in memo: - return memo[n] - if n <= 1: - return n - memo[n] = fibonacci_memo(n - 1, memo) + fibonacci_memo(n - 2, memo) - return memo[n] - -# Example usage -print(fibonacci_memo(10)) # Output: 55 - -``` - -**Conclusion** - -Memoization is an essential technique in the optimization of recursive algorithms, significantly improving their efficiency. Understanding how and when to use memoization is crucial for solving complex problems effectively, especially in competitive programming and algorithm design. By mastering this technique, programmers can write cleaner, more efficient code that performs well even for large input sizes. \ No newline at end of file diff --git a/docs/algorithms/memoisation-algorithms/what-is-memoisation.md b/docs/algorithms/memoisation-algorithms/what-is-memoisation.md deleted file mode 100644 index a940cbdec..000000000 --- a/docs/algorithms/memoisation-algorithms/what-is-memoisation.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -id: memoization-algorithms -sidebar_position: 1 -title: What is Memoization? -sidebar_label: What is Memoization? -description: "Memoization is an optimization technique used primarily to speed up recursive algorithms by caching previously computed results." -tags: [dsa, algorithms, memoization, dynamic programming] ---- - -## Memoization - -Memoization is an optimization technique used in computer science to improve the efficiency of recursive algorithms by storing the results of expensive function calls and reusing them when the same inputs occur again. This technique is particularly useful in dynamic programming, where problems can often be broken down into overlapping subproblems. - -### Importance of Memoization - -Memoization is vital for several reasons: - -1. **Improved Performance**: By caching results of expensive function calls, memoization significantly reduces the time complexity of algorithms that would otherwise perform redundant calculations. -2. **Optimal Resource Utilization**: It helps in optimizing resource usage by avoiding unnecessary computations, leading to faster execution times and lower memory consumption in some scenarios. -3. **Simplifying Recursive Algorithms**: Memoization allows complex recursive algorithms to be implemented more straightforwardly, enhancing readability and maintainability of the code. -4. **Foundation for Dynamic Programming**: Understanding memoization is essential for grasping dynamic programming concepts, which are critical for solving many algorithmic challenges. - -### Common Problems Utilizing Memoization - -Here are some commonly encountered problems that can be efficiently solved using memoization: - -- **Fibonacci Sequence**: Calculating Fibonacci numbers using memoization avoids the exponential time complexity of naive recursive approaches. -- **Longest Common Subsequence**: Finding the length of the longest common subsequence between two strings can be optimized with memoization. -- **Knapsack Problem**: Solving the 0/1 knapsack problem using memoization allows for efficient computation of maximum value. -- **Edit Distance**: Calculating the minimum edit distance between two strings can be optimized with memoization. - -### Memoization Implementation Examples - -#### 1. **Fibonacci Sequence** - -**Problem**: Compute the n-th Fibonacci number using memoization. - -**Python Implementation**: -```python -def fibonacci(n, memo={}): - if n in memo: - return memo[n] - if n <= 1: - return n - memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo) - return memo[n] - -# Example usage -print(fibonacci(10)) # Output: 55 -``` - -**C++ Implementation**: -```C++ -#include -#include -using namespace std; - -unordered_map memo; - -long long fibonacci(int n) { - if (memo.count(n)) return memo[n]; - if (n <= 1) return n; - memo[n] = fibonacci(n - 1) + fibonacci(n - 2); - return memo[n]; -} - -int main() { - cout << fibonacci(10) << endl; // Output: 55 - return 0; -} - -``` - -#### 2. **Longest Common Subsequence** - -**Problem**: Find the length of the longest common subsequence between two strings. -**Python Implementation**: -```python -def lcs(x, y, m, n, memo={}): - if (m, n) in memo: - return memo[(m, n)] - if m == 0 or n == 0: - return 0 - if x[m - 1] == y[n - 1]: - memo[(m, n)] = 1 + lcs(x, y, m - 1, n - 1, memo) - else: - memo[(m, n)] = max(lcs(x, y, m, n - 1, memo), lcs(x, y, m - 1, n, memo)) - return memo[(m, n)] - -# Example usage -x = "AGGTAB" -y = "GXTXAYB" -print(lcs(x, y, len(x), len(y))) # Output: 4 -``` - -**C++ Implementation**: -```C++ -#include -#include -using namespace std; - -unordered_map memo; - -int lcs(string x, string y, int m, int n) { - if (m == 0 || n == 0) return 0; - string key = to_string(m) + "|" + to_string(n); - if (memo.count(key)) return memo[key]; - - if (x[m - 1] == y[n - 1]) { - memo[key] = 1 + lcs(x, y, m - 1, n - 1); - } else { - memo[key] = max(lcs(x, y, m, n - 1), lcs(x, y, m - 1, n)); - } - return memo[key]; -} - -int main() { - string x = "AGGTAB"; - string y = "GXTXAYB"; - cout << lcs(x, y, x.size(), y.size()) << endl; // Output: 4 - return 0; -} -``` - - -#### 3. **0/1 Knapsack Problem** - -**Problem**: Find the maximum value that can be obtained in a knapsack of a given capacity. - -**Python Implementation**: -```python -def knapsack(weights, values, capacity, n, memo={}): - if (n, capacity) in memo: - return memo[(n, capacity)] - if n == 0 or capacity == 0: - return 0 - if weights[n - 1] > capacity: - memo[(n, capacity)] = knapsack(weights, values, capacity, n - 1, memo) - else: - memo[(n, capacity)] = max(values[n - 1] + knapsack(weights, values, capacity - weights[n - 1], n - 1, memo), - knapsack(weights, values, capacity, n - 1, memo)) - return memo[(n, capacity)] - -# Example usage -weights = [1, 2, 3] -values = [10, 15, 40] -capacity = 6 -n = len(values) -print(knapsack(weights, values, capacity, n)) # Output: 55 - -``` - -**C++ Implementation**: -```C++ -#include -#include -using namespace std; - -unordered_map memo; - -int knapsack(int weights[], int values[], int capacity, int n) { - if (n == 0 || capacity == 0) return 0; - string key = to_string(n) + "|" + to_string(capacity); - if (memo.count(key)) return memo[key]; - - if (weights[n - 1] > capacity) { - memo[key] = knapsack(weights, values, capacity, n - 1); - } else { - memo[key] = max(values[n - 1] + knapsack(weights, values, capacity - weights[n - 1], n - 1), - knapsack(weights, values, capacity, n - 1)); - } - return memo[key]; -} - -int main() { - int weights[] = {1, 2, 3}; - int values[] = {10, 15, 40}; - int capacity = 6; - int n = sizeof(values) / sizeof(values[0]); - cout << knapsack(weights, values, capacity, n) << endl; // Output: 55 - return 0; -} - -``` - -## Applications of Memoization in Competitive Programming - -In competitive programming, memoization is widely used for solving problems that involve recursive algorithms with overlapping subproblems. Some of its applications include: - -1. **Dynamic Programming**: Many dynamic programming problems, such as Fibonacci numbers, knapsack problems, and longest common subsequence, can be solved using memoization to optimize recursive solutions. - -2. **Combinatorial Problems**: Problems that involve combinations and permutations often benefit from memoization, allowing efficient computation of results without repeated calculations. - -3. **Game Theory**: In game theory problems, memoization can help efficiently compute the outcomes of recursive game scenarios. - -4. **Graph Problems**: Some graph problems, particularly those that involve paths and cycles, can also be optimized using memoization. - -## Conclusion - -Memoization is a powerful technique in computer science that enhances the performance of recursive algorithms by storing previously computed results. Its applications span various domains, particularly in dynamic programming and competitive programming. Mastering memoization equips programmers with essential tools to tackle complex problems efficiently, providing a significant advantage in both academic and professional settings. - diff --git a/docs/algorithms/modular-exponentiation-algorithm.md b/docs/algorithms/modular-exponentiation-algorithm.md deleted file mode 100644 index de180b95f..000000000 --- a/docs/algorithms/modular-exponentiation-algorithm.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: modular-exponentiation-algorithm -title: Modular Exponentiation Algorithm -sidebar_label: Modular Exponentiation -sidebar_position: 10 -description: "Modular Exponentiation is an algorithm used to efficiently compute large powers modulo a number, using a technique called exponentiation by squaring." -tags: [Modular Arithmetic, Exponentiation, Algorithms, Number Theory, Recursion] ---- - -# Modular Exponentiation Algorithm - -## Overview -**Modular Exponentiation** is an efficient algorithm for computing large powers modulo a number. This algorithm is widely used in cryptography and number theory, where dealing with large numbers is common, and directly calculating powers can lead to overflow. Instead of calculating `base^exp` first and then taking the modulo, **modular exponentiation** computes `(base^exp) % mod` efficiently using the **exponentiation by squaring** method, reducing the time complexity to logarithmic. - -## Problem Description -- **Input**: Three integers, `base`, `exp`, and `mod`, where: - - `base` is the base number to be raised to the power. - - `exp` is the exponent to which the base is raised. - - `mod` is the number by which the result will be reduced. -- **Output**: The result of `(base^exp) % mod`, calculated efficiently. -- **Constraints**: Large values for `base` and `exp` make a direct approach infeasible, so modular exponentiation is necessary for efficiency. - -## Solution approach -The **modular exponentiation algorithm** employs **exponentiation by squaring**, which reduces the problem size at each step by halving the exponent. This approach can be implemented recursively or iteratively and uses the following properties: - -- If `exp` is even: - $$ - \text{base}^{\text{exp}} = (\text{base}^{\text{exp}/2})^2 - $$ -- If `exp` is odd: - $$ - \text{base}^{\text{exp}} = \text{base} \times (\text{base}^{(\text{exp}-1)/2})^2 - $$ - -At each step, the intermediate result is taken modulo `mod` to keep the numbers manageable. - -### Key Steps -1. **Initialize the result** to 1. -2. **Iterate while `exp > 0`**: - - If `exp` is odd, multiply `result` by `base` and take modulo `mod`. - - Square the `base` and take modulo `mod`. - - Divide the exponent by 2. -3. Return the final `result` after the loop terminates. - -## Code Example - -```python -def modular_exponentiation(base, exp, mod): - result = 1 - base = base % mod # Update base if it's more than mod - - while exp > 0: - if exp % 2 == 1: # If exp is odd - result = (result * base) % mod - - base = (base * base) % mod # Square the base - exp //= 2 # Reduce exp by half - - return result - -# Example usage -result = modular_exponentiation(2, 10, 1000) -print(result) # Output: 24 -``` -## Time Complexity -The time complexity of the modular exponentiation algorithm is significantly reduced by the exponentiation by squaring technique. - -### Time Complexity Overview -- **Time Complexity**: O(log(exp)) - The algorithm reduces the exponent by half in each iteration, leading to a logarithmic number of steps relative to the size of the exponent. Each step involves constant-time operations like multiplication and modulo, so the overall time complexity is logarithmic. - -## Space Complexity -- **Space Complexity**: O(1) - The space complexity is constant because only a few variables (such as `base`, `exp`, and `result`) are required to perform the computation. - -## Applications -- **Cryptography**: Modular exponentiation is heavily used in cryptographic algorithms such as RSA, Diffie-Hellman key exchange, and ElGamal. -- **Number Theory**: Many problems in number theory, especially those related to prime numbers and modular arithmetic, rely on modular exponentiation. -- **Efficient Computation**: This algorithm is used in any scenario where large powers need to be computed modulo a number without causing overflow or performance issues. - -## Conclusion -The Modular Exponentiation Algorithm provides an efficient way to compute large powers modulo a number. It leverages the technique of exponentiation by squaring to reduce the number of operations from exponential to logarithmic time. This algorithm is crucial in fields like cryptography and number theory, where operations with large numbers are common and need to be performed efficiently. diff --git a/docs/algorithms/moores-voting-algorithm/moore-voting-algo.md b/docs/algorithms/moores-voting-algorithm/moore-voting-algo.md deleted file mode 100644 index e344d3527..000000000 --- a/docs/algorithms/moores-voting-algorithm/moore-voting-algo.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: moores-voting-algorithm -sidebar_position: 15 -title: "Moore's Voting Algorithm" -sidebar_label: Voting Algorithm ---- - -### Definition: - -Moore's Voting Algorithm is an efficient algorithm to find the majority element in an array. A majority element is defined as the element that appears more than N/2 times in the array, where N is the size of the array. The algorithm operates in linear time and uses constant space, making it optimal for this problem. - -### Characteristics: - -- **Two-Pass Algorithm**: - The algorithm works in two passes: - - - In the first pass, it finds a candidate for the majority element. - - In the second pass, it confirms whether the candidate is indeed the majority element. - -- **Linear Time Complexity**: - The algorithm runs in $O(N)$ time, where N is the number of elements in the array. - -- **Constant Space Complexity**: - It only requires a few extra variables, resulting in $O(1)$ space complexity. - -### Time Complexity: - -- **Best Case: $O(N)$** - The algorithm processes each element once during both passes. - -- **Average Case: $O(N)$** - It consistently runs in linear time for any arrangement of elements. - -- **Worst Case: $O(N)$** - Regardless of the input distribution, the time complexity remains linear. - -### Space Complexity: - -- **Space Complexity: $O(1)$** - The algorithm uses a constant amount of extra space. - -### Approach: - -The algorithm follows these steps: - -1. **Candidate Selection**: - - - Initialize a variable `candidate` and a counter `count` to zero. - - Traverse the array: - - If `count` is zero, set the current element as `candidate` and increment `count`. - - If the current element is equal to `candidate`, increment `count`. - - If the current element is not equal to `candidate`, decrement `count`. - -2. **Validation**: - - Traverse the array again to count occurrences of `candidate`. - - If the count is greater than N/2, return `candidate`; otherwise, there is no majority element. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -class Solution { -public: - // Function to find the majority element - int majorityElement(vector& nums) { - int candidate = -1, count = 0; - - // First pass to find the candidate - for (int num : nums) { - if (count == 0) { - candidate = num; - count = 1; - } else if (num == candidate) { - count++; - } else { - count--; - } - } - - // Second pass to confirm the candidate - count = 0; - for (int num : nums) { - if (num == candidate) { - count++; - } - } - - // Check if candidate is a majority element - if (count > nums.size() / 2) { - return candidate; - } else { - return -1; // No majority element - } - } -}; - -int main() { - vector nums = {3, 3, 4, 2, 4, 4, 2, 4, 4}; - - // Create an instance of Solution class - Solution sol; - - // Find the majority element - int majority = sol.majorityElement(nums); - - // Print the majority element - if (majority != -1) { - cout << "The majority element is: " << majority << endl; - } else { - cout << "No majority element exists." << endl; - } - - return 0; -} -``` diff --git a/docs/algorithms/recursive-algorithms/DirectRecursion.md b/docs/algorithms/recursive-algorithms/DirectRecursion.md deleted file mode 100644 index 8a965f355..000000000 --- a/docs/algorithms/recursive-algorithms/DirectRecursion.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -id: direct-recursion-algo -sidebar_position: 1 -title: Direct Recursion -sidebar_label: Direct Recursion ---- - -### Definition: - -Direct recursion is when a function calls itself directly. The function keeps calling itself with a modified argument until a base case is met, which stops the recursion. Direct recursion is used to solve problems that can be broken down into smaller, similar subproblems. - -### Characteristics: - -- **Self-Calling Function:** - - A function is directly recursive if it calls itself within its own body. - -- **Base Case:** - - A base case is required to stop the recursive calls, preventing infinite recursion. - -- **Multiple Calls:** - - The function may call itself once or multiple times depending on the problem. - -### Time Complexity: - -- **Time Complexity: O(n)** - The time complexity of direct recursion depends on the problem. For simple problems like calculating a factorial, it usually takes linear time `O(n)` where `n` is the input size. - -### Space Complexity: - -- **Space Complexity: O(n)** - Each recursive call takes up space on the call stack, leading to a space complexity proportional to the depth of the recursion. - -### Example Problems: - -1. **Factorial Function:** - - The factorial of a number `n` is defined as `n! = n * (n-1) * (n-2) * ... * 1`. We can calculate the factorial using direct recursion. - - ```cpp - #include - using namespace std; - - int factorial(int n) { - if (n <= 1) return 1; // Base case - return n * factorial(n - 1); // Recursive call - } - - int main() { - int num = 5; - cout << "Factorial of " << num << " is " << factorial(num) << endl; - return 0; - } - ``` - - - In this example, the function `factorial()` calls itself until `n` becomes 1, which is the base case. - -2. **Sum of First N Natural Numbers:** - - We can use direct recursion to find the sum of the first `n` natural numbers. - - ```cpp - #include - using namespace std; - - int sum(int n) { - if (n == 0) return 0; // Base case - return n + sum(n - 1); // Recursive call - } - - int main() { - int n = 10; - cout << "Sum of first " << n << " natural numbers is " << sum(n) << endl; - return 0; - } - ``` - - - In this example, the function `sum()` calls itself, reducing the value of `n` by 1 at each step until it reaches 0, the base case. - -3. **Fibonacci Sequence:** - - The Fibonacci sequence is a series where each number is the sum of the two preceding ones, starting with 0 and 1. We can compute the nth Fibonacci number using direct recursion. - - ```cpp - #include - using namespace std; - - int fibonacci(int n) { - if (n <= 1) return n; // Base cases - return fibonacci(n - 1) + fibonacci(n - 2); // Recursive calls - } - - int main() { - int n = 5; - cout << "Fibonacci of " << n << " is " << fibonacci(n) << endl; - return 0; - } - ``` - - - Here, the function `fibonacci()` calls itself twice to compute the Fibonacci numbers for `n-1` and `n-2`. - -### Recursive Tree: - -Direct recursion often generates a recursion tree, where each function call spawns new calls, visualizing the branching structure of recursive calls. - -### Common Applications: - -- Factorial calculation -- Fibonacci sequence -- Tower of Hanoi -- Sum of a series -- Tree traversal - -### C++ Implementation: - -**Factorial Example (Direct Recursion)** -```cpp -#include -using namespace std; - -int factorial(int n) { - if (n <= 1) return 1; // Base case - return n * factorial(n - 1); // Recursive call -} - -int main() { - int num = 5; - cout << "Factorial of " << num << " is " << factorial(num) << endl; - return 0; -} -``` - -**Sum of First N Natural Numbers (Direct Recursion)** -```cpp -#include -using namespace std; - -int sum(int n) { - if (n == 0) return 0; // Base case - return n + sum(n - 1); // Recursive call -} - -int main() { - int n = 10; - cout << "Sum of first " << n << " natural numbers is " << sum(n) << endl; - return 0; -} -``` - -**Fibonacci Example (Direct Recursion)** -```cpp -#include -using namespace std; - -int fibonacci(int n) { - if (n <= 1) return n; // Base case - return fibonacci(n - 1) + fibonacci(n - 2); // Recursive call -} - -int main() { - int n = 5; - cout << "Fibonacci of " << n << " is " << fibonacci(n) << endl; - return 0; -} -``` - -### Summary: - -Direct recursion is a simple yet powerful tool for solving problems that involve repetitive or self-similar subproblems. The key challenge lies in identifying the base case to prevent infinite recursion and understanding the problem well enough to break it down recursively. diff --git a/docs/algorithms/recursive-algorithms/IndirectRecursion.md b/docs/algorithms/recursive-algorithms/IndirectRecursion.md deleted file mode 100644 index 9c1b4511c..000000000 --- a/docs/algorithms/recursive-algorithms/IndirectRecursion.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: indirect-recursion-algo -sidebar_position: 2 -title: Indirect Recursion -sidebar_label: Indirect Recursion ---- - -### Definition: - -Indirect recursion occurs when a function calls another function, and eventually, the second function calls the first function back. This process forms a cycle of function calls between two or more functions, instead of a single function calling itself directly. - -### Characteristics: - -- **Mutual Call:** - - In indirect recursion, two or more functions call each other in a cyclic manner. - -- **Base Case:** - - Each recursive cycle must include a base case to prevent infinite loops and ensure termination. - -- **Multiple Functions:** - - Indirect recursion involves more than one function. A function calls another, which in turn calls the first one back. - -### Time Complexity: - -- **Time Complexity: O(n)** - - The time complexity of indirect recursion depends on the number of recursive calls. For simple problems, it is typically linear `O(n)`. - -### Space Complexity: - -- **Space Complexity: O(n)** - - Each recursive call uses stack space, leading to a space complexity proportional to the depth of the recursion. - -### Example Problems: - -1. **Odd and Even Numbers:** - - In this example, we use two functions: one for checking even numbers and another for odd numbers. The function `isEven()` calls `isOdd()`, and `isOdd()` calls `isEven()` until the base case is reached. - - ```cpp - #include - using namespace std; - - bool isEven(int n); - bool isOdd(int n); - - bool isEven(int n) { - if (n == 0) return true; // Base case - return isOdd(n - 1); // Call isOdd - } - - bool isOdd(int n) { - if (n == 0) return false; // Base case - return isEven(n - 1); // Call isEven - } - - int main() { - int num = 5; - if (isEven(num)) { - cout << num << " is even." << endl; - } else { - cout << num << " is odd." << endl; - } - return 0; - } - ``` - - - Here, `isEven()` calls `isOdd()`, and `isOdd()` calls `isEven()`. This continues until the base case is met. - -2. **Mutually Recursive Functions:** - - Another classic example of indirect recursion is mutually recursive functions, where one function calls another, and the second function calls the first function back in a loop. - - ```cpp - #include - using namespace std; - - void functionA(int n); - void functionB(int n); - - void functionA(int n) { - if (n > 0) { - cout << "In Function A: " << n << endl; - functionB(n - 1); // Call functionB - } - } - - void functionB(int n) { - if (n > 0) { - cout << "In Function B: " << n << endl; - functionA(n / 2); // Call functionA - } - } - - int main() { - int num = 10; - functionA(num); // Start the recursion chain - return 0; - } - ``` - - - In this example, `functionA()` calls `functionB()`, and `functionB()` calls `functionA()`. The base case for each function ensures termination. - -### Recursive Tree: - -Just like direct recursion, indirect recursion forms a recursion tree. However, the branches of this tree involve multiple functions that call each other in cycles. Each function call is part of a chain, leading back to earlier calls. - -### Applications: - -Indirect recursion is often used in: -- State machines -- Parsing algorithms -- Handling mutually exclusive conditions (like odd/even checks) - -### Common Challenges: - -- **Tracking Function Calls:** - - Indirect recursion can be more challenging to understand and debug because multiple functions are involved, and keeping track of the flow of execution can be complex. - -- **Base Case Design:** - - Designing appropriate base cases for each function in the recursion cycle is crucial to ensure that the recursion terminates. - -### C++ Implementation: - -**Odd and Even Checker (Indirect Recursion)** -```cpp -#include -using namespace std; - -bool isEven(int n); -bool isOdd(int n); - -bool isEven(int n) { - if (n == 0) return true; // Base case - return isOdd(n - 1); // Call isOdd -} - -bool isOdd(int n) { - if (n == 0) return false; // Base case - return isEven(n - 1); // Call isEven -} - -int main() { - int num = 5; - if (isEven(num)) { - cout << num << " is even." << endl; - } else { - cout << num << " is odd." << endl; - } - return 0; -} -``` - -**Mutually Recursive Functions (Indirect Recursion)** -```cpp -#include -using namespace std; - -void functionA(int n); -void functionB(int n); - -void functionA(int n) { - if (n > 0) { - cout << "In Function A: " << n << endl; - functionB(n - 1); // Call functionB - } -} - -void functionB(int n) { - if (n > 0) { - cout << "In Function B: " << n << endl; - functionA(n / 2); // Call functionA - } -} - -int main() { - int num = 10; - functionA(num); // Start the recursion chain - return 0; -} -``` - -### Summary: - -Indirect recursion occurs when two or more functions call each other in a cycle. It's an important concept in recursive algorithms, but it can be harder to follow due to the involvement of multiple functions. The base cases for each function in the cycle must be carefully designed to ensure the recursion terminates. diff --git a/docs/algorithms/recursive-algorithms/_category_.json b/docs/algorithms/recursive-algorithms/_category_.json deleted file mode 100644 index 3c3ce0fd6..000000000 --- a/docs/algorithms/recursive-algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Recursive Algorithms", - "position": 1, - "link": { - "type": "generated-index", - "description": "Learn about some Recursive Algorithms." - } - } \ No newline at end of file diff --git a/docs/algorithms/recursive-algorithms/mutual-recursion.md b/docs/algorithms/recursive-algorithms/mutual-recursion.md deleted file mode 100644 index 03968b4b5..000000000 --- a/docs/algorithms/recursive-algorithms/mutual-recursion.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -id: mutual-recursion -title: Mutual Recursion -sidebar_label: "Mutual Recursion" -sidebar_position: 1 -description: An overview of mutual recursion and its applications in programming. -tags: [recursion, algorithms, programming] ---- - - -# Mutual Recursion - -## Definition -Mutual recursion occurs when two or more functions recursively call each other. This means that the execution of one function depends on the execution of another, allowing for a collaborative approach to solving problems. - -## Why It Is Useful -Mutual recursion is useful for problems where two or more related tasks need to be handled in tandem. It is particularly applicable in: -- Algorithms that involve alternating behaviours, such as even and odd calculations. -- Solving problems in graph theory, where different conditions can trigger different functions. - -## Time Complexity Analysis - -### Best Case -The best case occurs when the mutual recursion reaches the base case quickly, requiring minimal calls. - -**Example:** -For a simple alternating function that checks even and odd: -```python -def is_even(n): - if n == 0: - return True - return is_odd(n - 1) - -def is_odd(n): - if n == 0: - return False - return is_even(n - 1) -``` -If $ n = 0 $, the function returns immediately. - -**Time Complexity:** -$ O(1) $ - -### Worst Case -The worst case occurs when the mutual recursion continues to call each other before reaching a base case. - -**Example:** Using the same alternating function: For $ n = 5 $, the function makes multiple calls, alternating between `is_even` and `is_odd`. - -**Time Complexity:** -$ O(n) $ - -## Example Using Mutual Recursion - -### Problem: Check Even or Odd - -### Dry Run -For $ n = 3 $, the recursive process would look like this: - -1. Start with `is_even(3)` - - Calls `is_odd(2)` - - Calls `is_even(1)` - - Calls `is_odd(0)` - - Returns `False` (base case) - - Returns `True` (1 is odd) - - Returns `False` (2 is even) - - Returns `True` (3 is odd) - -**Final Result:** `is_even(3)` returns `False`, indicating that 3 is odd. - -## Advantages of Mutual Recursion - -1. **Structured Code**: Mutual recursion can provide a more organized structure for code by separating different behaviours into distinct functions. - -2. **Clear Logic**: It can make the logic of certain algorithms clearer, especially when two functions are clearly related to the problem at hand. - -3. **Natural Problem Solving**: Some problems naturally fit into a mutual recursion pattern, allowing for straightforward implementation. - -## Disadvantages of Mutual Recursion - -1. **Complexity**: Understanding and debugging mutual recursion can be more complex than single recursion due to the interaction between functions. - -2. **Performance Issues**: Similar to tree recursion, mutual recursion can lead to inefficiencies if not optimized, particularly in terms of time complexity. - -3. **Stack Overflow Risk**: Deep mutual recursion can also lead to stack overflow errors, especially in languages without tail call optimization. - -## Code Implementation of Mutual Recursion - -### C Implementation: -```c -#include - -int is_even(int n); -int is_odd(int n); - -int is_even(int n) { - if (n == 0) { - return 1; // True (0 is even) - } - return is_odd(n - 1); -} - -int is_odd(int n) { - if (n == 0) { - return 0; // False (0 is not odd) - } - return is_even(n - 1); -} - -int main() { - int number = 3; - if (is_even(number)) { - printf("%d is even\n", number); - } else { - printf("%d is odd\n", number); - } - return 0; -} -``` -### Python Implementation: - -```python -def is_even(n): - if n == 0: - return True # 0 is even - return is_odd(n - 1) - -def is_odd(n): - if n == 0: - return False # 0 is not odd - return is_even(n - 1) - -number = 3 -if is_even(number): - print(f"{number} is even") -else: - print(f"{number} is odd") -``` -### Java Implementation : -```java -public class MutualRecursion { - public static boolean isEven(int n) { - if (n == 0) { - return true; // 0 is even - } - return isOdd(n - 1); - } - - public static boolean isOdd(int n) { - if (n == 0) { - return false; // 0 is not odd - } - return isEven(n - 1); - } - - public static void main(String[] args) { - int number = 3; - if (isEven(number)) { - System.out.println(number + " is even"); - } else { - System.out.println(number + " is odd"); - } - } -} -``` diff --git a/docs/algorithms/recursive-algorithms/non-tail-recursion.md b/docs/algorithms/recursive-algorithms/non-tail-recursion.md deleted file mode 100644 index 21957da58..000000000 --- a/docs/algorithms/recursive-algorithms/non-tail-recursion.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: non-tail-recursion -title: Non-Tail Recursion -sidebar_label: "Non-Tail Recursion" -sidebar_position: 2 -description: An overview of Non-Tail Recursion and its applications in programming. -tags: [recursion, algorithms, programming] ---- - -# Non-Tail Recursion - -## Definition -Non-tail recursion occurs when a recursive function performs some operations **after** making the recursive call. In contrast to tail recursion, where the recursive call is the final action in the function, non-tail recursion does not allow for optimization techniques like tail-call optimization because the function needs to retain its current state until further operations are completed. - -## Why It Is Useful -- **Post-processing**: Non-tail recursion is useful in scenarios where the function needs to do some work after the recursive call, such as aggregating results or performing cleanup. -- **Natural fit for divide-and-conquer**: Algorithms like merge sort or tree traversal require post-processing, making non-tail recursion essential. -- **Simpler logic**: Problems like calculating factorial, Fibonacci, or solving complex mathematical equations often become easier to understand and implement with non-tail recursion. - -## Time Complexity Analysis - -### Example 1: Factorial Calculation - -**Function:** -```txt -factorial(n) { - if (n == 0) - return 1; - else - return n * factorial(n-1); -} -``` - -## Best Case -In the best case, the function will stop as soon as the base condition is met (n == 0). This happens in constant time: - -**Best-case complexity: O(1).** -## Worst Case -In the worst case, the function will recurse n times, leading to: - -**Worst-case complexity: O(n).** - -## Example of Non-Tail Recursion: Factorial Calculation - -### Dry Run - -**Input:** `n = 3` - -1. `factorial(3)` calls `factorial(2)` -> `3 * factorial(2)` -2. `factorial(2)` calls `factorial(1)` -> `2 * factorial(1)` -3. `factorial(1)` calls `factorial(0)` -> `1 * factorial(0)` -4. `factorial(0)` returns `1` -5. `factorial(1)` returns `1 * 1 = 1` -6. `factorial(2)` returns `2 * 1 = 2` -7. `factorial(3)` returns `3 * 2 = 6` - -## Advantages and Disadvantages of Non-Tail Recursion - -### Advantages -1. **Easier to Implement**: - - Non-tail recursion often leads to simpler and more intuitive code for certain problems, especially when the problem requires combining results from recursive calls. - -2. **Preserves State**: - - Intermediate results are maintained in the call stack, allowing for complex operations after recursive calls without needing additional data structures. - -3. **Natural for Certain Algorithms**: - - Many algorithms, like tree traversals and divide-and-conquer algorithms (e.g., merge sort), are more naturally expressed using non-tail recursion. - -4. **Flexibility**: - - It can handle problems that involve multiple recursive calls or those that need post-processing of results from recursive calls. - -### Disadvantages -1. **Higher Memory Usage**: - - Non-tail recursion consumes more stack space because each call adds a new frame to the call stack, which can lead to stack overflow for deep recursion. - -2. **Performance Overhead**: - - The overhead of maintaining multiple active frames on the stack can slow down execution, especially compared to tail recursion, which can be optimized by compilers. - -3. **Limited Optimization**: - - Non-tail recursive functions cannot take advantage of tail call optimization (TCO), which reduces the function's call stack depth and enhances performance. - -4. **Complex Debugging**: - - Debugging non-tail recursive functions can be more challenging due to the multiple active states on the call stack, making it harder to track values and flow of execution. - - - -# Code Implementation: - -### C Implementation : - -```c -#include - -int factorial(int n) { - if (n == 0) - return 1; - return n * factorial(n - 1); // Non-tail recursion -} - -int main() { - int num = 3; - printf("Factorial of %d is %d\n", num, factorial(num)); - return 0; -} -``` - -### Python Implementation : - -```c -def factorial(n): - if n == 0: - return 1 - return n * factorial(n - 1) # Non-tail recursion - -num = 3 -print(f"Factorial of {num} is {factorial(num)}") -``` - -### Java Implementation : - -```c -public class Factorial { - public static int factorial(int n) { - if (n == 0) - return 1; - return n * factorial(n - 1); // Non-tail recursion - } - - public static void main(String[] args) { - int num = 3; - System.out.println("Factorial of " + num + " is " + factorial(num)); - } -} -``` diff --git a/docs/algorithms/recursive-algorithms/tail-recursion.md b/docs/algorithms/recursive-algorithms/tail-recursion.md deleted file mode 100644 index 96dfa164e..000000000 --- a/docs/algorithms/recursive-algorithms/tail-recursion.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: tail-recursion -title: Tail Recursion -sidebar_label: "Tail Recursion" -sidebar_position: 3 -description: An overview of Tail Recursion and its applications in programming. -tags: [recursion, algorithms, programming] ---- - -# Tail Recursion - -## Definition -**Tail recursion** is a form of recursion where the recursive call is the last operation in the function. After the recursive call, there are no additional operations left for the function to perform. In tail recursion, the result of the recursive call is immediately returned, allowing some compilers or interpreters to optimize the function call stack, transforming it into an iterative loop. - -- **Key Characteristic:** The recursive call occurs at the end of the function, and no computations follow it. - -## Why Is It Useful? -- **Stack Optimization:** Tail recursion allows compilers to optimize the call stack, using constant memory space instead of creating new stack frames for each recursive call. This process is called **Tail Call Optimization (TCO)**. -- **Prevents Stack Overflow:** In deeply recursive problems, tail recursion minimizes the risk of stack overflow by avoiding excessive memory consumption. -- **Improved Performance:** By reducing overhead through stack frame reuse, tail recursion can perform similarly to iterative solutions. - -# Time Complexity Analysis - -## Best Case Scenario: -The best case occurs when the function is called with minimal depth, such as when the recursion can terminate early. - -### Example: -A tail-recursive function that calculates the sum of numbers from `1` to `n`: - -```python -def sum_tail(n, acc=0): - if n == 0: - return acc - else: - return sum_tail(n - 1, acc + n) -``` -**Time Complexity (Best Case):** **O(1)** — constant time when n = 1 or the recursion depth is minimal.The recursion stops after one step ! - -## Worst Case Scenario: -The **worst case** happens when the recursion depth is maximum, requiring many recursive calls. - -### Example: -For n = 1000, the function will call itself 1000 times, each time reducing n by 1. - -**Time Complexity (Worst Case):** **O(n)** — linear time proportional to n, where n is the depth of recursion. - -## Example: Tail Recursive Factorial Calculation -Tail Recursion for Factorial -python -```c -def factorial_tail(n, acc=1): - if n == 0: - return acc - else: - return factorial_tail(n - 1, acc * n) -``` -## Dry Run Example for factorial_tail(5) -### For factorial_tail(5): - -- `factorial_tail(5, 1)` → Recursive call `factorial_tail(4, 5)` -- `factorial_tail(4, 5)` → Recursive call `factorial_tail(3, 20)` -- `factorial_tail(3, 20)` → Recursive call `factorial_tail(2, 60)` -- `factorial_tail(2, 60)` → Recursive call `factorial_tail(1, 120)` -- `factorial_tail(1, 120)` → Recursive call `factorial_tail(0, 120)` - -At this point, `n == 0`, so the function returns `120` (`5!`). - - - - -## Advantages of Tail Recursion -- **Memory Efficient:** It uses constant stack space due to tail call optimization, preventing stack overflow. -- **Simple and Readable:** The code remains simple and closely follows the recursive logic of the problem. -- **Performance Boost:** Tail recursion can be optimized to run as efficiently as loops. - -## Disadvantages of Tail Recursion -- **Compiler Dependency:** Not all programming languages or compilers support tail call optimization, which may prevent it from running efficiently in those cases. -- **Limited Use Cases:** It is only beneficial for problems that can be naturally solved using recursion. - -## Implementation - -### C Implementation -```c -#include - -int factorial_tail(int n, int acc) { - if (n == 0) - return acc; - return factorial_tail(n - 1, acc * n); -} - -int main() { - int n = 5; - printf("Factorial of %d is %d\n", n, factorial_tail(n, 1)); - return 0; -} - -``` - -### Python Implementation: - -```c -def factorial_tail(n, acc=1): - if n == 0: - return acc - else: - return factorial_tail(n - 1, acc * n) -``` - -### Java Implementation : -```c -public class TailRecursion { - public static int factorialTail(int n, int acc) { - if (n == 0) { - return acc; - } - return factorialTail(n - 1, acc * n); - } - - public static void main(String[] args) { - int n = 5; - System.out.println("Factorial of " + n + " is " + factorialTail(n, 1)); - } -} - -``` - diff --git a/docs/algorithms/recursive-algorithms/tree-recursion.md b/docs/algorithms/recursive-algorithms/tree-recursion.md deleted file mode 100644 index 33d5ed483..000000000 --- a/docs/algorithms/recursive-algorithms/tree-recursion.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: tree-recursion -title: Tree Recursion -sidebar_label: "Tree Recursion" -sidebar_position: 4 -description: An overview of Tree Recursion and its applications in programming. -tags: [recursion, algorithms, programming] ---- - -# Tree Recursion - -## Definition -Tree recursion is a type of recursion where a function makes multiple recursive calls, creating a branching structure similar to a tree. Each recursive call can further lead to multiple other calls, resulting in a tree-like structure of calls. - -## Why It Is Useful -Tree recursion is useful for solving problems that can be broken down into smaller subproblems, particularly in scenarios where the solution to the problem involves considering all possible combinations or arrangements. Common applications include: -- Generating permutations and combinations -- Solving problems in combinatorial optimization -- Traversing complex data structures like trees and graphs - -## Time Complexity Analysis -### Best Case -The best case occurs when the recursive function immediately reaches a base case without making multiple calls. - -**Example:** -For a recursive function that sums numbers until it reaches zero: -```python -def sum_numbers(n): - if n <= 0: - return 0 - return n + sum_numbers(n - 1) -``` - -If \(n = 0\), it will return immediately. - -**Time Complexity:** -\( **O(1)** \) - -### Worst Case -The worst case occurs when the recursive function generates a complete tree of calls before reaching a base case. - -**Example:** Consider the Fibonacci function defined recursively: -```python -def fibonacci(n): - if n <= 1: - return n - return fibonacci(n - 1) + fibonacci(n - 2) -``` - - - -For n=5, the function makes multiple calls, leading to a binary tree structure of calls. - -Time Complexity: -\( O(2^n) \) -## Example Using Tree Recursion - -### Problem: Generate All Permutations of a List - -### Dry Run -For the list `[1, 2]`, the recursive process would look like this: - -1. Start with the list `[1, 2]` - - Choose `1` and permute `[2]` → yields `[1, 2]` - - Choose `2` and permute `[1]` → yields `[2, 1]` -2. The results are `[[1, 2], [2, 1]]` - -## Advantages of Tree Recursion - -1. **Simplicity**: Tree recursion can lead to simpler and more readable code, especially for problems that inherently require exploring multiple possibilities, such as generating permutations or combinations. - -2. **Natural Fit for Certain Problems**: Many problems, particularly those involving combinatorial constructs or tree-like structures, can be solved more naturally using tree recursion. - -3. **Flexible Exploration**: It allows for an exhaustive exploration of all possible solutions, making it suitable for problems where all configurations need to be considered. - -## Disadvantages of Tree Recursion - -1. **High Time Complexity**: Tree recursion can lead to exponential time complexity, especially in problems like the Fibonacci sequence, where the same subproblems are solved multiple times. - -2. **Space Complexity**: The recursive calls can consume a significant amount of stack space, potentially leading to stack overflow for large inputs. - -3. **Inefficiency**: Due to the overlapping subproblems, many tree recursive algorithms can be inefficient. Memoization or dynamic programming is often preferred in such cases to optimize performance. - - -## Code Implementation - -### C Implementation - -```c -#include - -void swap(char *x, char *y) { - char temp = *x; - *x = *y; - *y = temp; -} - -void permute(char *a, int l, int r) { - if (l == r) { - printf("%s\n", a); - } else { - for (int i = l; i <= r; i++) { - swap((a + l), (a + i)); - permute(a, l + 1, r); - swap((a + l), (a + i)); // backtrack - } - } -} - -int main() { - char str[] = "12"; - int n = strlen(str); - permute(str, 0, n - 1); - return 0; -} -``` - -### Python Implementation: - -```python -def permute(s): - if len(s) == 1: - return [s] - result = [] - for i, char in enumerate(s): - for perm in permute(s[:i] + s[i+1:]): - result.append(char + perm) - return result - -# Example Usage -print(permute("12")) -``` -### Java Implementation: - -```java -import java.util.ArrayList; - -public class Permutation { - public static void permute(String str, String current) { - if (str.length() == 0) { - System.out.println(current); - } else { - for (int i = 0; i < str.length(); i++) { - permute(str.substring(0, i) + str.substring(i + 1), current + str.charAt(i)); - } - } - } - - public static void main(String[] args) { - String str = "12"; - permute(str, ""); - } -} -``` diff --git a/docs/algorithms/sorting-algorithms/BitonicSort.md b/docs/algorithms/sorting-algorithms/BitonicSort.md deleted file mode 100644 index e410eaf67..000000000 --- a/docs/algorithms/sorting-algorithms/BitonicSort.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -id: bitonic-sort-algo -sidebar_position: 12 -title: Bitonic Sort -sidebar_label: Bitonic Sort -description: A detailed guide on the Bitonic Sort algorithm with Python implementation examples. -tags: [bitonic sort, algorithms, sorting algorithms] ---- - -### Definition: - -Bitonic sort is a **parallel sorting algorithm** that can sort a sequence of numbers into bitonic sequences and then merge them in a manner that results in a completely sorted sequence. It is primarily used in **parallel computing environments**. - -### Characteristics: - -- **Bitonic Sequence**: - - - A bitonic sequence is a sequence that first increases and then decreases, or vice versa. Bitonic sort leverages this property to efficiently split and merge subarrays. - -- **Parallel Sorting**: - - - Bitonic sort is highly efficient when implemented on parallel architectures, where multiple processors can perform the sorting operations concurrently. - -- **Recursive Structure**: - - Bitonic sort works by recursively splitting the array into smaller bitonic sequences, sorting those sequences, and then merging them. - -### Time Complexity: - -- **Best Case: O(log^2 n)** - Bitonic sort divides the sequence into subarrays and sorts them in parallel, resulting in logarithmic operations at each level of recursion. - -- **Average Case: O(log^2 n)** - Even in average cases, bitonic sort maintains its logarithmic time complexity. - -- **Worst Case: O(log^2 n)** - The worst case for bitonic sort is also $O(log^2 n)$ due to the structured recursion and parallel sorting capabilities. - -### Space Complexity: - -- **Space Complexity: O(n)** - Bitonic sort uses additional memory to store subarrays during the sorting process, but the overall space complexity is linear relative to the input size. - -### Python Implementation: - -```python -def bitonic_sort(arr, low, cnt, direction): - if cnt > 1: - k = cnt // 2 - bitonic_sort(arr, low, k, 1) # Sort in ascending order - bitonic_sort(arr, low + k, k, 0) # Sort in descending order - bitonic_merge(arr, low, cnt, direction) - -def bitonic_merge(arr, low, cnt, direction): - if cnt > 1: - k = cnt // 2 - for i in range(low, low + k): - if (direction == 1 and arr[i] > arr[i + k]) or (direction == 0 and arr[i] < arr[i + k]): - arr[i], arr[i + k] = arr[i + k], arr[i] - bitonic_merge(arr, low, k, direction) - bitonic_merge(arr, low + k, k, direction) - -def sort(arr, N, up=1): - bitonic_sort(arr, 0, N, up) - -# Example usage: -arr = [3, 7, 4, 8, 6, 2, 1, 5] -N = len(arr) -sort(arr, N) -print("Sorted array:", arr) -``` - -### Summary: - -Bitonic sort is a **parallel-friendly sorting algorithm** that is well-suited for distributed computing environments. With a time complexity of $O(log^2 n)$, it is very efficient for sorting large datasets in parallel. However, its sequential performance is not as competitive as other common sorting algorithms like quicksort or mergesort in practical applications. - diff --git a/docs/algorithms/sorting-algorithms/BogoSort.md b/docs/algorithms/sorting-algorithms/BogoSort.md deleted file mode 100644 index a430736b4..000000000 --- a/docs/algorithms/sorting-algorithms/BogoSort.md +++ /dev/null @@ -1,99 +0,0 @@ ---- - -id: bogo-sort-algo -sidebar_position: 13 -title: Bogo Sort -sidebar_label: Bogo Sort - ---- - -### Definition: - -Bogo Sort (also known as permutation sort, stupid sort, or slow sort) is a highly inefficient sorting algorithm based on the generate-and-test paradigm. The algorithm generates random permutations of the array until it finds one that is sorted. It is not practical for large arrays, as its average-case time complexity is extremely poor. - -### Characteristics: - -- **Generate-and-Test**: - - Bogo sort works by randomly shuffling the elements of an array and then checking if the array is sorted. This process repeats until the array is sorted. - -- **Highly Inefficient**: - - The time complexity of Bogo sort makes it unusable for all but the smallest inputs, as the number of permutations of an array grows factorially with its size. - -- **Not In-Place**: - - Bogo sort can be in-place or not depending on the implementation, though it's typically done in-place since no extra memory is needed aside from shuffling operations. - -- **Not Stable**: - - Since elements are randomly shuffled, Bogo sort does not preserve the relative order of equal elements, making it inherently unstable. - -### Time Complexity: - -- **Best Case: O(n)** - In the best-case scenario, the array is already sorted on the first check, so only one permutation is generated. - -- **Average Case: O((n+1)!)** - On average, Bogo sort requires generating and checking all possible permutations, leading to factorial time complexity. - -- **Worst Case: Unbounded** - In the worst-case scenario, Bogo sort could theoretically never find a sorted permutation, making the time to complete unbounded. - -### Space Complexity: - -- **Space Complexity: O(1)** - Bogo sort requires no additional space other than the input array, as it works in-place by shuffling the array. - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -// Function to check if the array is sorted -bool isSorted(int arr[], int size) { - for (int i = 0; i < size - 1; i++) { - if (arr[i] > arr[i + 1]) { - return false; - } - } - return true; -} - -// Function to shuffle the array randomly -void shuffle(int arr[], int size) { - for (int i = 0; i < size; i++) { - swap(arr[i], arr[rand() % size]); - } -} - -// Function to perform Bogo sort -void bogoSort(int arr[], int size) { - while (!isSorted(arr, size)) { - shuffle(arr, size); - } -} - -int main() { - srand(time(0)); - int arr[] = {3, 2, 5, 1, 4}; - int size = sizeof(arr) / sizeof(arr[0]); - - bogoSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Bogo sort is a highly inefficient sorting algorithm based on generating random permutations until the array is sorted. With an average-case time complexity of $O((n+1)!)$, it is impractical for anything but small arrays or as a teaching tool to illustrate inefficiency. Despite its impracticality, Bogo sort serves as a humorous example of how not to sort a list, given its extreme inefficiency. - -The main takeaway is that Bogo sort, while theoretically interesting, should not be used in practice due to its poor performance and high computational cost. - diff --git a/docs/algorithms/sorting-algorithms/BubbleSort.md b/docs/algorithms/sorting-algorithms/BubbleSort.md deleted file mode 100644 index ad7ba8703..000000000 --- a/docs/algorithms/sorting-algorithms/BubbleSort.md +++ /dev/null @@ -1,129 +0,0 @@ ---- - -id: bubble-sort-algo -sidebar_position: 1 -title: Bubble Sort -sidebar_label: Bubble Sort - ---- - -### Definition: - -Bubble sort is a simple comparison-based sorting algorithm that repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. This process continues until the list is sorted. - -### Characteristics: - -- **Repeated Comparison**: - - The algorithm compares each pair of adjacent elements and swaps them if they are out of order. It continues until no more swaps are needed. - -- **In-Place Sorting**: - - Bubble sort operates directly on the input array and does not require extra space, making it an in-place sorting algorithm. - -- **Stable**: - - Since the algorithm only swaps elements when necessary, the relative order of elements with equal values remains the same, making bubble sort a stable algorithm. - -- **Simple Implementation**: - - Bubble sort is easy to implement but not very efficient for large datasets. It's mainly used for educational purposes. - -### Time Complexity: - -- **Best Case: O(n)** - In the best-case scenario, where the array is already sorted, bubble sort only makes a single pass through the array without making any swaps. - -- **Average Case: O(n²)** - On average, bubble sort compares and swaps elements multiple times, leading to quadratic time complexity. - -- **Worst Case: O(n²)** - In the worst-case scenario, where the array is sorted in reverse order, the algorithm must compare and swap every element, making n-1 comparisons and swaps in each pass. - -### Space Complexity: - -- **Space Complexity: O(1)** - Bubble sort is an in-place algorithm, meaning it requires only a constant amount of extra memory, regardless of the input size. - -### C++ Implementation: - -**Iterative Approach** -```cpp -#include -using namespace std; - -void bubbleSortIterative(int arr[], int size) { - for (int i = 0; i < size - 1; i++) { - bool swapped = false; // To check if any swap happened in the current iteration - for (int j = 0; j < size - i - 1; j++) { - if (arr[j] > arr[j + 1]) { - // Swap arr[j] and arr[j + 1] - int temp = arr[j]; - arr[j] = arr[j + 1]; - arr[j + 1] = temp; - swapped = true; - } - } - // If no swap occurred, the array is already sorted - if (!swapped) { - break; - } - } -} - -int main() { - int arr[] = {64, 34, 25, 12, 22, 11, 90}; - int size = sizeof(arr) / sizeof(arr[0]); - - bubbleSortIterative(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -**Recursive Approach** -```cpp -#include -using namespace std; - -void bubbleSortRecursive(int arr[], int size) { - // Base case: If the array is of size 1, it's already sorted - if (size == 1) { - return; - } - - // Perform one pass of bubble sort - for (int i = 0; i < size - 1; i++) { - if (arr[i] > arr[i + 1]) { - // Swap arr[i] and arr[i + 1] - int temp = arr[i]; - arr[i] = arr[i + 1]; - arr[i + 1] = temp; - } - } - - // Recursively sort the remaining array - bubbleSortRecursive(arr, size - 1); -} - -int main() { - int arr[] = {64, 34, 25, 12, 22, 11, 90}; - int size = sizeof(arr) / sizeof(arr[0]); - - bubbleSortRecursive(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Bubble sort is one of the simplest sorting algorithms. While it is inefficient for large datasets due to its O(n²) time complexity, it provides an easy-to-understand introduction to sorting. Both the iterative and recursive versions of bubble sort are straightforward to implement, with the iterative version being more commonly used due to its simplicity. diff --git a/docs/algorithms/sorting-algorithms/BucketSort.md b/docs/algorithms/sorting-algorithms/BucketSort.md deleted file mode 100644 index 32d87a516..000000000 --- a/docs/algorithms/sorting-algorithms/BucketSort.md +++ /dev/null @@ -1,95 +0,0 @@ ---- - -id: bucket-sort-algo -sidebar_position: 9 -title: Bucket Sort -sidebar_label: Bucket Sort - ---- - -### Definition: - -Bucket sort is a comparison-based sorting algorithm that works by distributing elements into several "buckets" or ranges. Each bucket is sorted individually, either using another sorting algorithm or recursively applying bucket sort. Finally, the sorted buckets are concatenated to produce the final sorted array. - -### Characteristics: - -- **Distribution-Based Sorting**: - - Bucket sort distributes elements into different buckets, typically based on their value ranges, and then sorts the individual buckets. - -- **Efficient for Uniform Data Distribution**: - - Bucket sort is efficient when the input elements are uniformly distributed across the range, as each bucket will contain a relatively even number of elements. - -- **Not In-Place**: - - Bucket sort uses additional memory for the buckets, making it not an in-place algorithm. - -- **Stable**: - - Bucket sort is stable when the underlying sorting algorithm used within each bucket is stable. - -### Time Complexity: - -- **Best Case: O(n + k)** - In the best case, where the elements are evenly distributed across the buckets, and each bucket contains only a few elements, the overall time complexity is linear. - -- **Average Case: O(n + k)** - On average, bucket sort performs well when the elements are uniformly distributed. The average-case complexity is O(n + k), where `n` is the number of elements and `k` is the number of buckets. - -- **Worst Case: O(n²)** - The worst-case scenario occurs when all elements are placed in the same bucket, reducing bucket sort to a slower sorting algorithm (like insertion sort), leading to quadratic time complexity. - -### Space Complexity: - -- **Space Complexity: O(n + k)** - Bucket sort requires extra space for the buckets and the array storing the final result, leading to a space complexity of O(n + k). - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -// Function to perform bucket sort -void bucketSort(float arr[], int size) { - // Create empty buckets - vector buckets[size]; - - // Put array elements in different buckets based on their value - for (int i = 0; i < size; i++) { - int bucketIndex = size * arr[i]; // Index in the bucket array - buckets[bucketIndex].push_back(arr[i]); - } - - // Sort individual buckets using a sorting algorithm (here, insertion sort) - for (int i = 0; i < size; i++) { - sort(buckets[i].begin(), buckets[i].end()); - } - - // Concatenate all buckets into the sorted array - int index = 0; - for (int i = 0; i < size; i++) { - for (int j = 0; j < buckets[i].size(); j++) { - arr[index++] = buckets[i][j]; - } - } -} - -int main() { - float arr[] = {0.897, 0.565, 0.656, 0.1234, 0.665, 0.3434}; - int size = sizeof(arr) / sizeof(arr[0]); - - bucketSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Bucket sort is an efficient algorithm for sorting data that is uniformly distributed over a range. By dividing the data into smaller buckets and sorting them individually, bucket sort can achieve linear time complexity in the best and average cases. However, if the data is not evenly distributed, its worst-case time complexity can degrade to O(n²). Bucket sort is often used in conjunction with other algorithms and performs well when the number of buckets is proportional to the input size. Its primary trade-off is its need for additional space. diff --git a/docs/algorithms/sorting-algorithms/CocktailShakerSort.md b/docs/algorithms/sorting-algorithms/CocktailShakerSort.md deleted file mode 100644 index cfc40d45a..000000000 --- a/docs/algorithms/sorting-algorithms/CocktailShakerSort.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: cocktail-shaker-sort-algo -sidebar_position: 18 -title: Cocktail Shaker Sort -sidebar_label: Cocktail Shaker Sort ---- - -### Definition: - -Cocktail Shaker Sort, also known as Bidirectional Bubble Sort, is a variation of the Bubble Sort algorithm that sorts an array in both directions. It traverses the array back and forth, moving larger elements towards the end and smaller elements towards the beginning, making it more efficient than standard Bubble Sort in some cases. - -### Characteristics: - -- **Bidirectional**: - Unlike traditional sorting algorithms that only iterate in one direction, Cocktail Shaker Sort moves in both directions, which can help to reduce the total number of passes required. - -- **In-Place**: - The algorithm sorts the array without using any additional storage, modifying the input array directly. - -- **Stable**: - Cocktail Shaker Sort maintains the relative order of equal elements, making it a stable sorting algorithm. - -### Time Complexity: - -- **Best Case: O(n)** - When the array is already sorted, the algorithm makes a single pass. - -- **Average Case: O(n²)** - In most scenarios, the algorithm's performance resembles that of Bubble Sort. - -- **Worst Case: O(n²)** - Similar to Bubble Sort, the worst-case scenario occurs with a reversed array. - -### Space Complexity: - -- **Space Complexity: O(1)** - The algorithm operates in constant space since it only requires a few variables for swapping and indexing. - -### Java Implementation: - -```java -public class CocktailShakerSort { - - // Method to perform Cocktail Shaker Sort - public static void cocktailShakerSort(int[] arr) { - boolean swapped = true; - int start = 0; - int end = arr.length - 1; - - while (swapped) { - swapped = false; - - // Forward pass - for (int i = start; i < end; i++) { - if (arr[i] > arr[i + 1]) { - swap(arr, i, i + 1); - swapped = true; - } - } - - // If nothing moved, the array is sorted - if (!swapped) break; - - swapped = false; - end--; - - // Backward pass - for (int i = end; i > start; i--) { - if (arr[i] < arr[i - 1]) { - swap(arr, i, i - 1); - swapped = true; - } - } - - start++; - } - } - - // Helper method to swap two elements - private static void swap(int[] arr, int i, int j) { - int temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - - public static void main(String[] args) { - int[] arr = {5, 3, 1, 4, 2}; - cocktailShakerSort(arr); - System.out.println("Sorted array:"); - for (int num : arr) { - System.out.print(num + " "); - } - } -} -``` - -### Summary: -Cocktail Shaker Sort improves upon the standard Bubble Sort by processing the array in both directions, potentially reducing the number of iterations needed. Its bidirectional approach provides a simple yet effective alternative for sorting, though it still maintains a quadratic time complexity in average and worst-case scenarios, making it less efficient than more advanced algorithms like Quick Sort or Merge Sort. diff --git a/docs/algorithms/sorting-algorithms/CombSort.md b/docs/algorithms/sorting-algorithms/CombSort.md deleted file mode 100644 index d6d0e7e3b..000000000 --- a/docs/algorithms/sorting-algorithms/CombSort.md +++ /dev/null @@ -1,107 +0,0 @@ ---- - -id: comb-sort-algo -sidebar_position: 10 -title: Comb Sort -sidebar_label: Comb Sort - ---- - -### Definition: - -Comb sort is an improvement over bubble sort. It compares elements that are farther apart initially, decreasing the gap between elements in subsequent iterations. The idea is to eliminate "turtles" (small values near the end of the list) early in the sorting process, which slows down bubble sort. - -### Characteristics: - -- **Gap Decrease**: - - Comb sort starts by comparing elements that are far apart, reducing the gap by a shrinking factor (usually 1.3) after each pass until the gap becomes 1, at which point it behaves like bubble sort. - -- **In-Place Sorting**: - - Like bubble sort, comb sort is an in-place sorting algorithm, meaning it requires no extra memory aside from the input array. - -- **Unstable**: - - Comb sort is an unstable sorting algorithm, meaning that equal elements may not retain their relative order. - -- **Improvement over Bubble Sort**: - - By addressing "turtles" early, comb sort can improve upon the O(n²) performance of bubble sort, making it faster for larger datasets. - -### Time Complexity: - -- **Best Case: O(n log n)** - In the best case, where the array is already nearly sorted, comb sort runs in O(n log n) time due to the logarithmic reduction of the gap size. - -- **Average Case: O(n²/2ᵏ)** - The average case is better than bubble sort, though the exact complexity depends on the shrink factor used. - -- **Worst Case: O(n²)** - In the worst case, comb sort behaves similarly to bubble sort, with a time complexity of O(n²), though it performs faster in practice. - -### Space Complexity: - -- **Space Complexity: O(1)** - Comb sort is an in-place sorting algorithm, requiring only a constant amount of additional memory. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -// Function to find the next gap -int getNextGap(int gap) { - // Shrink gap by the shrink factor (typically 1.3) - gap = (gap * 10) / 13; - if (gap < 1) return 1; - return gap; -} - -// Function to perform comb sort -void combSort(int arr[], int size) { - // Initialize gap - int gap = size; - - // Initialize swapped as true to ensure that the process continues - bool swapped = true; - - // Keep running until the gap reduces to 1 and no more swaps occur - while (gap != 1 || swapped) { - // Find the next gap - gap = getNextGap(gap); - - // Initialize swapped as false so that we can check if a swap happened - swapped = false; - - // Compare all elements with current gap - for (int i = 0; i < size - gap; i++) { - if (arr[i] > arr[i + gap]) { - // Swap arr[i] and arr[i + gap] - int temp = arr[i]; - arr[i] = arr[i + gap]; - arr[i + gap] = temp; - - // Set swapped to true to indicate that a swap occurred - swapped = true; - } - } - } -} - -int main() { - int arr[] = {8, 4, 1, 56, 3, -44, 23, -6, 28, 0}; - int size = sizeof(arr) / sizeof(arr[0]); - - combSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Comb sort is an efficient improvement over bubble sort, with a time complexity that typically performs better on larger datasets. By comparing elements that are far apart and gradually reducing the gap size, it can handle "turtles" (small elements at the end) early in the process. While it has a worst-case time complexity of O(n²), its practical performance is much better, often approaching O(n log n). It's simple to implement, in-place, and better suited for real-world use than bubble sort. diff --git a/docs/algorithms/sorting-algorithms/CountingSort.md b/docs/algorithms/sorting-algorithms/CountingSort.md deleted file mode 100644 index 330dcc36a..000000000 --- a/docs/algorithms/sorting-algorithms/CountingSort.md +++ /dev/null @@ -1,106 +0,0 @@ ---- - -id: counting-sort-algo -sidebar_position: 8 -title: Counting Sort -sidebar_label: Counting Sort - ---- - -### Definition: - -Counting sort is a non-comparative sorting algorithm that sorts elements by counting the number of occurrences of each distinct element in the array. It works by determining the position of each element in the sorted output using a counting array. - -### Characteristics: - -- **Non-Comparative Sorting**: - - Counting sort does not compare elements directly but relies on counting occurrences of each element and uses these counts to determine their position in the sorted array. - -- **Stable**: - - Counting sort is a stable sorting algorithm because it maintains the relative order of equal elements when building the output array. - -- **Efficient for Small Ranges**: - - Counting sort is efficient when the range of input values is small compared to the number of elements in the array. - -- **Not In-Place**: - - Counting sort requires extra space proportional to the range of the input data, making it not an in-place algorithm. - -### Time Complexity: - -- **Best Case: O(n + k)** - Counting sort achieves linear time when the range of the input data (k) is not significantly larger than the number of elements (n). - -- **Average Case: O(n + k)** - The time complexity remains linear in most cases, provided that the range `k` is reasonably small compared to `n`. - -- **Worst Case: O(n + k)** - The worst-case time complexity occurs when the range of input values is large, resulting in extra space and time for the counting array. - -### Space Complexity: - -- **Space Complexity: O(n + k)** - Counting sort requires an extra counting array and an output array, resulting in a space complexity of O(n + k), where `k` is the range of the input values. - -### C++ Implementation: - -```cpp -#include -#include -using namespace std; - -// Counting sort function -void countingSort(int arr[], int size) { - // Find the maximum element in the array - int max = arr[0]; - for (int i = 1; i < size; i++) { - if (arr[i] > max) { - max = arr[i]; - } - } - - // Create a counting array to store count of each element - vector count(max + 1, 0); - - // Store the count of each element in the count array - for (int i = 0; i < size; i++) { - count[arr[i]]++; - } - - // Modify the count array to store the cumulative count of elements - for (int i = 1; i <= max; i++) { - count[i] += count[i - 1]; - } - - // Build the output array - vector output(size); - for (int i = size - 1; i >= 0; i--) { - output[count[arr[i]] - 1] = arr[i]; - count[arr[i]]--; - } - - // Copy the output array to arr[], so that arr[] now contains the sorted elements - for (int i = 0; i < size; i++) { - arr[i] = output[i]; - } -} - -int main() { - int arr[] = {4, 2, 2, 8, 3, 3, 1}; - int size = sizeof(arr) / sizeof(arr[0]); - - countingSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Counting sort is a highly efficient algorithm for sorting integers within a limited range. It performs in linear time, O(n + k), making it faster than comparison-based algorithms like quicksort or mergesort in certain situations. However, the space complexity, O(n + k), means it requires significant extra memory, making it less suitable for large datasets with a wide range of input values. Counting sort is often used as a subroutine in more advanced algorithms like radix sort, and it works best when the range of input data is small relative to the dataset size. - diff --git a/docs/algorithms/sorting-algorithms/CycleSort.md b/docs/algorithms/sorting-algorithms/CycleSort.md deleted file mode 100644 index 6f69c9bf1..000000000 --- a/docs/algorithms/sorting-algorithms/CycleSort.md +++ /dev/null @@ -1,131 +0,0 @@ ---- - -id: cycle-sort-algo -sidebar_position: 12 -title: Cycle Sort -sidebar_label: Cycle Sort - ---- - -### Definition: - -Cycle sort is a comparison-based, in-place sorting algorithm known for its optimal writes, making it one of the most efficient sorting algorithms in terms of the number of memory writes. It is designed to minimize the number of element movements, and each element is moved to its correct position as part of a cycle, hence the name. - -### Characteristics: - -- **Minimizes Writes**: - - Cycle sort is designed to minimize the number of memory writes. In fact, it performs the minimum possible number of writes to sort the array, making it ideal for scenarios where write operations are costly (e.g., memory-limited devices or flash storage). - -- **In-Place Sorting**: - - The algorithm sorts the array in place, requiring no additional memory beyond the input array. - -- **Unstable**: - - Cycle sort is an unstable sorting algorithm because it may change the relative order of equal elements during the rearrangement. - -- **Efficient in Write-Heavy Environments**: - - While not the most efficient in terms of time complexity, its ability to minimize write operations makes it useful in environments where writing to memory is expensive. - -### Time Complexity: - -- **Best Case: O(n²)** - Even in the best case, cycle sort has a time complexity of O(n²), as it requires traversing each cycle of elements in the array. - -- **Average Case: O(n²)** - On average, cycle sort performs a quadratic number of comparisons and swaps, making it inefficient for large datasets. - -- **Worst Case: O(n²)** - In the worst case, the time complexity remains O(n²), similar to algorithms like selection sort and bubble sort. - -### Space Complexity: - -- **Space Complexity: O(1)** - Cycle sort is an in-place algorithm, requiring no additional memory besides the input array. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -// Function to perform cycle sort -void cycleSort(int arr[], int size) { - for (int cycle_start = 0; cycle_start <= size - 2; cycle_start++) { - int item = arr[cycle_start]; - int pos = cycle_start; - - // Find position where we put the element - for (int i = cycle_start + 1; i < size; i++) { - if (arr[i] < item) { - pos++; - } - } - - // If the item is already in the correct position - if (pos == cycle_start) { - continue; - } - - // Skip duplicates - while (item == arr[pos]) { - pos++; - } - - // Put the item in its correct position - if (pos != cycle_start) { - swap(item, arr[pos]); - } - - // Rotate the rest of the cycle - while (pos != cycle_start) { - pos = cycle_start; - - // Find the position where we put the element - for (int i = cycle_start + 1; i < size; i++) { - if (arr[i] < item) { - pos++; - } - } - - // Skip duplicates - while (item == arr[pos]) { - pos++; - } - - // Put the item in its correct position - if (item != arr[pos]) { - swap(item, arr[pos]); - } - } - } -} - -int main() { - int arr[] = {20, 40, 50, 10, 30}; - int size = sizeof(arr) / sizeof(arr[0]); - - cycleSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Explanation: - -1. **Cycle Detection**: - - Cycle sort detects cycles in the permutation of elements. Each cycle is traversed, and the element is placed in its correct position, ensuring that elements are only written when necessary. - -2. **Efficient Memory Writes**: - - The key feature of cycle sort is its minimal memory writes. Each element is moved to its correct position only once in each cycle, which can reduce the total number of writes significantly. - -3. **Skipping Duplicates**: - - The algorithm handles duplicates by skipping over them when placing elements in their correct positions, ensuring that duplicate elements are sorted correctly without unnecessary swaps. - -### Summary: - -Cycle sort is unique in its ability to minimize the number of write operations, making it one of the most efficient algorithms in terms of memory writes. However, due to its quadratic time complexity, it is not suitable for large datasets in general-purpose sorting. Its primary use case is in environments where minimizing writes is critical, such as memory-limited systems or scenarios involving non-volatile memory. While it offers optimal performance in terms of writes, it has similar time complexity to simpler algorithms like selection sort and is best used when minimizing write operations is more important than optimizing time complexity. diff --git a/docs/algorithms/sorting-algorithms/Dutch-flag-algo.md b/docs/algorithms/sorting-algorithms/Dutch-flag-algo.md deleted file mode 100644 index a4e292692..000000000 --- a/docs/algorithms/sorting-algorithms/Dutch-flag-algo.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: sort-012-dutch-flag -sidebar_position: 14 -title: Sort 0s, 1s, and 2s using Dutch National Flag Algorithm -sidebar_label: Dutch Flag Algorithm - ---- - -### Definition: - -The Dutch National Flag Algorithm is an efficient sorting algorithm that sorts an array containing only 0's, 1's, and 2's in linear time. This algorithm uses a three-pointer approach and operates in-place, making it optimal in terms of both time and space. - -### Characteristics: - -- **Three Pointers**: - The algorithm uses three pointers, `low`, `mid`, and `high`: - - `low` is used to place 0's. - - `mid` is used to traverse the array. - - `high` is used to place 2's. - -- **In-Place Sorting**: - The array is sorted in-place without using extra space, making the algorithm space-efficient. - -- **Efficient for Specific Inputs**: - The algorithm is optimized for arrays with only three distinct values (0, 1, and 2), achieving linear time complexity. - -### Time Complexity: - -- **Best Case: $O(N)$** - The array is traversed only once using the `mid` pointer, resulting in linear time complexity. - -- **Average Case: $O(N)$** - The algorithm still runs in linear time even for a randomly arranged array, as each element is processed at most once. - -- **Worst Case: $O(N)$** - In the worst case, the array may require multiple swaps, but the time complexity remains O(N), where N is the size of the array. - -### Space Complexity: - -- **Space Complexity: $O(1)$** - The algorithm uses constant extra space since no additional arrays or data structures are required. - -### Approach: - -The algorithm works by using the three pointers (`low`, `mid`, and `high`) to partition the array into three sections: - -- `nums[0]` to `nums[low-1]` for 0's. -- `nums[low]` to `nums[mid-1]` for 1's. -- `nums[high+1]` to `nums[n-1]` for 2's. - -Here are the steps involved: - -1. Initialize `low` and `mid` at 0 and `high` at `sizeOfArray - 1`. -2. Iterate over the array with the `mid` pointer until `mid <= high`: - - If `nums[mid] == 0`, swap `nums[low]` and `nums[mid]`, and increment both `low` and `mid`. - - If `nums[mid] == 1`, simply increment `mid`. - - If `nums[mid] == 2`, swap `nums[mid]` and `nums[high]`, and decrement `high` without moving `mid`. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -class Solution { -public: - // Function to sort the array containing only 0s, 1s, and 2s - void sortZeroOneTwo(vector& nums) { - // 3 pointers: low, mid, high - int low = 0, mid = 0, high = nums.size() - 1; - - // Traverse the array using mid pointer - while (mid <= high) { - if (nums[mid] == 0) { - // Swap nums[low] and nums[mid], move both low and mid forward - swap(nums[low], nums[mid]); - low++; - mid++; - } - else if (nums[mid] == 1) { - // Move mid pointer forward - mid++; - } - else { - // Swap nums[mid] and nums[high], move high pointer backward - swap(nums[mid], nums[high]); - high--; - } - } - } -}; - -int main() { - vector nums = {0, 2, 1, 2, 0, 1}; - - // Create an instance of Solution class - Solution sol; - - // Sort the array - sol.sortZeroOneTwo(nums); - - // Print the array elements after sorting - cout << "After sorting:" << endl; - for (int i = 0; i < nums.size(); i++) { - cout << nums[i] << " "; - } - cout << endl; - - return 0; -} -``` -### Summary: -The Dutch National Flag Algorithm efficiently sorts an array containing only 0's, 1's, and 2's in a single traversal of the array. It achieves optimal time complexity of $O(N)$ and operates in-place, making it an ideal solution for this type of problem. The use of three pointers (low, mid, and high) ensures that the array is correctly partitioned, and the algorithm is both simple and effective. diff --git a/docs/algorithms/sorting-algorithms/GnomeSort.md b/docs/algorithms/sorting-algorithms/GnomeSort.md deleted file mode 100644 index 84bf0dd5c..000000000 --- a/docs/algorithms/sorting-algorithms/GnomeSort.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -id: gnome-sort-algo -sidebar_position: 16 -title: Gnome Sort -sidebar_label: Gnome Sort ---- - -### Definition: - -Gnome Sort is a simple comparison-based sorting algorithm that sorts an array by iterating through it and swapping adjacent elements if they are in the wrong order. If a swap occurs, the algorithm moves one position back; otherwise, it moves one position forward. The algorithm continues until the entire array is sorted. - -### Characteristics: - -- **Swapping**: - Gnome Sort swaps adjacent elements that are out of order. If the current element is larger than the next one, they are swapped, and the algorithm moves backward. If no swap occurs, it moves forward. - -- **In-Place**: - It does not require additional storage; hence it is an in-place sorting algorithm. - -- **Stable**: - Gnome Sort is stable, meaning it preserves the relative order of equal elements. - -### Time Complexity: - -- **Best Case: O(n)** - Occurs when the array is already sorted or nearly sorted, requiring minimal swaps. - -- **Average Case: O(n²)** - Similar to Bubble Sort, it performs poorly with larger datasets due to its quadratic time complexity. - -- **Worst Case: O(n²)** - This happens when the array is sorted in reverse order, leading to the maximum number of swaps. - -### Space Complexity: - -- **Space Complexity: O(1)** - As it sorts the array in place, the space requirement is constant. - -### Java Implementation: - -```java -public class GnomeSort { - - // Method to perform Gnome Sort - public static void gnomeSort(int[] arr) { - int index = 0; - while (index < arr.length) { - if (index == 0) { - index++; - } - if (arr[index] >= arr[index - 1]) { - index++; - } else { - // Swap arr[index] and arr[index - 1] - int temp = arr[index]; - arr[index] = arr[index - 1]; - arr[index - 1] = temp; - index--; - } - } - } - - public static void main(String[] args) { - int[] arr = {34, 2, 10, -9, 1}; - gnomeSort(arr); - System.out.println("Sorted array:"); - for (int num : arr) { - System.out.print(num + " "); - } - } -} -``` - -### Summary: -Gnome Sort is a straightforward algorithm that can be easily implemented but is inefficient for larger datasets due to its O(n²) average and worst-case time complexities. It is primarily of theoretical interest and is not commonly used in practice compared to more efficient algorithms like Quick Sort or Merge Sort. diff --git a/docs/algorithms/sorting-algorithms/HeapSort.md b/docs/algorithms/sorting-algorithms/HeapSort.md deleted file mode 100644 index 662a0c09a..000000000 --- a/docs/algorithms/sorting-algorithms/HeapSort.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -id: heap-sort-algo -sidebar_position: 6 -title: Heap Sort -sidebar_label: Heap Sort -description: A detailed guide on the Heap Sort algorithm with C++ implementation examples. -tags: [heap sort, algorithms, sorting algorithms] ---- - -### Definition: - -Heap sort is a **comparison-based** sorting algorithm that uses a binary heap data structure to efficiently find the largest or smallest element, depending on the heap type. It is an **in-place** and **non-stable** sorting algorithm that operates by first building a max heap and then extracting elements from it. - -### Characteristics: - -- **Binary Heap**: - - Heap sort is based on a complete binary tree structure called a heap. The two types of heaps are: - - **Max Heap**: The root is the largest element. - - **Min Heap**: The root is the smallest element. - -- **In-Place Sorting**: - - Heap sort sorts the array in place without requiring additional memory beyond the array itself, making it memory efficient. - -- **Non-Stable**: - - Heap sort is a non-stable sorting algorithm, meaning that the relative order of equal elements may not be preserved during the sorting process. - -- **No Recursive Calls**: - - Unlike recursive algorithms like merge sort, heap sort uses an iterative approach to build the heap and extract elements. - -### Time Complexity: - -- **Best Case: O(n log n)** - Heap sort involves building the heap $(O(n))$ and extracting elements from it $(O(n log n))$, so even in the best case, it requires $O(n log n)$ time. - -- **Average Case: O(n log n)** - Heap sort's time complexity remains $O(n log n)$ across average cases since the heap operations are logarithmic in nature. - -- **Worst Case: O(n log n)** - The worst case also results in $O(n log n)$, as heapifying and extracting the largest elements are bound by logarithmic comparisons. - -### Space Complexity: - -- **Space Complexity: O(1)** - Heap sort is an in-place algorithm, meaning it does not need additional memory to store subarrays or temporary structures, aside from the input array. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -// To heapify a subtree rooted with node i, n is the size of the heap -void heapify(int arr[], int n, int i) { - int largest = i; // Initialize largest as root - int left = 2 * i + 1; // left = 2*i + 1 - int right = 2 * i + 2; // right = 2*i + 2 - - // If left child is larger than root - if (left < n && arr[left] > arr[largest]) - largest = left; - - // If right child is larger than largest so far - if (right < n && arr[right] > arr[largest]) - largest = right; - - // If largest is not root - if (largest != i) { - swap(arr[i], arr[largest]); - - // Recursively heapify the affected sub-tree - heapify(arr, n, largest); - } -} - -// Main function to perform heap sort -void heapSort(int arr[], int n) { - // Build heap (rearrange array) - for (int i = n / 2 - 1; i >= 0; i--) - heapify(arr, n, i); - - // One by one extract an element from heap - for (int i = n - 1; i > 0; i--) { - // Move current root to end - swap(arr[0], arr[i]); - - // Call max heapify on the reduced heap - heapify(arr, i, 0); - } -} - -// A utility function to print an array -void printArray(int arr[], int n) { - for (int i = 0; i < n; i++) - cout << arr[i] << " "; - cout << endl; -} - -// Driver program to test the heap sort -int main() { - int arr[] = {12, 11, 13, 5, 6, 7}; - int n = sizeof(arr) / sizeof(arr[0]); - - heapSort(arr, n); - - cout << "Sorted array: \n"; - printArray(arr, n); -} -``` - -### Summary: - -Heap sort is an efficient, in-place sorting algorithm that works by building a max heap from the input array and then repeatedly extracting the largest element. Its consistent time complexity of O(n log n) makes it useful for many applications, although its non-stability and in-place nature make it less ideal for sorting data that requires maintaining the relative order of equal elements. diff --git a/docs/algorithms/sorting-algorithms/InsertionSort.md b/docs/algorithms/sorting-algorithms/InsertionSort.md deleted file mode 100644 index fe986c8f1..000000000 --- a/docs/algorithms/sorting-algorithms/InsertionSort.md +++ /dev/null @@ -1,127 +0,0 @@ ---- - -id: insertion-sort-algo -sidebar_position: 3 -title: Insertion Sort -sidebar_label: Insertion Sort - ---- - -### Definition: - -Insertion sort is a simple and efficient comparison-based sorting algorithm that builds the final sorted array one element at a time. It works similarly to how people sort playing cards in their hands. The algorithm starts with one element and repeatedly inserts the next element into its correct position within the already sorted portion of the array. - -### Characteristics: - -- **In-Place Sorting**: - - Insertion sort sorts the array in place, meaning it does not require extra memory for another array, making it an in-place algorithm. - -- **Stable**: - - It maintains the relative order of elements with equal values, making it a stable sorting algorithm. - -- **Efficient for Small Datasets**: - - Insertion sort is efficient for small datasets or nearly sorted datasets. It performs well in scenarios where the list is already partially sorted. - -- **Online Algorithm**: - - Insertion sort is an online algorithm, meaning it can sort a list as it receives elements one by one. - -### Time Complexity: - -- **Best Case: O(n)** - The best case occurs when the array is already sorted, so the algorithm only needs to iterate through the list once without making any swaps or shifts. - -- **Average Case: O(n²)** - On average, insertion sort must make n/2 comparisons and shifts for each element, leading to a quadratic time complexity. - -- **Worst Case: O(n²)** - The worst-case scenario occurs when the array is sorted in reverse order, requiring the algorithm to make the maximum number of comparisons and shifts. - -### Space Complexity: - -- **Space Complexity: O(1)** - Insertion sort is an in-place algorithm that requires a constant amount of extra memory for variables such as the current element being inserted. - -### C++ Implementation: - -**Iterative Approach** -```cpp -#include -using namespace std; - -void insertionSortIterative(int arr[], int size) { - for (int i = 1; i < size; i++) { - int key = arr[i]; - int j = i - 1; - - // Move elements of arr[0..i-1] that are greater than key - // to one position ahead of their current position - while (j >= 0 && arr[j] > key) { - arr[j + 1] = arr[j]; - j--; - } - arr[j + 1] = key; // Insert the key into its correct position - } -} - -int main() { - int arr[] = {12, 11, 13, 5, 6}; - int size = sizeof(arr) / sizeof(arr[0]); - - insertionSortIterative(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -**Recursive Approach** -```cpp -#include -using namespace std; - -void insertionSortRecursive(int arr[], int size) { - // Base case: If the array is of size 1, it's already sorted - if (size <= 1) { - return; - } - - // Sort the first n-1 elements - insertionSortRecursive(arr, size - 1); - - // Insert the last element at its correct position - int key = arr[size - 1]; - int j = size - 2; - - // Move elements of arr[0..size-2] that are greater than key - // to one position ahead of their current position - while (j >= 0 && arr[j] > key) { - arr[j + 1] = arr[j]; - j--; - } - arr[j + 1] = key; // Insert the key into its correct position -} - -int main() { - int arr[] = {12, 11, 13, 5, 6}; - int size = sizeof(arr) / sizeof(arr[0]); - - insertionSortRecursive(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Insertion sort is a simple yet efficient algorithm for small or nearly sorted datasets. It works by building a sorted array one element at a time, inserting each element into its correct position. Although it has a quadratic time complexity for average and worst-case scenarios, its linear time complexity in the best case makes it advantageous for sorting small datasets or datasets that are already nearly sorted. The iterative version is more common and easier to understand, while the recursive version provides a more elegant solution at the cost of slightly more overhead. diff --git a/docs/algorithms/sorting-algorithms/JumpSort.md b/docs/algorithms/sorting-algorithms/JumpSort.md deleted file mode 100644 index f7fa1dcfa..000000000 --- a/docs/algorithms/sorting-algorithms/JumpSort.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: jump-sort-algo -sidebar_position: 2 -title: Jump Sort -sidebar_label: Jump Sort ---- - -### Definition: - -Jump Sort is a simple comparison-based sorting algorithm that sorts elements by dividing the list into blocks and performing a linear search within these blocks. The algorithm jumps ahead by a fixed step size to reduce the number of comparisons, making it more efficient than naive sorting algorithms for larger datasets. - -### Characteristics: - -- **Block-wise Comparison**: - - Jump Sort divides the array into blocks of a fixed size (often the square root of the array length) and performs linear searches within these blocks. - -- **In-Place Sorting**: - - It operates directly on the input array without needing additional storage, making it an in-place sorting algorithm. - -- **Not Stable**: - - Jump Sort does not maintain the relative order of elements with equal values, which means it is not a stable sorting algorithm. - -- **Simplicity**: - - The algorithm is straightforward and easy to implement, although it may not be as efficient as other algorithms for large datasets. - -### Time Complexity: - -- **Best Case: O(n)** - In the best-case scenario, where the array is already sorted, Jump Sort can traverse the array with minimal comparisons. - -- **Average Case: O(n√n)** -On average, Jump Sort will perform a number of comparisons proportional to the number of elements times the square root of the number of elements. - -- **Worst Case: O(n√n)** -In the worst case, where the elements are in reverse order, Jump Sort will require a full traversal of the blocks, resulting in quadratic time complexity. - -### Space Complexity: - -- **Space Complexity: O(1)** -Jump Sort is an in-place algorithm, so it requires only a constant amount of extra memory, regardless of the input size. - -### C++ Implementation: - -**Jump Sort** -```cpp -#include -#include -using namespace std; - -void jumpSort(int arr[], int size) { - int step = sqrt(size); // Optimal block size - for (int i = 0; i < size; i += step) { - int end = min(i + step, size); - // Perform linear sort within the block - for (int j = i; j < end; j++) { - for (int k = j + 1; k < end; k++) { - if (arr[j] > arr[k]) { - // Swap arr[j] and arr[k] - swap(arr[j], arr[k]); - } - } - } - } -} - -int main() { - int arr[] = {64, 34, 25, 12, 22, 11, 90}; - int size = sizeof(arr) / sizeof(arr[0]); - - jumpSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` diff --git a/docs/algorithms/sorting-algorithms/MergeSort.md b/docs/algorithms/sorting-algorithms/MergeSort.md deleted file mode 100644 index e5bc730a7..000000000 --- a/docs/algorithms/sorting-algorithms/MergeSort.md +++ /dev/null @@ -1,199 +0,0 @@ ---- - -id: merge-sort-algo -sidebar_position: 4 -title: Merge Sort -sidebar_label: Merge Sort - ---- - -### Definition: - -Merge sort is a **divide-and-conquer** sorting algorithm that splits the array into smaller subarrays, sorts them, and then merges them back together in the correct order. It is a stable and comparison-based algorithm, which ensures that equal elements maintain their original relative positions. - -### Characteristics: - -- **Divide and Conquer**: - - Merge sort works by dividing the array into two halves, sorting each half, and then merging them back together in sorted order. This process is repeated recursively. - -- **Stable**: - - Merge sort is a stable sorting algorithm, meaning it maintains the relative order of equal elements. - -- **External Sorting**: - - Merge sort can be used to sort large datasets that do not fit into memory (external sorting) because it works well with data on disk or in streams. - -- **Requires Additional Space**: - - Unlike in-place sorting algorithms, merge sort requires additional memory to store the subarrays during the merging process. - -### Time Complexity: - -- **Best Case: O(n log n)** - Even in the best case (when the array is already sorted), merge sort divides the array into smaller parts and performs a merging process, resulting in a time complexity of O(n log n). - -- **Average Case: O(n log n)** - On average, merge sort consistently divides the array and performs merging, leading to a time complexity of O(n log n). - -- **Worst Case: O(n log n)** - In the worst case (reverse-sorted array), merge sort must still divide and merge the array in logarithmic time with n comparisons. - -### Space Complexity: - -- **Space Complexity: O(n)** - Merge sort requires additional space to store the temporary subarrays created during the merging process. This leads to a space complexity of O(n) due to the auxiliary arrays used for merging. - -### C++ Implementation: - -**Iterative (Bottom-Up) Approach** -```cpp -#include -using namespace std; - -// Merge function to merge two halves -void merge(int arr[], int left, int mid, int right) { - int n1 = mid - left + 1; - int n2 = right - mid; - - // Create temporary arrays - int L[n1], R[n2]; - - // Copy data to temporary arrays - for (int i = 0; i < n1; i++) - L[i] = arr[left + i]; - for (int j = 0; j < n2; j++) - R[j] = arr[mid + 1 + j]; - - // Merge the temporary arrays back into arr[left..right] - int i = 0, j = 0, k = left; - while (i < n1 && j < n2) { - if (L[i] <= R[j]) { - arr[k] = L[i]; - i++; - } else { - arr[k] = R[j]; - j++; - } - k++; - } - - // Copy the remaining elements of L[], if any - while (i < n1) { - arr[k] = L[i]; - i++; - k++; - } - - // Copy the remaining elements of R[], if any - while (j < n2) { - arr[k] = R[j]; - j++; - k++; - } -} - -// Iterative merge sort function -void mergeSortIterative(int arr[], int size) { - for (int curr_size = 1; curr_size <= size - 1; curr_size = 2 * curr_size) { - for (int left = 0; left < size - 1; left += 2 * curr_size) { - int mid = min(left + curr_size - 1, size - 1); - int right = min(left + 2 * curr_size - 1, size - 1); - merge(arr, left, mid, right); - } - } -} - -int main() { - int arr[] = {12, 11, 13, 5, 6, 7}; - int size = sizeof(arr) / sizeof(arr[0]); - - mergeSortIterative(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -**Recursive Approach** -```cpp -#include -using namespace std; - -// Merge function to merge two halves -void merge(int arr[], int left, int mid, int right) { - int n1 = mid - left + 1; - int n2 = right - mid; - - // Create temporary arrays - int L[n1], R[n2]; - - // Copy data to temporary arrays - for (int i = 0; i < n1; i++) - L[i] = arr[left + i]; - for (int j = 0; j < n2; j++) - R[j] = arr[mid + 1 + j]; - - // Merge the temporary arrays back into arr[left..right] - int i = 0, j = 0, k = left; - while (i < n1 && j < n2) { - if (L[i] <= R[j]) { - arr[k] = L[i]; - i++; - } else { - arr[k] = R[j]; - j++; - } - k++; - } - - // Copy the remaining elements of L[], if any - while (i < n1) { - arr[k] = L[i]; - i++; - k++; - } - - // Copy the remaining elements of R[], if any - while (j < n2) { - arr[k] = R[j]; - j++; - k++; - } -} - -// Recursive merge sort function -void mergeSortRecursive(int arr[], int left, int right) { - if (left < right) { - int mid = left + (right - left) / 2; - - // Sort first and second halves - mergeSortRecursive(arr, left, mid); - mergeSortRecursive(arr, mid + 1, right); - - // Merge the sorted halves - merge(arr, left, mid, right); - } -} - -int main() { - int arr[] = {12, 11, 13, 5, 6, 7}; - int size = sizeof(arr) / sizeof(arr[0]); - - mergeSortRecursive(arr, 0, size - 1); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Merge sort is an efficient and reliable sorting algorithm, particularly for large datasets. It works by recursively dividing the array into smaller subarrays and merging them in the correct order. Despite its additional space complexity, its consistent time complexity of O(n log n) makes it a popular choice for sorting algorithms. The recursive approach is more intuitive, but the iterative version can be useful in cases where recursion depth could be a concern. diff --git a/docs/algorithms/sorting-algorithms/Odd-Even-Sort.md b/docs/algorithms/sorting-algorithms/Odd-Even-Sort.md deleted file mode 100644 index ba3f950c2..000000000 --- a/docs/algorithms/sorting-algorithms/Odd-Even-Sort.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: odd-even-sort-algo -sidebar_position: 19 -title: Odd-Even Sort -sidebar_label: Odd-Even Sort ---- - -### Definition: - -Odd-Even Sort is a simple parallel sorting algorithm that works by repeatedly performing two phases: an odd phase and an even phase. It compares and swaps adjacent elements in two passes, which gradually sorts the array. It is mainly used in parallel computing environments due to its ability to be implemented efficiently across multiple processors. - -### Characteristics: - -- **Two Phases**: - The algorithm alternates between an odd phase (comparing elements at odd indexes with their next even index) and an even phase (comparing elements at even indexes with their next odd index). - -- **In-Place**: - The algorithm sorts the array without requiring any additional storage, modifying the input array directly. - -- **Not Stable**: - Odd-Even Sort is not stable, meaning that the relative order of equal elements may not be preserved. - -### Time Complexity: - -- **Best Case: O(n)** - When the array is already sorted, the algorithm only requires one pass. - -- **Average Case: O(n²)** -The average time complexity is quadratic, similar to other simple sorting algorithms. - -- **Worst Case: O(n²)** -The worst-case scenario occurs when the array is in reverse order. - -### Space Complexity: - -- **Space Complexity: O(1)** -The algorithm operates in constant space, only using a few variables for swapping. - -### Java Implementation: - -```java -public class OddEvenSort { - - // Method to perform Odd-Even Sort - public static void oddEvenSort(int[] arr) { - boolean isSorted = false; - int n = arr.length; - - while (!isSorted) { - isSorted = true; - - // Odd phase - for (int i = 1; i < n - 1; i += 2) { - if (arr[i] > arr[i + 1]) { - swap(arr, i, i + 1); - isSorted = false; - } - } - - // Even phase - for (int i = 0; i < n - 1; i += 2) { - if (arr[i] > arr[i + 1]) { - swap(arr, i, i + 1); - isSorted = false; - } - } - } - } - - // Helper method to swap two elements - private static void swap(int[] arr, int i, int j) { - int temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - - public static void main(String[] args) { - int[] arr = {5, 3, 1, 4, 2}; - oddEvenSort(arr); - System.out.println("Sorted array:"); - for (int num : arr) { - System.out.print(num + " "); - } - } -} -``` - -### Summary: -Odd-Even Sort is a straightforward sorting algorithm that alternates between odd and even phases to sort an array. While it can be implemented efficiently in parallel computing environments, its average and worst-case time complexities of O(n2) make it less efficient compared to more advanced algorithms like Quick Sort or Merge Sort. diff --git a/docs/algorithms/sorting-algorithms/OddEvenSort.md b/docs/algorithms/sorting-algorithms/OddEvenSort.md deleted file mode 100644 index 4309a9b45..000000000 --- a/docs/algorithms/sorting-algorithms/OddEvenSort.md +++ /dev/null @@ -1,99 +0,0 @@ - - - - -### Definition: - -Odd-Even Sort is a simple comparison-based sorting algorithm, also known as Brick Sort. It works by repeatedly comparing all odd-indexed elements with their next even-indexed neighbor and swapping them if they are out of order. Then, it performs the same comparison for even-indexed elements and continues alternating between these two phases until the list is sorted. - -### Characteristics: - -- **Parallel Comparison**: - - Odd-Even Sort alternates between comparing odd-even indexed pairs and even-odd indexed pairs, progressively sorting the array. - -- **In-Place Sorting**: - - Like Shell Sort, Odd-Even Sort is an in-place algorithm, meaning it requires no extra memory aside from the input array itself. - -- **Stable**: - - Odd-Even Sort is a stable sorting algorithm, as it only swaps adjacent elements, preserving the relative order of equal elements. - -- **Simple Implementation**: - - Odd-Even Sort is easy to implement and can be parallelized since adjacent element comparisons are independent. - -### Time Complexity: - -- **Best Case: O(n)** - If the array is already sorted, Odd-Even Sort only requires one pass through the array. - -- **Average Case: O(n²)** - In the average case, Odd-Even Sort takes quadratic time, as it may require multiple passes over the array. - -- **Worst Case: O(n²)** - In the worst case, such as a reverse-sorted array, Odd-Even Sort also degrades to O(n²). - -### Space Complexity: - -- **Space Complexity: O(1)** - Like Shell Sort, Odd-Even Sort is an in-place sorting algorithm, requiring constant additional memory. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -// Function to perform odd-even sort -void oddEvenSort(int arr[], int size) { - bool sorted = false; // Initially array is unsorted - - while (!sorted) { - sorted = true; - - // Perform Odd phase - for (int i = 1; i <= size - 2; i += 2) { - if (arr[i] > arr[i + 1]) { - swap(arr[i], arr[i + 1]); - sorted = false; - } - } - - // Perform Even phase - for (int i = 0; i <= size - 2; i += 2) { - if (arr[i] > arr[i + 1]) { - swap(arr[i], arr[i + 1]); - sorted = false; - } - } - } -} - -int main() { - int arr[] = {34, 2, 10, -9}; - int size = sizeof(arr) / sizeof(arr[0]); - - oddEvenSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Explanation: - -1. **Odd Phase**: - - During the odd phase, elements at odd indices (1, 3, 5, etc.) are compared with their immediate even neighbors (2, 4, 6, etc.). If an odd-indexed element is larger than its even neighbor, they are swapped. - -2. **Even Phase**: - - During the even phase, elements at even indices (0, 2, 4, etc.) are compared with their immediate odd neighbors (1, 3, 5, etc.). Similarly, if an even-indexed element is larger, they are swapped. - -3. **Repetition**: - - The process alternates between odd and even phases until no swaps are made during a complete pass, which means the array is sorted. - -### Summary: - -Odd-Even Sort is a simple comparison-based algorithm that repeatedly compares and swaps adjacent elements based on their odd or even positions. Despite its simplicity, it is not particularly efficient for large datasets, as its average and worst-case time complexity is O(n²). However, its simplicity and parallelization potential make it an attractive choice for certain applications where simpler algorithms suffice or where parallel computation can be leveraged. \ No newline at end of file diff --git a/docs/algorithms/sorting-algorithms/Pancake-sorting-algorithm.md b/docs/algorithms/sorting-algorithms/Pancake-sorting-algorithm.md deleted file mode 100644 index ddf3dc8db..000000000 --- a/docs/algorithms/sorting-algorithms/Pancake-sorting-algorithm.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -id: pancake-sorting-algorithm -title: Pancake Sorting Algorithm -sidebar_label: Pancake Sorting Algorithm -sidebar_position: 12 -description: "Pancake sorting is a sorting algorithm in which the only allowed operation is to reverse the elements of a prefix of the array." -tags: [Sorting Algorithms, pancake-sorting-algorithm, Algorithm] ---- - -# Pancake Sorting Algorithm - -## Overview -Pancake sorting is a sorting algorithm in which the only allowed operation is to reverse the elements of a prefix of the array. The goal is to sort the array using a minimal number of prefix reversals. This problem is a classic example of a **sorting** algorithm that limits the available operations. - -## Introduction -In **Pancake Sorting**, we are given a stack of pancakes of varying sizes and we want to sort them in order of size, with the largest pancake at the bottom and the smallest pancake on top. However, the only allowed operation is a **flip**, which reverses the order of the top `k` pancakes in the stack. The algorithm aims to sort the pancakes using the fewest number of flips. - -## Characteristics of Pancake Sorting Algorithm -- **Flip-Based Sorting**: The algorithm sorts an array by repeatedly flipping prefixes of the array. -- **In-Place Sorting**: Pancake sort is performed in-place, meaning it uses a constant amount of extra space. -- **Non-Comparison-Based**: Unlike comparison-based algorithms like Quick Sort or Merge Sort, pancake sorting only allows flipping operations. - -## How Pancake Sorting Works -1. **Find the Largest Pancake**: In each iteration, find the largest pancake that is not yet in its correct position. -2. **Flip the Largest Pancake to the Top**: Perform a flip to move the largest pancake to the top of the stack. -3. **Flip the Largest Pancake to Its Correct Position**: Perform another flip to move the largest pancake to its correct position at the bottom of the unsorted section of the stack. -4. **Repeat**: Repeat the process for the remaining unsorted pancakes. - -## Step-by-Step Execution of Pancake Algorithm - -```mermaid -graph TD - P1(Pancake Stack: 3, 6, 2, 5, 4, 1) --> P2(Flip first 5 elements) - P2 --> P3(Pancake Stack: 5, 2, 6, 3, 4, 1) - P3 --> P4(Flip first 3 elements) - P4 --> P5(Pancake Stack: 6, 2, 5, 3, 4, 1) - P5 --> P6(Flip first 6 elements) - P6 --> P7(Pancake Stack: 1, 4, 3, 5, 2, 6) - P7 --> P8(Continue process...) -``` - -## Algorithm Steps -1. **Find the largest unsorted pancake** in the stack. -2. **Flip it to the top** of the stack. -3. **Flip it again** to place it in its correct position. -4. Repeat the process for the remaining unsorted pancakes until all are sorted. - -## Time Complexity -- **Time Complexity:** O(n²) where `n` is the number of pancakes. This is because: -- Finding the largest pancake takes linear time (O(n)). -- Flipping the stack also takes linear time. -- These operations are repeated for each unsorted pancake. - -- **Space Complexity:** O(1) as the algorithm works in-place without requiring additional memory. - -## Applications -- **Theoretical Significance:** Pancake sorting is primarily of theoretical interest and is not used in practical applications due to its inefficiency compared to other sorting algorithms. - -- **Robotic Manipulation:** Pancake sorting is an example of constrained sorting, which is related to problems in robotic manipulation and sorting, where only specific operations are allowed. - -- **Problem Solving:** It serves as an educational example, demonstrating how to approach problems with limited operations, making it useful in algorithmic teaching and learning. - -## Algorithm Steps -1. **For each unsorted portion of the array**, find the index of the largest element. -2. **If the largest element is not at the top**, flip the subarray to move it to the top. -3. **Flip again** to move the largest element to its correct position. -4. Repeat for the rest of the array until it is fully sorted. - -## Advantages of Pancake Sorting -- **In-Place:** Pancake sorting requires no extra space for sorting. -- **Simple Operations:** The algorithm only uses a single operation (flip), making it straightforward to understand and implement. - -## Limitations -- **Inefficient:** Pancake sorting has a time complexity of O(n²), making it unsuitable for large datasets. -- **Theoretical Use:** It is primarily used as a theoretical example and rarely applied in real-world sorting tasks. - -## Conclusion -Pancake Sorting is an interesting and educational sorting algorithm, though it is inefficient compared to practical algorithms like Quick Sort or Merge Sort. It serves as a useful theoretical model for constrained sorting problems, such as in robotic manipulation or problem-solving scenarios where only specific operations are allowed. - - - - - diff --git a/docs/algorithms/sorting-algorithms/Pigeonhole.md b/docs/algorithms/sorting-algorithms/Pigeonhole.md deleted file mode 100644 index 81ae3321e..000000000 --- a/docs/algorithms/sorting-algorithms/Pigeonhole.md +++ /dev/null @@ -1,91 +0,0 @@ ---- - -id: pigeonhole-sort-algo -sidebar_position: 14 -title: Pigeonhole Sort -sidebar_label: Pigeonhole Sort - ---- - -### Definition: - -Pigeonhole Sort is a non-comparison sorting algorithm based on the pigeonhole principle. It sorts an array of n elements where the range of input values ( k ) is not significantly greater than n. The algorithm distributes the elements into "pigeonholes" (or buckets) according to their value and then collects them back into a sorted order. - -### Characteristics: - -- **Pigeonhole Principle**: - - Pigeonhole sort works on the idea that if n items are put into m containers, with n>m, at least one container must contain more than one item. This principle is used to allocate input values into corresponding pigeonholes. - -- **Bucket Distribution**: - - The algorithm creates an array of pigeonholes to store the input values, where the index corresponds to the value of the elements being sorted. - -- **In-Place**: - - While pigeonhole sort requires additional space to hold the pigeonholes, the sorting operation itself can be performed in-place. - -- **Stable**: - - Pigeonhole sort can be implemented in a stable manner, meaning it preserves the relative order of equal elements. - -### Time Complexity: - -- **Best Case: O(n + k)** - In the best case, when the input values are well-distributed, the algorithm performs efficiently. - -- **Average Case: O(n + k)** -The average-case complexity remains linear with respect to the number of elements and the range of the input values. - -- **Worst Case: O(n + k)** -The worst-case scenario still yields linear time complexity as it processes all values in the range. - -### Space Complexity: - -- **Space Complexity: O(k)** -The space complexity is linear relative to the range of input values, which may lead to inefficiency when the range is much larger than \( n \). - -### Java Implementation: - -```java -import java.util.Arrays; - -public class PigeonholeSort { - public static void pigeonholeSort(int[] arr) { - int min = arr[0]; - int max = arr[0]; - - // Find the range (min and max values) - for (int i = 1; i < arr.length; i++) { - if (arr[i] < min) { - min = arr[i]; - } - if (arr[i] > max) { - max = arr[i]; - } - } - - int range = max - min + 1; // Size of pigeonholes - int[] pigeonholes = new int[range]; - - // Populate the pigeonholes - for (int i = 0; i < arr.length; i++) { - pigeonholes[arr[i] - min]++; - } - - // Collect the sorted elements - int index = 0; - for (int i = 0; i < range; i++) { - while (pigeonholes[i] > 0) { - arr[index++] = i + min; - pigeonholes[i]--; - } - } - } - - public static void main(String[] args) { - int[] arr = {8, 3, 2, 7, 4, 6, 1, 5}; - pigeonholeSort(arr); - System.out.println("Sorted array: " + Arrays.toString(arr)); - } -} -``` - -### Summary: -Pigeonhole Sort is an efficient sorting algorithm for datasets with a limited range of values. With a time complexity of 𝑂(𝑛+𝑘), it performs well when the range of input values is not excessively large compared to the number of elements. However, it is not widely used in practical applications due to its linear space requirement when the range is much larger than 𝑛. diff --git a/docs/algorithms/sorting-algorithms/QuickSort.md b/docs/algorithms/sorting-algorithms/QuickSort.md deleted file mode 100644 index 193e35d5c..000000000 --- a/docs/algorithms/sorting-algorithms/QuickSort.md +++ /dev/null @@ -1,161 +0,0 @@ ---- - -id: quick-sort-algo -sidebar_position: 5 -title: Quick Sort -sidebar_label: Quick Sort - ---- - -### Definition: - -Quick sort is a **divide-and-conquer** sorting algorithm that works by selecting a 'pivot' element from the array and partitioning the other elements into two subarrays, according to whether they are less than or greater than the pivot. The subarrays are then recursively sorted. This process of partitioning and sorting leads to a highly efficient sorting algorithm. - -### Characteristics: - -- **Divide and Conquer**: - - Quick sort partitions the array into smaller subarrays and sorts them independently before merging the results back together. - -- **In-Place Sorting**: - - It sorts the array in place and typically requires little additional memory, only for recursive calls. - -- **Unstable**: - - Quick sort is an unstable algorithm, meaning it does not guarantee that the relative order of equal elements will be maintained. - -- **Efficient for Large Datasets**: - - Quick sort is one of the fastest sorting algorithms in practice, especially for large datasets, and has excellent cache performance. - -### Time Complexity: - -- **Best Case: O(n log n)** - In the best case, the pivot divides the array into two nearly equal subarrays, leading to a logarithmic number of comparisons across each recursive call. - -- **Average Case: O(n log n)** - On average, quick sort partitions the array into balanced subarrays, leading to an O(n log n) time complexity. - -- **Worst Case: O(n²)** - The worst-case scenario occurs when the pivot chosen is consistently the smallest or largest element, leading to unbalanced partitions and quadratic time complexity. This can be mitigated by using strategies like randomized pivots or choosing the median of three elements as the pivot. - -### Space Complexity: - -- **Space Complexity: O(log n)** - Quick sort requires O(log n) space for recursive calls when the partitioning is balanced. In the worst case (highly unbalanced partitioning), it requires O(n) space for recursion. - -### C++ Implementation: - -**Iterative Approach** -```cpp -#include -#include -using namespace std; - -// Partition function to place the pivot element in the correct position -int partition(int arr[], int low, int high) { - int pivot = arr[high]; // Pivot is taken as the last element - int i = (low - 1); // Index of the smaller element - - for (int j = low; j < high; j++) { - if (arr[j] <= pivot) { - i++; // Increment index of smaller element - swap(arr[i], arr[j]); // Swap current element with the smaller element - } - } - swap(arr[i + 1], arr[high]); // Place the pivot element in the correct position - return (i + 1); -} - -// Iterative quick sort function -void quickSortIterative(int arr[], int low, int high) { - stack s; - s.push(low); - s.push(high); - - // Keep popping elements until stack is empty - while (!s.empty()) { - high = s.top(); - s.pop(); - low = s.top(); - s.pop(); - - int p = partition(arr, low, high); - - // If there are elements on the left of the pivot, push them onto the stack - if (p - 1 > low) { - s.push(low); - s.push(p - 1); - } - - // If there are elements on the right of the pivot, push them onto the stack - if (p + 1 < high) { - s.push(p + 1); - s.push(high); - } - } -} - -int main() { - int arr[] = {10, 7, 8, 9, 1, 5}; - int size = sizeof(arr) / sizeof(arr[0]); - - quickSortIterative(arr, 0, size - 1); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -**Recursive Approach** -```cpp -#include -using namespace std; - -// Partition function to place the pivot element in the correct position -int partition(int arr[], int low, int high) { - int pivot = arr[high]; // Pivot is taken as the last element - int i = (low - 1); // Index of the smaller element - - for (int j = low; j < high; j++) { - if (arr[j] <= pivot) { - i++; // Increment index of smaller element - swap(arr[i], arr[j]); // Swap current element with the smaller element - } - } - swap(arr[i + 1], arr[high]); // Place the pivot element in the correct position - return (i + 1); -} - -// Recursive quick sort function -void quickSortRecursive(int arr[], int low, int high) { - if (low < high) { - int pi = partition(arr, low, high); - - // Recursively sort elements before and after partition - quickSortRecursive(arr, low, pi - 1); - quickSortRecursive(arr, pi + 1, high); - } -} - -int main() { - int arr[] = {10, 7, 8, 9, 1, 5}; - int size = sizeof(arr) / sizeof(arr[0]); - - quickSortRecursive(arr, 0, size - 1); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Quick sort is a highly efficient and widely used sorting algorithm that works well for large datasets. It employs the divide-and-conquer approach, partitioning the array around a pivot and sorting the subarrays recursively. Although its worst-case time complexity is O(n²), this can often be avoided by choosing an appropriate pivot (like the median of three). In practice, quick sort is often faster than other O(n log n) algorithms like merge sort due to its in-place sorting nature and better cache performance. diff --git a/docs/algorithms/sorting-algorithms/RadixSort.md b/docs/algorithms/sorting-algorithms/RadixSort.md deleted file mode 100644 index 8e432fa45..000000000 --- a/docs/algorithms/sorting-algorithms/RadixSort.md +++ /dev/null @@ -1,120 +0,0 @@ ---- - -id: radix-sort-algo -sidebar_position: 7 -title: Radix Sort -sidebar_label: Radix Sort - ---- - - -### Definition: - -Radix sort is a non-comparative sorting algorithm that sorts numbers by processing individual digits. It processes each digit of the numbers one at a time, starting from the least significant digit to the most significant digit (LSD variant) or vice versa (MSD variant), using a stable subroutine such as counting sort. - -### Characteristics: - -- **Non-Comparative Sorting**: - - Unlike comparison-based sorting algorithms, radix sort does not compare elements directly. Instead, it processes each digit of the elements one by one. - -- **Stable**: - - Radix sort preserves the relative order of elements with equal keys, making it a stable sorting algorithm, especially when used with stable intermediate sorting algorithms like counting sort. - -- **Efficient for Large Datasets**: - - Radix sort can outperform comparison-based sorting algorithms (like quicksort or merge sort) on large datasets, particularly when the size of the input numbers (keys) is much smaller than the number of elements in the dataset. - -- **In-Place Sorting (depending on implementation)**: - - Depending on the subroutine used (like counting sort), radix sort can be implemented as an in-place algorithm, though some versions may require extra space. - -### Time Complexity: - -- **Best Case: O(nk)** - When the input elements are uniformly distributed across a small range, radix sort runs in linear time, where `n` is the number of elements, and `k` is the number of digits in the largest number. - -- **Average Case: O(nk)** - Radix sort performs consistently well, especially when the number of digits (k) is small compared to the number of elements (n). - -- **Worst Case: O(nk)** - The worst-case scenario is also O(nk), making radix sort more predictable in performance compared to algorithms with O(n²) worst cases. - -### Space Complexity: - -- **Space Complexity: O(n + k)** - Radix sort requires additional space for the counting array or buckets used during intermediate sorting, where `n` is the number of elements, and `k` is the number of digits. - -### C++ Implementation: - -**LSD (Least Significant Digit) Radix Sort Using Counting Sort** - -```cpp -#include -using namespace std; - -// A utility function to get the maximum value in the array -int getMax(int arr[], int size) { - int max = arr[0]; - for (int i = 1; i < size; i++) { - if (arr[i] > max) { - max = arr[i]; - } - } - return max; -} - -// A function to do counting sort of arr[] according to the digit represented by exp -void countingSort(int arr[], int size, int exp) { - int output[size]; // Output array to store sorted numbers - int count[10] = {0}; // There are 10 possible digits (0 to 9) - - // Count the occurrences of each digit - for (int i = 0; i < size; i++) { - count[(arr[i] / exp) % 10]++; - } - - // Change count[i] so that it contains the actual position of this digit in output[] - for (int i = 1; i < 10; i++) { - count[i] += count[i - 1]; - } - - // Build the output array - for (int i = size - 1; i >= 0; i--) { - output[count[(arr[i] / exp) % 10] - 1] = arr[i]; - count[(arr[i] / exp) % 10]--; - } - - // Copy the output array to arr[], so that arr[] now contains the sorted numbers - for (int i = 0; i < size; i++) { - arr[i] = output[i]; - } -} - -// The main function to implement radix sort -void radixSort(int arr[], int size) { - // Find the maximum number to know the number of digits - int max = getMax(arr, size); - - // Do counting sort for every digit. Note that exp is 10^i where i is the current digit position - for (int exp = 1; max / exp > 0; exp *= 10) { - countingSort(arr, size, exp); - } -} - -int main() { - int arr[] = {170, 45, 75, 90, 802, 24, 2, 66}; - int size = sizeof(arr) / sizeof(arr[0]); - - radixSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Radix sort is an efficient algorithm for sorting integers and other data types with a fixed range of digits. Unlike comparison-based algorithms, it processes the digits of the numbers in multiple passes, making it suitable for large datasets where elements have many digits. Its predictable time complexity, especially in cases where the number of digits is much smaller than the number of elements, makes it an attractive option in such scenarios. diff --git a/docs/algorithms/sorting-algorithms/SelectionSort.md b/docs/algorithms/sorting-algorithms/SelectionSort.md deleted file mode 100644 index 51879adaa..000000000 --- a/docs/algorithms/sorting-algorithms/SelectionSort.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: selection-sort-algo -sidebar_position: 2 -title: Selection Sort -sidebar_label: Selection Sort -description: Selection sort is a simple comparison-based sorting algorithm that repeatedly selects the smallest (or largest) element from the unsorted portion of the array and swaps it with the first unsorted element. It works by dividing the array into a sorted and an unsorted region and systematically reducing the size of the unsorted region. -tags: [Sorting Algorithms, Selection Sort] ---- - -### Definition: - -Selection sort is a simple comparison-based sorting algorithm that repeatedly selects the smallest (or largest) element from the unsorted portion of the array and swaps it with the first unsorted element. It works by dividing the array into a sorted and an unsorted region and systematically reducing the size of the unsorted region. - -### Characteristics: - -- **In-Place Sorting**: - - Selection sort operates directly on the input array and does not require additional storage, making it an in-place sorting algorithm. - -- **Not Stable**: - - Selection sort is not a stable sorting algorithm because equal elements can be swapped, potentially changing their relative order. - -- **Selection Process**: - - In each pass, the algorithm selects the smallest element from the unsorted part of the array and places it in the correct position by swapping it with the first element of the unsorted part. - -- **Inefficient for Large Datasets**: - - Although the algorithm is simple, it is not efficient for large datasets as it requires many comparisons and swaps. - -### Time Complexity: - -- **Best Case: O(n²)** - Even in the best case where the array is already sorted, the algorithm must make n²/2 comparisons because it systematically searches for the smallest element in the unsorted portion. - -- **Average Case: O(n²)** - On average, the algorithm must make n²/2 comparisons and n swaps. This quadratic time complexity makes selection sort inefficient for large datasets. - -- **Worst Case: O(n²)** - In the worst-case scenario (reverse sorted array), selection sort must still make the same number of comparisons as in the average case. - -### Space Complexity: - -- **Space Complexity: O(1)** - Selection sort is an in-place algorithm and requires only a constant amount of extra memory for swapping elements. - -### C++ Implementation: - -**Iterative Approach** -```cpp -#include -using namespace std; - -void selectionSortIterative(int arr[], int size) { - for (int i = 0; i < size - 1; i++) { - int minIndex = i; // Assume the current element is the minimum - - // Find the minimum element in the remaining unsorted array - for (int j = i + 1; j < size; j++) { - if (arr[j] < arr[minIndex]) { - minIndex = j; // Update the index of the minimum element - } - } - - // Swap the found minimum element with the first unsorted element - if (minIndex != i) { - int temp = arr[i]; - arr[i] = arr[minIndex]; - arr[minIndex] = temp; - } - } -} - -int main() { - int arr[] = {64, 25, 12, 22, 11}; - int size = sizeof(arr) / sizeof(arr[0]); - - selectionSortIterative(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -**Recursive Approach** -```cpp -#include -using namespace std; - -void selectionSortRecursive(int arr[], int size, int index = 0) { - // Base case: If the array is completely sorted - if (index == size - 1) { - return; - } - - int minIndex = index; - - // Find the minimum element in the remaining unsorted array - for (int j = index + 1; j < size; j++) { - if (arr[j] < arr[minIndex]) { - minIndex = j; - } - } - - // Swap the found minimum element with the first unsorted element - if (minIndex != index) { - int temp = arr[index]; - arr[index] = arr[minIndex]; - arr[minIndex] = temp; - } - - // Recursively sort the rest of the array - selectionSortRecursive(arr, size, index + 1); -} - -int main() { - int arr[] = {64, 25, 12, 22, 11}; - int size = sizeof(arr) / sizeof(arr[0]); - - selectionSortRecursive(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Summary: - -Selection sort is a simple, easy-to-understand algorithm that can be useful for small datasets or when memory space is limited. However, its quadratic time complexity makes it inefficient for large datasets. The algorithm iteratively selects the minimum element from the unsorted portion of the array and swaps it into place. The iterative and recursive implementations both perform the same function, with the recursive version offering a cleaner, although slightly more complex, approach. diff --git a/docs/algorithms/sorting-algorithms/ShellSort.md b/docs/algorithms/sorting-algorithms/ShellSort.md deleted file mode 100644 index 702d7fb2d..000000000 --- a/docs/algorithms/sorting-algorithms/ShellSort.md +++ /dev/null @@ -1,102 +0,0 @@ ---- - -id: shell-sort-algo -sidebar_position: 11 -title: Shell Sort -sidebar_label: Shell Sort - ---- - -### Definition: - -Shell sort is an extension of insertion sort that allows the exchange of far-apart elements to move elements towards their correct position faster. It starts by sorting pairs of elements far apart, then progressively reduces the gap between elements to be compared. This makes Shell sort more efficient than insertion sort, especially for larger datasets. - -### Characteristics: - -- **Gap-based Sorting**: - - The core idea of Shell sort is to first sort elements that are far apart, using a sequence of gaps that reduces until a final insertion sort is performed when the gap is 1. - -- **In-Place Sorting**: - - Shell sort is an in-place algorithm, which means it requires no extra memory besides the input array itself. - -- **Unstable**: - - Shell sort is an unstable sorting algorithm because it can swap elements that are far apart, which may disrupt the relative order of equal elements. - -- **Gap Sequence**: - - The choice of gap sequence is crucial to the performance of Shell sort. Common sequences include the original gap sequence (n/2, n/4, ..., 1), Hibbard's sequence, and Sedgewick's sequence, among others. - -### Time Complexity: - -- **Best Case: O(n log n)** - With an optimal gap sequence, Shell sort can approach O(n log n) in the best case. - -- **Average Case: O(n log² n)** - The average-case complexity of Shell sort is better than that of many simple quadratic sorting algorithms like insertion sort or bubble sort, but it depends heavily on the gap sequence. - -- **Worst Case: O(n²)** - In the worst case, with poor gap choices, Shell sort can degrade to quadratic time complexity. - -### Space Complexity: - -- **Space Complexity: O(1)** - Shell sort is an in-place sorting algorithm, meaning it requires a constant amount of extra memory. - -### C++ Implementation: - -```cpp -#include -using namespace std; - -// Function to perform shell sort -void shellSort(int arr[], int size) { - // Start with a large gap, then reduce the gap - for (int gap = size / 2; gap > 0; gap /= 2) { - // Perform a gapped insertion sort for this gap size - for (int i = gap; i < size; i++) { - int temp = arr[i]; - int j; - - // Shift earlier gap-sorted elements up until the correct location for arr[i] is found - for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) { - arr[j] = arr[j - gap]; - } - - // Put temp (the original arr[i]) in its correct location - arr[j] = temp; - } - } -} - -int main() { - int arr[] = {12, 34, 54, 2, 3}; - int size = sizeof(arr) / sizeof(arr[0]); - - shellSort(arr, size); - - cout << "Sorted array: \n"; - for (int i = 0; i < size; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Explanation: - -1. **Gap Selection**: - - Shell sort begins by choosing a large gap (half the size of the array) and performs a "gapped" insertion sort, comparing and swapping elements far apart. The gap is progressively reduced, and finally, when the gap becomes 1, the array is fully sorted using a regular insertion sort. - -2. **Performance Improvement**: - - Sorting with larger gaps allows elements to move towards their correct position faster, reducing the number of swaps needed during the final insertion sort pass. This significantly improves performance compared to a standard insertion sort. - -### Gap Sequences: - -- **Shell's Original Sequence**: The gap is initially set to half the array size and is halved each time (n/2, n/4, ..., 1). -- **Hibbard's Sequence**: Uses gaps of the form (1, 3, 7, 15, 31, ..., 2ⁿ−1), which provides better performance in practice. -- **Sedgewick's Sequence**: More complex, but provides excellent performance for larger arrays. - -### Summary: - -Shell sort is a highly efficient general-purpose comparison-based sorting algorithm that improves upon insertion sort by first comparing elements far apart. By reducing the gap over iterations, it minimizes the number of comparisons and swaps required. With its average-case time complexity of O(n log² n), Shell sort performs significantly better than simple quadratic algorithms like bubble or insertion sort, making it suitable for moderate-sized datasets. However, the performance depends heavily on the choice of the gap sequence. diff --git a/docs/algorithms/sorting-algorithms/StoogeSort.md b/docs/algorithms/sorting-algorithms/StoogeSort.md deleted file mode 100644 index 9f970b6d3..000000000 --- a/docs/algorithms/sorting-algorithms/StoogeSort.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -id: stooge-sort-algo -sidebar_position: 16 -title: Stooge Sort -sidebar_label: Stooge Sort -description: A detailed guide on the Stooge Sort algorithm with Python implementation examples. -tags: [stooge sort, algorithms, sorting algorithms] ---- - -### Definition: - -Stooge sort is a **recursive sorting algorithm** that operates by comparing the first and last elements of a sequence and swapping them if necessary. It then recursively applies the same procedure to overlapping subarrays. While Stooge sort is notable for its academic interest, it is inefficient for practical use due to its high time complexity. - -### Characteristics: - -- **Recursive Algorithm**: - - Stooge sort uses a recursive approach to sort elements. It first swaps elements if needed, then recursively sorts the first two-thirds and the last two-thirds of the array. - -- **Inefficient Time Complexity**: - - Despite its simplicity, Stooge sort is inefficient with a time complexity of $O(n^{2.7095})$, making it one of the least efficient sorting algorithms. - -- **Rarely Used in Practice**: - - Due to its poor performance, Stooge sort is rarely used in real-world applications, but it remains a useful algorithm for theoretical study. - -### Time Complexity: - -- **Best Case: $O(n^{2.7095})$ - Even in the best case, Stooge sort requires recursive calls that make its performance slower than more efficient algorithms like merge sort or quicksort. - -- **Average Case: $O(n^{2.7095})$ - The time complexity remains $O(n^{2.7095})$ across average cases due to the recursion. - -- **Worst Case: $O(n^{2.7095})$ - Stooge sort's worst-case performance is similar to its average and best-case complexities. - -### Space Complexity: - -- **Space Complexity: $O(n)$ - The space complexity of Stooge sort is linear due to the recursive calls storing subarrays on the stack. - -### Python Implementation: - -```python -def stooge_sort(arr, l, h): - if l >= h: - return - - # If first element is smaller than the last, swap them - if arr[l] > arr[h]: - arr[l], arr[h] = arr[h], arr[l] - - # If there are more than 2 elements in the array - if h - l + 1 > 2: - t = (h - l + 1) // 3 - stooge_sort(arr, l, h - t) # Sort the first 2/3 - stooge_sort(arr, l + t, h) # Sort the last 2/3 - stooge_sort(arr, l, h - t) # Again sort the first 2/3 - -# Example usage: -arr = [2, 4, 5, 3, 1] -stooge_sort(arr, 0, len(arr) - 1) -print("Sorted array:", arr) -``` - -### Summary: - -Stooge sort is an inefficient **recursive sorting algorithm** with a high time complexity of $O(n^{2.7095})$, making it impractical for real-world use. While it has educational value, it is rarely used in practice, especially when compared to more efficient algorithms like quicksort or merge sort. diff --git a/docs/algorithms/sorting-algorithms/TimSort.md b/docs/algorithms/sorting-algorithms/TimSort.md deleted file mode 100644 index f40ce2f57..000000000 --- a/docs/algorithms/sorting-algorithms/TimSort.md +++ /dev/null @@ -1,158 +0,0 @@ ---- - -id: tim-sort-algo -sidebar_position: 11 -title: Tim Sort -sidebar_label: Tim Sort - ---- - -### Definition: - -Tim Sort is a hybrid, stable sorting algorithm derived from merge sort and insertion sort. It is designed to perform well on real-world data, which often contains certain order. The algorithm splits the array into small pieces (called "runs"), sorts each run using insertion sort, and then merges the runs using a merge sort technique. It is the default sorting algorithm in Python and Java's standard libraries. - -### Characteristics: - -- **Hybrid Sorting**: - - Combines the simplicity and efficiency of insertion sort for small datasets and the power of merge sort for larger datasets. - -- **Adaptive**: - - Tim Sort takes advantage of existing order in the dataset, making it highly efficient for partially sorted data. - -- **Stable**: - - Tim Sort preserves the relative order of elements with equal values, making it a stable sorting algorithm. - -- **Efficient for Real-World Data**: - - Designed to work well on real-world data sets, which often contain sequences of ordered elements, and thus performs better than many traditional algorithms in practice. - -### Time Complexity: - -- **Best Case: O(n)** - In the best-case scenario, if the array is already nearly sorted, Tim Sort can achieve linear time complexity by taking advantage of the order in the data. - -- **Average Case: O(n log n)** - On average, Tim Sort performs merges in logarithmic time while the insertion sort handles small runs, resulting in O(n log n) time complexity. - -- **Worst Case: O(n log n)** - Even in the worst case, where the array is entirely unsorted, Tim Sort maintains an O(n log n) time complexity due to its use of merge sort for larger portions of the data. - -### Space Complexity: - -- **Space Complexity: O(n)** - Tim Sort requires O(n) additional space for the merging process, which is similar to merge sort. - -### Steps in Tim Sort: - -1. **Divide the Array into Runs**: - - Tim Sort splits the array into small pieces or subarrays called "runs." The length of these runs is usually determined by the size of the input and a predefined minimum run size. - -2. **Sort Each Run Using Insertion Sort**: - - Each small run is sorted using insertion sort, which is efficient for small datasets due to its low overhead. - -3. **Merge the Sorted Runs Using Merge Sort**: - - Once the runs are sorted, Tim Sort merges them using the same technique as merge sort, ensuring that the entire array is sorted efficiently. - -### Minimum Run Size: - -Tim Sort selects a "minimum run size," which is typically a power of two or based on heuristics that balance the performance of the insertion sort and merge operations. Common implementations, like Python, use 32 or 64 as the minimum run size. - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -const int RUN = 32; - -// Insertion sort function to sort an array from left to right -void insertionSort(int arr[], int left, int right) { - for (int i = left + 1; i <= right; i++) { - int temp = arr[i]; - int j = i - 1; - while (j >= left && arr[j] > temp) { - arr[j + 1] = arr[j]; - j--; - } - arr[j + 1] = temp; - } -} - -// Merge function to merge two sorted subarrays -void merge(int arr[], int l, int m, int r) { - int len1 = m - l + 1, len2 = r - m; - vector left(len1), right(len2); - - for (int i = 0; i < len1; i++) { - left[i] = arr[l + i]; - } - for (int i = 0; i < len2; i++) { - right[i] = arr[m + 1 + i]; - } - - int i = 0, j = 0, k = l; - while (i < len1 && j < len2) { - if (left[i] <= right[j]) { - arr[k++] = left[i++]; - } else { - arr[k++] = right[j++]; - } - } - - while (i < len1) { - arr[k++] = left[i++]; - } - while (j < len2) { - arr[k++] = right[j++]; - } -} - -// Tim sort function -void timSort(int arr[], int n) { - for (int i = 0; i < n; i += RUN) { - insertionSort(arr, i, min(i + RUN - 1, n - 1)); - } - - for (int size = RUN; size < n; size = 2 * size) { - for (int left = 0; left < n; left += 2 * size) { - int mid = min(left + size - 1, n - 1); - int right = min(left + 2 * size - 1, n - 1); - - if (mid < right) { - merge(arr, left, mid, right); - } - } - } -} - -int main() { - int arr[] = {5, 21, 7, 23, 19}; - int n = sizeof(arr) / sizeof(arr[0]); - - timSort(arr, n); - - cout << "Sorted array: \n"; - for (int i = 0; i < n; i++) { - cout << arr[i] << " "; - } - cout << endl; - - return 0; -} -``` - -### Explanation: - -1. **Insertion Sort for Small Runs**: - - The array is broken into smaller chunks called "runs," and insertion sort is applied to each run. Insertion sort is highly efficient for small, nearly sorted arrays. - -2. **Merge Process**: - - Once the runs are sorted, the algorithm merges them using a process similar to merge sort. The merging happens in logarithmic time, ensuring that the overall time complexity remains O(n log n). - -3. **Adaptive Behavior**: - - Tim Sort adapts to existing order in the data, using insertion sort for smaller runs and merge sort for the rest. This allows it to perform very efficiently on real-world data. - -### Summary: - -Tim Sort is a highly efficient sorting algorithm used in practical applications, particularly in standard libraries like Python and Java. It combines the best aspects of merge sort and insertion sort, making it adaptive, stable, and well-suited for sorting real-world datasets with existing order. Although its worst-case time complexity is O(n log n), its ability to adapt to partially sorted data often gives it a performance edge in practice. diff --git a/docs/algorithms/sorting-algorithms/Topological-sorting-algorithm.md b/docs/algorithms/sorting-algorithms/Topological-sorting-algorithm.md deleted file mode 100644 index 2e63a7516..000000000 --- a/docs/algorithms/sorting-algorithms/Topological-sorting-algorithm.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: topological-sorting-algorithm -title: Topological Sorting Algorithm -sidebar_label: Topological Sorting Algorithm -sidebar_position: 16 -description: "Topological Sorting is a linear ordering of vertices in a directed acyclic graph (DAG) such that for every directed edge u -> v, vertex u comes before v." -tags: [Graph Theory, Topological Sorting, DAG, Sorting Algorithms, Graph Algorithms] ---- - -# Topological Sorting Algorithm - -## Overview -Topological Sorting is a graph-based algorithm used to order vertices of a **Directed Acyclic Graph (DAG)**. It provides a linear ordering of vertices such that for every directed edge **u → v**, vertex **u** comes before **v**. This algorithm is fundamental in tasks such as task scheduling, course prerequisite checking, and more. - -## Introduction -In **Topological Sorting**, vertices of a DAG are arranged in a sequence such that every directed edge points from an earlier vertex to a later one in the sequence. This algorithm is applicable only for **DAGs**, as the presence of a cycle would violate the ordering. - -## Characteristics of Topological Sorting Algorithm -- **Linear Ordering**: Topological sorting produces a linear sequence that respects the directed edges. -- **Acyclic Graph**: Works only with **DAGs** (Directed Acyclic Graphs). -- **No Unique Solution**: There may be multiple valid topological orderings depending on the graph's structure. - -## How Topological Sorting Works -1. **Identify Vertices**: In a DAG, identify vertices with no incoming edges (i.e., in-degree of 0). -2. **Remove Vertices**: Remove the vertex and all its outgoing edges from the graph. -3. **Repeat Process**: Continue the process for remaining vertices until all vertices are ordered. -4. **Result**: The result is a topological ordering where all directed edges point forward in the sequence. - -## Step-by-Step Execution - -```mermaid -graph TD - A((A)) --> B((B)) - A --> C((C)) - B --> D((D)) - C --> D - C --> E((E)) - D --> F((F)) - E --> F -``` -## Execution Steps -Topological Sorting helps in sorting vertices in a Directed Acyclic Graph (DAG) such that for every directed edge `u → v`, vertex `u` comes before `v` in the ordering. - -### Algorithm Steps: -1. **Identify vertices with no incoming edges** (in-degree 0), e.g., vertex A. -2. **Remove A** and its outgoing edges. -3. **Repeat the process** for remaining vertices. -4. **Continue** until all vertices are sorted. - -### Example of Topological Order: -A -→ B -→ C -→ D → E -→ F - -## Time Complexity -**Time Complexity:** O(V + E), where: -- `V` is the number of vertices. -- `E` is the number of edges. - -Each vertex and edge is visited exactly once, making the algorithm linear. - -## Applications -1. **Task Scheduling**: Determines the order in which tasks should be performed, ensuring some tasks precede others. -2. **Course Prerequisites**: Determines the order of courses in an academic curriculum where certain courses have prerequisites. -3. **Dependency Resolution**: Used in package managers to install software dependencies in the correct order. -4. **Compiler Optimization**: Helps determine the order of code execution in a pipeline (instruction scheduling). - -## Pseudocode - -### Kahn's Algorithm for Topological Sorting -1. Compute the in-degree for each vertex. -2. Initialize a queue with all vertices having in-degree 0. -3. While the queue is not empty: - - Dequeue a vertex from the queue. - - Append it to the topological ordering list. - - For each outgoing edge from the dequeued vertex, reduce the in-degree of the adjacent vertex. - - If the in-degree of an adjacent vertex becomes zero, enqueue it. -4. If all vertices are processed, the result is the topological order. Otherwise, the graph contains a cycle. - -### DFS-Based Algorithm -1. Perform DFS on each vertex. -2. On visiting a vertex, mark it as visited and recursively visit all its unvisited neighbors. -3. Once all neighbors are visited, push the vertex onto a stack. -4. After DFS completes, the stack contains the topological order. - -## Advantages of Topological Sorting -- **Efficient Task Ordering**: Helps in scheduling tasks with dependencies. -- **Cycle Detection**: If a cycle exists in the graph, the algorithm will detect it and stop. -- **Linear Time**: The algorithm works in linear time O(V + E) for DAGs. - -## Limitations -- **Applicable Only to DAGs**: Topological sorting works only for Directed Acyclic Graphs. It cannot be applied to cyclic graphs. - -## Conclusion -Topological Sorting is a fundamental algorithm used in many real-world applications such as task scheduling, dependency resolution, and compiler optimization. Understanding how to implement and apply this algorithm is essential for working with Directed Acyclic Graphs (DAGs) in graph theory and computer science. Its linear time complexity makes it efficient for large-scale problems, and its ability to detect cycles ensures that tasks are organized correctly in the absence of cyclic dependencies. - diff --git a/docs/algorithms/sorting-algorithms/TreeSort.md b/docs/algorithms/sorting-algorithms/TreeSort.md deleted file mode 100644 index 598c09c19..000000000 --- a/docs/algorithms/sorting-algorithms/TreeSort.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: tree-sort-algo -sidebar_position: 15 -title: Tree Sort -sidebar_label: Tree Sort ---- - -### Definition: - -Tree Sort is a sorting algorithm that builds a Binary Search Tree (BST) from the elements of the array and then performs an in-order traversal to retrieve the elements in sorted order. It is efficient when the tree remains balanced, but can degrade to quadratic time complexity in the worst case. - -### Characteristics: - -- **Binary Search Tree (BST)**: - - Tree Sort inserts elements into a binary search tree where each node follows the property: the left child is smaller than the parent node and the right child is larger. - -- **In-Order Traversal**: - - Once all elements are inserted into the BST, an in-order traversal is performed to retrieve the elements in sorted order. - -- **Not In-Place**: - - Tree Sort is not an in-place algorithm because it uses additional memory to store the BST. - -- **Stable**: - - Tree Sort can be stable if implemented carefully by ensuring that equal elements are inserted in a way that maintains their relative order. - -### Time Complexity: - -- **Best Case: O(n log n)** - When the tree remains balanced, insertion and traversal operations are logarithmic, resulting in an overall complexity of O(n log n). - -- **Average Case: O(n log n)** - For random input, the tree usually remains balanced. - -- **Worst Case: O(n²)** - In the worst case, such as when inserting elements that are already sorted, the tree can become skewed, and the algorithm may take O(n²) time. - -### Space Complexity: - -- **Space Complexity: O(n)** - The algorithm uses extra space for the tree structure, proportional to the number of elements in the input array. - -### Java Implementation: - -```java -// Class to represent a node in the BST -class TreeNode { - int value; - TreeNode left, right; - - public TreeNode(int value) { - this.value = value; - left = right = null; - } -} - -// TreeSort class -public class TreeSort { - TreeNode root; - - // Method to insert a node into the BST - void insert(int value) { - root = insertRec(root, value); - } - - // Recursive method to insert a node into the BST - TreeNode insertRec(TreeNode root, int value) { - if (root == null) { - root = new TreeNode(value); - return root; - } - if (value < root.value) { - root.left = insertRec(root.left, value); - } else if (value > root.value) { - root.right = insertRec(root.right, value); - } - return root; - } - - // Method to perform an in-order traversal - void inorderRec(TreeNode root) { - if (root != null) { - inorderRec(root.left); - System.out.print(root.value + " "); - inorderRec(root.right); - } - } - - // Main function to sort an array using Tree Sort - void treeSort(int[] arr) { - for (int value : arr) { - insert(value); - } - inorderRec(root); // Prints the sorted elements - } - - public static void main(String[] args) { - TreeSort tree = new TreeSort(); - int[] arr = {5, 3, 7, 2, 8, 1, 9}; - System.out.println("Sorted array:"); - tree.treeSort(arr); - } -} -``` - -### Summary: -Tree Sort is an intuitive and simple sorting algorithm that leverages the properties of Binary Search Trees to sort an array. While its average-case time complexity is 𝑂(𝑛log𝑛) O(nlogn), it can degrade to 𝑂(𝑛2) O(n2) in the worst case, making it less suitable for practical use in many scenarios compared to other algorithms like QuickSort or MergeSort. diff --git a/docs/algorithms/sorting-algorithms/_category_.json b/docs/algorithms/sorting-algorithms/_category_.json deleted file mode 100644 index eb8a080f8..000000000 --- a/docs/algorithms/sorting-algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Sorting Algorithms", - "position": 2, - "link": { - "type": "generated-index", - "description": "Learn about some Sorting Algorithms." - } - } \ No newline at end of file diff --git a/docs/algorithms/sorting-algorithms/odd-even-sorting.md b/docs/algorithms/sorting-algorithms/odd-even-sorting.md deleted file mode 100644 index a9995b6e3..000000000 --- a/docs/algorithms/sorting-algorithms/odd-even-sorting.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: odd-even-sorting -title: Odd Even Sorting -sidebar_label: Odd Even Sorting Algorithm -sidebar_position: 17 -description: "Odd-Even Sort is a simple comparison-based sorting algorithm, also known as Brick Sort." -tags: [Sorting Algorithms, odd-even-sort, brick-sort] ---- - -Odd-Even Sort, also known as **Brick Sort**, is a simple comparison-based sorting algorithm. It works by repeatedly comparing all odd-indexed elements with their next even-indexed neighbour and swapping them if they are out of order. Then, it performs the same comparison for even-indexed elements and continues alternating between these two phases until the list is sorted. - ---- - -## Characteristics - -- **Parallel Comparison**: Odd-Even Sort alternates between comparing odd-indexed and even-indexed pairs of elements, which makes it suitable for parallel execution. - -- **In-Place Sorting**: The algorithm operates directly on the input array, requiring no additional memory aside from the input array itself. - -- **Stable**: Odd-Even Sort is stable, meaning it preserves the relative order of elements with equal values. - -- **Simple Implementation**: Easy to implement, but it can be inefficient for large datasets. - ---- - -## Time Complexity - -- **Best Case**: $O(n)$ (when the array is already sorted) -- **Average Case**: $O(n^2)$ -- **Worst Case**: $O(n^2)$ (when the array is in reverse order) - ---- - -## Space Complexity - -- **Space Complexity**: $O(1)$ since the sorting is performed in-place. - ---- - -## Java Implementation - -```java -import java.util.Scanner; - -public class OddEvenSort { - // Function to perform odd-even sort - public static void oddEvenSort(int[] arr) { - boolean sorted = false; // Initially, the array is unsorted - - while (!sorted) { - sorted = true; - - // Perform Odd phase - for (int i = 1; i < arr.length - 1; i += 2) { - if (arr[i] > arr[i + 1]) { - swap(arr, i, i + 1); - sorted = false; - } - } - - // Perform Even phase - for (int i = 0; i < arr.length - 1; i += 2) { - if (arr[i] > arr[i + 1]) { - swap(arr, i, i + 1); - sorted = false; - } - } - } - } - - // Function to swap two elements in the array - private static void swap(int[] arr, int i, int j) { - int temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - - System.out.print("Enter the number of elements: "); - int n = scanner.nextInt(); - - int[] arr = new int[n]; - System.out.println("Enter " + n + " elements:"); - for (int i = 0; i < n; i++) { - arr[i] = scanner.nextInt(); - } - - oddEvenSort(arr); - - System.out.println("Sorted array:"); - for (int num : arr) { - System.out.print(num + " "); - } - System.out.println(); - - scanner.close(); - } -} -``` - ---- - -## Explanation - -1. **Odd Phase**: In the odd phase, elements at odd indices are compared to their next even neighbours. If an odd-indexed element is greater than the following even-indexed element, they are swapped. - -2. **Even Phase**: In the even phase, even-indexed elements are compared to their next odd-indexed neighbour and swapped if necessary. - -3. **Repetition**: These phases alternate until no swaps are necessary in a complete pass, which means the array is sorted. - ---- - -## Summary - -Odd-Even Sort is a basic sorting algorithm that repeatedly compares and swaps adjacent elements based on their odd or even positions. Despite its simplicity, it is inefficient for large datasets due to its $O(n^2)$ average and worst-case time complexity. However, its ease of implementation and potential for parallelization make it suitable for specific scenarios. diff --git a/docs/algorithms/sorting-algorithms/parity-partition-sort.md b/docs/algorithms/sorting-algorithms/parity-partition-sort.md deleted file mode 100644 index c84fb0d9d..000000000 --- a/docs/algorithms/sorting-algorithms/parity-partition-sort.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -id: parity-partition-sort -title: Parity Partition Sort -sidebar_label: "Strand Sort" -sidebar_position: 9 -description: Overview and examples of Parity Partition Sort. -tags: [sorting, dsa, algorithms, programming, parity sort, partition sort, parity partition sort] ---- - -**Parity Partition Sort** - -**Definition** - -Parity Partition Sort is a sorting algorithm that initially partitions an array into two subarrays: one containing even numbers and the other containing odd numbers. It then sorts each subarray independently using a standard sorting algorithm like Merge Sort or Insertion Sort. Finally, the two sorted subarrays are merged to form the final sorted array. - -**Algorithm** - -1. **Partition:** - - Iterate through the array and place even numbers in the left part of a temporary array. - - Place odd numbers in the right part of the temporary array. -2. **Sort:** - - Sort the even and odd partitions independently using a suitable sorting algorithm (e.g., Merge Sort). -3. **Merge:** - - Merge the sorted even and odd partitions back into the original array. - -**Java Implementation** - -```java -public class ParityPartitionSort { - public void paritySort(int[] arr) { - int n = arr.length; - int[] temp = new int[n]; - int evenIndex = 0, oddIndex = n - 1; - - // Partition the array into even and odd parts - for (int num : arr) { - if (num % 2 == 0) { - temp[evenIndex++] = num; - } else { - temp[oddIndex--] = num; - } - } - - // Sort the even and odd partitions - mergeSort(temp, 0, evenIndex - 1); - mergeSort(temp, oddIndex + 1, n - 1); - - // Copy the sorted array back - System.arraycopy(temp, 0, arr, 0, n); - } - - // Merge Sort implementation (for sorting even and odd partitions) - // ... (Merge Sort implementation) -} -``` - -**Time Complexity** - -* **Partitioning:** O(n) -* **Sorting:** O(n log n) for each partition -* **Merging:** O(n) - -**Overall Time Complexity:** O(n log n) - -**Space Complexity:** O(n) for the temporary array. diff --git a/docs/algorithms/sorting-algorithms/strand-sort.md b/docs/algorithms/sorting-algorithms/strand-sort.md deleted file mode 100644 index ed6bb1e8b..000000000 --- a/docs/algorithms/sorting-algorithms/strand-sort.md +++ /dev/null @@ -1,375 +0,0 @@ ---- -id: strand-sort -title: Strand Sort -sidebar_label: "Strand Sort" -sidebar_position: 8 -description: An overview of the Strand Sort Algorithm and its applications in programming. -tags: [sorting, dsa, algorithms, programming, strand sort] ---- - -**Strand Sort** is a recursive sorting algorithm that repeatedly extracts sorted sublists (strands) from the unsorted list and merges them to create a sorted list. - -## Steps: - -1. **Extract a strand**: Start from the first element of the list. Extract elements in order as long as they are larger than the last extracted one. - -2. **Remove extracted elements**: Once a strand is extracted, remove those elements from the original list. - -3. **Merge the strand**: Merge the extracted strand into the previously sorted list. - -4. **Repeat**: Repeat the process with the remaining unsorted elements until all elements are sorted. - -### Example - -Let’s take an unsorted list: -`[4, 3, 9, 1, 7, 2, 6, 5, 8]` - -#### Step-by-Step Execution: - -1. **Initial list**: - `Unsorted list = [4, 3, 9, 1, 7, 2, 6, 5, 8]` - -2. **Extract the first strand**: - - Start with the first element `4`. - - Next, `9` is larger than `4`, so we add it to the strand. - - The extracted strand is `[4, 9]`. - - Now, the unsorted list becomes: - `Unsorted list = [3, 1, 7, 2, 6, 5, 8]` - -3. **Merge the strand with the sorted list**: - - The sorted list is initially empty. - - Merging the first strand `[4, 9]` results in: - `Sorted list = [4, 9]`. - -4. **Extract the second strand**: - - Start with the first element `3`. - - Next, `7` is larger than `3`, so we add it to the strand. - - The extracted strand is `[3, 7]`. - - Now, the unsorted list becomes: - `Unsorted list = [1, 2, 6, 5, 8]` - -5. **Merge the second strand**: - - Merge the second strand `[3, 7]` with the sorted list `[4, 9]`. - - The result after merging: - `Sorted list = [3, 4, 7, 9]`. - -6. **Extract the third strand**: - - Start with the first element `1`. - - `2` is larger than `1`, so we add it. - - `6` is larger than `2`, so we add it as well. - - The extracted strand is `[1, 2, 6]`. - - Now, the unsorted list becomes: - `Unsorted list = [5, 8]` - -7. **Merge the third strand**: - - Merge the third strand `[1, 2, 6]` with the sorted list `[3, 4, 7, 9]`. - - The result after merging: - `Sorted list = [1, 2, 3, 4, 6, 7, 9]`. - -8. **Extract the fourth strand**: - - Start with the first element `5`. - - Next, `8` is larger than `5`, so we add it. - - The extracted strand is `[5, 8]`. - - Now, the unsorted list is empty: - `Unsorted list = []` - -9. **Merge the fourth strand**: - - Merge the final strand `[5, 8]` with the sorted list `[1, 2, 3, 4, 6, 7, 9]`. - - The result after merging: - `Sorted list = [1, 2, 3, 4, 5, 6, 7, 8, 9]`. - -### Final Sorted List: -The sorted list is: -`[1, 2, 3, 4, 5, 6, 7, 8, 9]` - - - -## Time Complexity Analysis - -### Best Case: - -- **Time Complexity: O(n log n)** - In the best case, each strand extracted is already sorted, meaning the extracted strand contains multiple elements. This scenario reduces the number of merges required and results in an efficient merge process similar to merge sort. - -- **Example (Best Case)**: - If the input list is nearly sorted or already sorted, the strands will be long, minimizing the total number of merges. - - Example List: - `[1, 2, 3, 4, 5, 6, 7, 8, 9]` - - The first strand extracted will be the entire list: `[1, 2, 3, 4, 5, 6, 7, 8, 9]`. - - No further extraction or merging is required. - -- **Number of strands**: Only one large strand. -- **Merge steps**: None. - - This minimizes both the number of strands extracted and merge operations, resulting in O(n log n). - -### Worst Case: - -- **Time Complexity: O(n²)** - In the worst case, each extracted strand contains only one element, meaning the strands are as short as possible. This leads to the maximum number of merge operations. - -- **Example (Worst Case)**: - If the input list is in reverse order, each element must be extracted individually, as each element will be smaller than the previous one. - - Example List: - `[9, 8, 7, 6, 5, 4, 3, 2, 1]` - - The first strand extracted is `[9]`. - - The next extracted strand is `[8]`, and so on. - - This requires many merging operations, with each strand consisting of just one element. - -- **Number of strands**: n (where each strand contains only one element). -- **Merge steps**: Each strand (single element) must be merged one-by-one into the sorted list. - - This results in O(n²) due to excessive merging operations. - ---- - -## Example for Worst Case: - -Consider the reverse sorted list: - -`[9, 8, 7, 6, 5, 4, 3, 2, 1]` - -1. Extract strands: - - First strand: `[9]` - - Second strand: `[8]` - - Third strand: `[7]` - - (Continue extracting single elements until the list is empty) - -2. Merge process: - - Merge `[9]` with `[8]` → `[8, 9]` - - Merge `[8, 9]` with `[7]` → `[7, 8, 9]` - - Continue merging each extracted strand (one element) with the sorted list. - -3. Since each strand consists of only one element, the number of merging steps grows quadratically as we repeatedly merge single-element strands into an ever-growing sorted list. - -This results in a time complexity of **O(n²)**. - ---- - -## Example for Best Case: - -Consider a sorted list: - -`[1, 2, 3, 4, 5, 6, 7, 8, 9]` - -1. Extract strands: - - The first strand will be `[1, 2, 3, 4, 5, 6, 7, 8, 9]`. - -2. Merge process: - - Since the entire list was extracted as a single strand, no further merging steps are required. - -This leads to the best-case time complexity of **O(n log n)**. - ---- - -## Summary of Time Complexity - -- **Best Case**: O(n log n) — Occurs when the list is already sorted or nearly sorted, reducing the number of strands and merge operations. -- **Worst Case**: O(n²) — Occurs when each strand contains only one element (e.g., reverse sorted list), leading to many merge operations. -- **Average Case**: Typically between O(n log n) and O(n²), depending on the structure of the input list. - - - - -## Advantages: -1. **Simple to understand**: The process of extracting sorted strands and merging is conceptually easy. -2. **Works well with linked lists**: As strand sort can efficiently handle linked lists, it avoids the overhead of frequent element shifting like in arrays. -3. **Stable sort**: Strand sort maintains the relative order of equal elements. - -## Disadvantages: -1. **Not efficient for large datasets**: The worst-case time complexity is O(n²), which makes it inefficient for large lists. -2. **Recursive nature**: Its recursive design can lead to high memory usage and potential stack overflow issues for deep recursion. -3. **Limited use cases**: Due to its inefficiency with arrays and larger datasets, it's not commonly used in practice. - -## Implementations - -### 1. **C Implementation** - -```c -#include -#include - -typedef struct Node { - int data; - struct Node* next; -} Node; - -Node* newNode(int data) { - Node* node = (Node*)malloc(sizeof(Node)); - node->data = data; - node->next = NULL; - return node; -} - -void append(Node** head, int data) { - Node* temp = *head; - Node* new_node = newNode(data); - if (!*head) { - *head = new_node; - return; - } - while (temp->next) - temp = temp->next; - temp->next = new_node; -} - -Node* merge(Node* a, Node* b) { - if (!a) return b; - if (!b) return a; - - if (a->data < b->data) { - a->next = merge(a->next, b); - return a; - } else { - b->next = merge(a, b->next); - return b; - } -} - -Node* extractStrand(Node** head) { - Node* curr = *head, *prev = NULL, *strand = NULL, *tail = NULL; - while (curr) { - if (!prev || curr->data >= prev->data) { - if (!strand) strand = tail = curr; - else { - tail->next = curr; - tail = curr; - } - if (prev) prev->next = curr->next; - else *head = curr->next; - curr = curr->next; - tail->next = NULL; - } else { - prev = curr; - curr = curr->next; - } - } - return strand; -} - -void strandSort(Node** head) { - Node* sorted = NULL; - while (*head) { - Node* strand = extractStrand(head); - sorted = merge(sorted, strand); - } - *head = sorted; -} - -void printList(Node* head) { - while (head) { - printf("%d ", head->data); - head = head->next; - } - printf("\n"); -} - -int main() { - Node* head = NULL; - int arr[] = {4, 3, 9, 1, 7, 2, 6, 5, 8}; - int n = sizeof(arr) / sizeof(arr[0]); - - for (int i = 0; i < n; i++) append(&head, arr[i]); - - strandSort(&head); - - printf("Sorted list: "); - printList(head); - return 0; -} -``` -# 2) Python Implementation -```c -def merge(a, b): - if not a: - return b - if not b: - return a - - if a[0] < b[0]: - return [a[0]] + merge(a[1:], b) - else: - return [b[0]] + merge(a, b[1:]) - -def extract_strand(lst): - strand = [lst[0]] - i = 1 - while i < len(lst): - if lst[i] >= strand[-1]: - strand.append(lst.pop(i)) - else: - i += 1 - return strand - -def strand_sort(lst): - sorted_lst = [] - while lst: - strand = extract_strand(lst) - sorted_lst = merge(sorted_lst, strand) - return sorted_lst - -# Example usage -lst = [4, 3, 9, 1, 7, 2, 6, 5, 8] -sorted_lst = strand_sort(lst) -print("Sorted list:", sorted_lst) -``` -# 3) Java Implementation - -```c -import java.util.LinkedList; - -public class StrandSort { - public static LinkedList merge(LinkedList a, LinkedList b) { - LinkedList result = new LinkedList<>(); - while (!a.isEmpty() && !b.isEmpty()) { - if (a.peek() <= b.peek()) { - result.add(a.poll()); - } else { - result.add(b.poll()); - } - } - result.addAll(a); - result.addAll(b); - return result; - } - - public static LinkedList extractStrand(LinkedList list) { - LinkedList strand = new LinkedList<>(); - strand.add(list.poll()); - for (int i = 0; i < list.size(); ) { - if (list.get(i) >= strand.getLast()) { - strand.add(list.remove(i)); - } else { - i++; - } - } - return strand; - } - - public static LinkedList strandSort(LinkedList list) { - LinkedList sorted = new LinkedList<>(); - while (!list.isEmpty()) { - LinkedList strand = extractStrand(list); - sorted = merge(sorted, strand); - } - return sorted; - } - - public static void main(String[] args) { - LinkedList list = new LinkedList<>(); - int[] arr = {4, 3, 9, 1, 7, 2, 6, 5, 8}; - for (int j : arr) { - list.add(j); - } - - LinkedList sortedList = strandSort(list); - System.out.println("Sorted list: " + sortedList); - } -} -``` diff --git a/docs/algorithms/string-algorithm/Boyer-moore-algorithm.md b/docs/algorithms/string-algorithm/Boyer-moore-algorithm.md deleted file mode 100644 index 0abd03bdd..000000000 --- a/docs/algorithms/string-algorithm/Boyer-moore-algorithm.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: boyer-moore-algorithm -title: Boyer-Moore Algorithm for Pattern Matching -sidebar_label: Boyer-Moore -sidebar_position: 7 -description: "A comprehensive guide to using the Boyer-Moore Algorithm for efficient pattern matching." -tags: [pattern matching, string algorithms, competitive programming, Boyer-Moore] ---- - -Below is a detailed explanation of the Boyer-Moore algorithm, a powerful string-searching algorithm that efficiently finds occurrences of a pattern in a text by leveraging information from the pattern itself. - - - -## Definition: - -The Boyer-Moore algorithm is an efficient pattern-matching algorithm that searches for occurrences of a pattern in a text by leveraging information from the pattern itself. It achieves sublinear time complexity in many cases, making it one of the fastest string searching algorithms. - -## Explanation: - -The Boyer-Moore algorithm preprocesses the pattern to create two heuristic tables: the **bad character rule** and the **good suffix rule**. These tables help determine how far the search window can be moved after a mismatch, significantly reducing the number of comparisons needed. - -## Bad Character Rule: - -When a mismatch occurs, the bad character rule dictates that the pattern should be shifted to the right so that the last occurrence of the mismatched character in the pattern aligns with the text character, or the pattern should be shifted past the text character if the character does not exist in the pattern. - -## Good Suffix Rule: - -If a part of the pattern matches the text but fails at some point, the good suffix rule determines how much to shift the pattern based on the longest suffix of the pattern that matches the text. - - - -## Code Implementation (Python): - -```python -def bad_character_heuristic(pattern): - """Creates the bad character table for the given pattern. - - Args: - pattern: The pattern string. - - Returns: - A dictionary mapping characters to their last occurrence index in the pattern. - """ - bad_char = {} - for i in range(len(pattern)): - bad_char[pattern[i]] = i - return bad_char - -def boyer_moore_search(pattern, text): - """Performs Boyer-Moore algorithm for pattern matching. - - Args: - pattern: The pattern to be searched. - text: The text in which the pattern is searched. - - Returns: - A list of starting indices where the pattern is found in the text. - """ - m = len(pattern) - n = len(text) - bad_char = bad_character_heuristic(pattern) - result = [] - - s = 0 # shift of the pattern with respect to text - while s <= n - m: - j = m - 1 - - while j >= 0 and pattern[j] == text[s + j]: - j -= 1 - - if j < 0: - result.append(s) - s += (m - bad_char.get(text[s + m], -1)) if s + m < n else 1 - else: - s += max(1, j - bad_char.get(text[s + j], -1)) - - return result - -# Example usage -text = "ABABDABACDABABCABAB" -pattern = "ABABCABAB" - - -result = boyer_moore_search(pattern, text) - -print("Pattern found at indices:", result) -``` - - - - -## Complexity Analysis: - -- **Time Complexity:** The Boyer-Moore algorithm has an average-case time complexity of $O(n/m)$, where $n$ is the length of the text and $m$ is the length of the pattern. In the worst case, the time complexity is $O(nm)$. -- **Space Complexity:** The space complexity of the algorithm is $O(m)$, where $m$ is the length of the pattern. This space is used to store the bad character heuristic table. - -The Boyer-Moore algorithm is particularly effective when the alphabet size is small and the pattern length is relatively large. It is widely used in practice due to its efficiency in many real-world scenarios. - -## Key Takeaways: - -- The Boyer-Moore algorithm is a powerful string-searching algorithm that leverages information from the pattern itself to efficiently find occurrences of the pattern in a text. -- It preprocesses the pattern to create heuristic tables that guide the shifting of the pattern during the search process, reducing the number of comparisons needed. -- By using the bad character rule and the good suffix rule, the Boyer-Moore algorithm can achieve sublinear time complexity in many cases, making it one of the fastest string searching algorithms. - -The Boyer-Moore algorithm is a valuable addition to the toolkit of any programmer dealing with pattern matching tasks, especially in scenarios where efficiency is crucial. Its ability to achieve sublinear time complexity in many cases makes it a popular choice for various applications. - - \ No newline at end of file diff --git a/docs/algorithms/string-algorithm/Naive-search.md b/docs/algorithms/string-algorithm/Naive-search.md deleted file mode 100644 index c57a32a41..000000000 --- a/docs/algorithms/string-algorithm/Naive-search.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: naive-search-algorithm -title: "Naive Search Algorithm" -sidebar_label: "Naive Search" -sidebar_position: 8 -description: "A basic string-search algorithm that checks every position in the text for a match with the pattern." -tags: [pattern matching, string algorithms, brute-force search, naive search, competitive programming] ---- - -In computer science, the **Naive Search Algorithm** (also known as brute-force search) is a basic string matching technique that checks every possible position in the text for the occurrence of a given pattern. Although simple to implement, it is inefficient for large texts and patterns as it performs comparisons one by one without any optimization. - - - -## Overview - -The **Naive Search Algorithm** (also known as brute-force search) is a basic string matching technique that checks every possible position in the text for the occurrence of a given pattern. Although simple to implement, it is inefficient for large texts and patterns as it performs comparisons one by one without any optimization. - -### Time Complexity: -- **Worst Case:** O(n * m) -Where: -- `n` is the length of the text. -- `m` is the length of the pattern. - -## How It Works - -1. The algorithm starts at the first character of the text. -2. It compares the pattern to a substring of the text of the same length. -3. If there’s a mismatch, it moves one position to the right and repeats the comparison. -4. If a match is found, it records the position. -5. This process continues until the entire text has been checked. - -## Example - -For the text `text = "abcabcabc"` and pattern `pattern = "abc"`, the naive search will compare: - -- Compare `"abc"` with the first three characters: **Match** at index 0. -- Move to the next position and compare `"bca"`, then `"cab"`: **Mismatch**. -- Compare `"abc"` with the next `"abc"` at index 3: **Match**. - -Thus, matches are found at indices 0 and 3. - - - -## Code Implementation - -### Python - -```python -def naive_search(pattern, text): - """Naive search algorithm for pattern matching. - - Args: - pattern: The pattern string to search for. - text: The text string where the pattern is to be searched. - - Returns: - A list of starting indices where the pattern is found in the text. - """ - m = len(pattern) - n = len(text) - result = [] - - # Traverse the text and compare each substring of length m with the pattern - for i in range(n - m + 1): - if text[i:i + m] == pattern: - result.append(i) - - return result - -# Example usage -text = "abcabcabc" -pattern = "abc" -matches = naive_search(pattern, text) -print("Pattern found at indices:", matches) -``` - -### C++ - -```cpp -#include -#include -#include -using namespace std; - -vector naive_search(string pattern, string text) { - int m = pattern.length(); - int n = text.length(); - vector result; - - // Traverse the text and compare each substring of length m with the pattern - for (int i = 0; i <= n - m; i++) { - bool match = true; - for (int j = 0; j < m; j++) { - if (text[i + j] != pattern[j]) { - match = false; - break; - } - } - if (match) { - result.push_back(i); - } - } - - return result; -} - -int main() { - string text = "abcabcabc"; - string pattern = "abc"; - - vector matches = naive_search(pattern, text); - cout << "Pattern found at indices: "; - for (int index : matches) - cout << index << " "; - cout << endl; - - return 0; -} -``` - - - -## Limitations - -- **Efficiency:** The algorithm performs O(n * m) comparisons in the worst case, which is inefficient for large texts and patterns. -- **No Optimization:** Unlike more advanced algorithms like Rabin-Karp or Knuth-Morris-Pratt, the naive search algorithm does not use any hashing or preprocessing to improve search times. - -## Applications - -- **Educational Use:** Due to its simplicity, the naive search is often used to introduce pattern matching algorithms. -- **Small-scale Search Problems:** Suitable for small text searches or when efficiency is not a primary concern. - -## Complexity Analysis - -- **Time Complexity:** The naive search algorithm has a time complexity of $O(n * m)$ in the worst case, where n is the length of the text and m is the length of the pattern. - -- **Space Complexity:** The space complexity of the algorithm is $O(1)$ as it does not require any additional space apart from the input strings. - -The naive search algorithm is a simple and intuitive approach to pattern matching but is not suitable for large-scale applications due to its inefficiency. More advanced algorithms like Rabin-Karp, Knuth-Morris-Pratt, or Boyer-Moore are preferred for real-world scenarios. - - - -## Conclusion - -The **Naive Search Algorithm** is a basic string matching technique that checks every possible position in the text for the occurrence of a given pattern. Although simple to implement, it is inefficient for large texts and patterns as it performs comparisons one by one without any optimization. \ No newline at end of file diff --git a/docs/algorithms/string-algorithm/Suffix-Tree-Algorithm.md b/docs/algorithms/string-algorithm/Suffix-Tree-Algorithm.md deleted file mode 100644 index fee059147..000000000 --- a/docs/algorithms/string-algorithm/Suffix-Tree-Algorithm.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: suffix-tree-algorithm -title: Suffix Tree Algorithm -sidebar_label: Suffix Tree -tags: [String Matching, DSA, Suffix Tree, Tree] -description: Construct and search a Suffix Tree efficiently to represent all suffixes of a string for substring searching and pattern matching. ---- - -In computer science, a **suffix tree** is a compressed trie containing all the suffixes of a given text as their keys and positions in the text as their values. Suffix trees allow particularly fast implementations of many important string operations, such as substring search. They are used in bioinformatics applications, such as in the construction of the Burrows–Wheeler transform and in the compression of DNA sequences. - - - -## Description - -A **suffix tree** is a compressed tries of all the suffixes of a given string. It allows for efficient substring searching, pattern matching, and other operations on strings. Suffix trees provide a way to represent all substrings of a string in a space-efficient manner. - -### Problem Definition - -- **Input**: - - A string `S` of length `n`. - -- **Output**: - - A suffix tree representing all suffixes of `S`. - - - -### Algorithm Overview - -1. **Construction**: - - Build the suffix tree by inserting all suffixes of the string. - - Use an efficient algorithm (e.g., Ukkonen's algorithm) to construct the suffix tree in linear time. - -2. **Searching**: - - Traverse the suffix tree to search for patterns and substrings efficiently. - -### Time Complexity - -- Construction: `O(n)` (for efficient algorithms like Ukkonen's). -- Search: `O(m)` for a pattern of length `m`. - -### Space Complexity - -- `O(n)` for storing the suffix tree. - -### C++ Implementation - -Below is a simple implementation of a suffix tree. Note that a full implementation may require more complexity to handle various cases. - -```cpp -#include -#include -#include -#include - -using namespace std; - -struct SuffixTreeNode { - map children; - int start, *end; - int suffixIndex; -}; - -class SuffixTree { -public: - SuffixTreeNode* root; - string text; - - SuffixTree(const string& text) { - this->text = text; - root = new SuffixTreeNode(); - root->start = -1; - root->end = new int(-1); - buildSuffixTree(); - } - - void buildSuffixTree() { - int n = text.size(); - for (int i = 0; i < n; i++) { - insertSuffix(i); - } - } - - void insertSuffix(int index) { - SuffixTreeNode* currentNode = root; - for (int i = index; i < text.size(); i++) { - char currentChar = text[i]; - if (currentNode->children.find(currentChar) == currentNode->children.end()) { - currentNode->children[currentChar] = new SuffixTreeNode(); - } - currentNode = currentNode->children[currentChar]; - } - currentNode->suffixIndex = index; - } -}; - -int main() { - string text = "banana"; - SuffixTree suffixTree(text); - cout << "Suffix tree constructed for: " << text << endl; - return 0; -} -``` - - - -## Conclusion - -The suffix tree is a powerful data structure for string matching and pattern searching. It allows for efficient construction and searching of substrings in linear time. Suffix trees are widely used in bioinformatics and other applications where string operations are required. \ No newline at end of file diff --git a/docs/algorithms/string-algorithm/Z-Algorithm.md b/docs/algorithms/string-algorithm/Z-Algorithm.md deleted file mode 100644 index 6ebc72549..000000000 --- a/docs/algorithms/string-algorithm/Z-Algorithm.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -id: z-algorithm -title: "Z Algorithm" -sidebar_label: "Z Algorithm" -sidebar_position: 6 -description: "A comprehensive guide to using the Z-Algorithm for efficient pattern matching." -tags: [pattern matching, string algorithms, competitive programming] ---- - -In computer science, the **Z-Algorithm** is an efficient linear-time algorithm used for pattern matching in strings. It computes an array Z for a given string S, where Z[i] contains the length of the longest substring starting from S[i] that is also a prefix of S. The Z-Algorithm is widely used in competitive programming and string matching applications. - - - -## Definition: - -The Z-Algorithm computes an array Z for a string S such that Z[i] contains the length of the longest substring starting from S[i] that is also a prefix of S. It is an efficient method to solve pattern matching problems. - -## Explanation: - -Given a string S of length n, the Z-array is computed where Z[i] is the length of the longest substring starting from S[i] that matches the prefix of S. The algorithm runs in O(n) time and is used in various string matching applications. - - - -## Code Implementation - -```python -def calculate_z(S): - """Calculates the Z-array for a given string S. - - Args: - S: The input string. - - Returns: - A list where each element i contains the length of the longest substring - starting from S[i] which is also a prefix of S. - """ - Z = [0] * len(S) - L, R, K = 0, 0, 0 - for i in range(1, len(S)): - if i > R: - L, R = i, i - while R < len(S) and S[R] == S[R - L]: - R += 1 - Z[i] = R - L - R -= 1 - else: - K = i - L - if Z[K] < R - i + 1: - Z[i] = Z[K] - else: - L = i - while R < len(S) and S[R] == S[R - L]: - R += 1 - Z[i] = R - L - R -= 1 - return Z -``` - -### Code Implementation (C++): - -```cpp -#include -#include -using namespace std; - -vector calculate_z(string S) { - int n = S.length(); - vector Z(n); - int L = 0, R = 0, K; - - for (int i = 1; i < n; i++) { - if (i > R) { - L = R = i; - while (R < n && S[R] == S[R - L]) - R++; - Z[i] = R - L; - R--; - } else { - K = i - L; - if (Z[K] < R - i + 1) { - Z[i] = Z[K]; - } else { - L = i; - while (R < n && S[R] == S[R - L]) - R++; - Z[i] = R - L; - R--; - } - } - } - return Z; -} - -int main() { - string S = "aabcaabxaaaz"; - vector Z = calculate_z(S); - - cout << "Z-array: "; - for (int z : Z) - cout << z << " "; - cout << endl; - - return 0; -} -``` - -### Code Implementation (Java): - -```java -import java.util.Arrays; - -public class ZAlgorithm { - - public static int[] calculate_z(String S) { - int n = S.length(); - int[] Z = new int[n]; - int L = 0, R = 0, K; - - for (int i = 1; i < n; i++) { - if (i > R) { - L = R = i; - while (R < n && S.charAt(R) == S.charAt(R - L)) - R++; - Z[i] = R - L; - R--; - } else { - K = i - L; - if (Z[K] < R - i + 1) { - Z[i] = Z[K]; - } else { - L = i; - while (R < n && S.charAt(R) == S.charAt(R - L)) - R++; - Z[i] = R - L; - R--; - } - } - } - return Z; - } - - public static void main(String[] args) { - String S = "aabcaabxaaaz"; - int[] Z = calculate_z(S); - - System.out.println("Z-array: " + Arrays.toString(Z)); - } -} -``` - - - -## Explanation of the Code: - -- **calculate_z:** This function computes the Z-array for the given string S. The Z-array holds the length of the longest substring starting from index i that matches the prefix of the string. -- The Z-values are calculated using two pointers, L and R, which define the current window where a match with the prefix exists. - -### Example Usage: - -For the string `S = "aabcaabxaaaz"`, the computed Z-array is `[0, 1, 0, 0, 3, 1, 0, 0, 2, 1, 0, 0]`. - -## Applications in Competitive Programming - -### Pattern Matching: -The Z-algorithm is used to search for occurrences of a pattern in a text by concatenating the pattern and text with a unique separator and computing the Z-array. - -### String Matching: -Efficiently find all occurrences of a pattern in a string, which is useful in solving problems like finding periodicities in strings or solving DNA sequence matching. - -### Prefix-Suffix Problems: -Can be used to find all prefixes of a string that are also suffixes, which is helpful in problems like finding palindromes and string periodicity. diff --git a/docs/algorithms/string-algorithm/aho-corasick-algorithm.md b/docs/algorithms/string-algorithm/aho-corasick-algorithm.md deleted file mode 100644 index 40019e95d..000000000 --- a/docs/algorithms/string-algorithm/aho-corasick-algorithm.md +++ /dev/null @@ -1,259 +0,0 @@ ---- -id: aho-corasick-algorithm -title: "Aho-Corasick Algorithm" -sidebar_label: "Aho-Corasick" -sidebar_position: 9 -description: "An efficient algorithm for multiple pattern matching using a trie and failure links." -tags: [pattern matching, string algorithms, Aho-Corasick, trie, competitive programming] ---- - -In computer science, the **Aho-Corasick Algorithm** is a string searching algorithm that efficiently finds multiple patterns in a given text. It constructs a finite-state machine in the form of a trie (prefix tree) with failure links, allowing it to search for all patterns simultaneously in linear time. - - - -## Overview - -The **Aho-Corasick Algorithm** is a classical string matching algorithm used for efficiently finding multiple patterns within a given text. It constructs a finite-state machine in the form of a trie (prefix tree) with failure links, which allows it to search for all patterns simultaneously in linear time. - -### Time Complexity: -- **Construction Time:** O(m), where `m` is the total number of characters in all patterns. -- **Search Time:** O(n), where `n` is the length of the text. - -## How It Works - -1. **Trie Construction:** All patterns are inserted into a trie where each node represents a character in the patterns. -2. **Failure Links:** Failure links are added to each node, pointing to the longest suffix which is also a prefix. This allows the algorithm to efficiently transition between nodes when a mismatch occurs. -3. **Pattern Search:** The text is processed one character at a time, following the trie structure to match the patterns. If a mismatch occurs, failure links are used to skip unnecessary comparisons. - -## Example - -Given patterns `["he", "she", "his", "hers"]` and the text `"ushers"`, the Aho-Corasick algorithm constructs a trie with failure links to search for these patterns. The algorithm finds matches for `"he"`, `"she"`, and `"hers"`. - -## Code Implementation - -### Python - -```python -from collections import deque, defaultdict - -class AhoCorasick: - def __init__(self, patterns): - """Initialize the Aho-Corasick automaton for the given patterns.""" - self.trie = {} - self.output = defaultdict(list) - self.fail = {} - - # Build the trie - self._build_trie(patterns) - - # Add failure links - self._build_failure_links() - - def _build_trie(self, patterns): - """Insert patterns into the trie.""" - self.trie = {'root': {}} - new_node = 0 - - for idx, pattern in enumerate(patterns): - node = 'root' - for char in pattern: - if char not in self.trie[node]: - new_node += 1 - self.trie[node][char] = str(new_node) - self.trie[str(new_node)] = {} - node = self.trie[node][char] - self.output[node].append(pattern) - - def _build_failure_links(self): - """Construct the failure links for Aho-Corasick.""" - queue = deque() - self.fail['root'] = 'root' - - # Initialize failure links for the first level of the trie - for char, node in self.trie['root'].items(): - self.fail[node] = 'root' - queue.append(node) - - # BFS for setting failure links - while queue: - curr_node = queue.popleft() - - for char, next_node in self.trie[curr_node].items(): - queue.append(next_node) - - # Find failure link for current node - fail_node = self.fail[curr_node] - while fail_node != 'root' and char not in self.trie[fail_node]: - fail_node = self.fail[fail_node] - - if char in self.trie[fail_node]: - self.fail[next_node] = self.trie[fail_node][char] - else: - self.fail[next_node] = 'root' - - # Combine output of fail state - self.output[next_node].extend(self.output[self.fail[next_node]]) - - def search(self, text): - """Search for patterns in the given text.""" - node = 'root' - results = [] - - for i, char in enumerate(text): - while node != 'root' and char not in self.trie[node]: - node = self.fail[node] - - if char in self.trie[node]: - node = self.trie[node] - else: - node = 'root' - - # Check if any pattern ends at this character - if self.output[node]: - for pattern in self.output[node]: - results.append((i - len(pattern) + 1, pattern)) - - return results - -# Example usage -patterns = ["he", "she", "his", "hers"] -text = "ushers" -ac = AhoCorasick(patterns) -matches = ac.search(text) -print("Matches found:", matches) -``` - -### C++ - -```cpp -#include -#include -#include -#include -using namespace std; - -class AhoCorasick { - struct Node { - map children; - int fail; - vector output; - }; - - vector trie; - vector patterns; - -public: - AhoCorasick(const vector& patterns) { - trie.push_back(Node()); // Root node - this->patterns = patterns; - build_trie(); - build_failure_links(); - } - - void build_trie() { - for (int idx = 0; idx < patterns.size(); ++idx) { - string pattern = patterns[idx]; - int node = 0; - - for (char ch : pattern) { - if (!trie[node].children.count(ch)) { - trie[node].children[ch] = trie.size(); - trie.push_back(Node()); - } - node = trie[node].children[ch]; - } - trie[node].output.push_back(idx); - } - } - - void build_failure_links() { - queue q; - for (auto& [ch, next_node] : trie[0].children) { - trie[next_node].fail = 0; - q.push(next_node); - } - - while (!q.empty()) { - int curr_node = q.front(); - q.pop(); - - for (auto& [ch, next_node] : trie[curr_node].children) { - int fail = trie[curr_node].fail; - - while (fail != 0 && !trie[fail].children.count(ch)) { - fail = trie[fail].fail; - } - - if (trie[fail].children.count(ch)) { - trie[next_node].fail = trie[fail].children[ch]; - } else { - trie[next_node].fail = 0; - } - - trie[next_node].output.insert(trie[next_node].output.end(), - trie[trie[next_node].fail].output.begin(), - trie[trie[next_node].fail].output.end()); - q.push(next_node); - } - } - } - - vector> search(const string& text) { - int node = 0; - vector> results; - - for (int i = 0; i < text.size(); ++i) { - char ch = text[i]; - - while (node != 0 && !trie[node].children.count(ch)) { - node = trie[node].fail; - } - - if (trie[node].children.count(ch)) { - node = trie[node].children[ch]; - } else { - node = 0; - } - - for (int pattern_idx : trie[node].output) { - results.emplace_back(i - patterns[pattern_idx].size() + 1, patterns[pattern_idx]); - } - } - - return results; - } -}; - -int main() { - vector patterns = {"he", "she", "his", "hers"}; - string text = "ushers"; - - AhoCorasick ac(patterns); - vector> matches = ac.search(text); - - cout << "Matches found:\n"; - for (const auto& [idx, pattern] : matches) { - cout << "Pattern \"" << pattern << "\" found at index " << idx << endl; - } - - return 0; -} -``` - - - -## Advantages - -- **Multiple Pattern Search:** Efficiently searches for multiple patterns in a single pass through the text. -- **Linear Time Complexity:** After preprocessing the patterns, the search runs in linear time relative to the length of the text. -- **Failure Links:** These allow the algorithm to efficiently backtrack and reuse previously computed results when mismatches occur. - -## Applications - -- **Text Search:** Useful in applications such as search engines, text editors, and data mining where multiple patterns need to be searched. -- **Intrusion Detection Systems:** Often used to detect multiple predefined patterns in network traffic. -- **DNA Sequence Analysis:** Helps in finding multiple patterns within genetic sequences. - -## Conclusion - -The **Aho-Corasick Algorithm** is an optimal solution for problems involving multiple pattern matching. Its combination of a trie and failure links ensures that it can handle large datasets and multiple queries efficiently. \ No newline at end of file diff --git a/docs/algorithms/string-algorithm/kmp-algorithm.md b/docs/algorithms/string-algorithm/kmp-algorithm.md deleted file mode 100644 index 09b8e9501..000000000 --- a/docs/algorithms/string-algorithm/kmp-algorithm.md +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: kmp-algorithm -title: "KMP Algorithm" -sidebar_label: "KMP" -sidebar_position: 8 -description: "A comprehensive guide to using the KMP Algorithm for efficient pattern matching." -tags: [pattern matching, string algorithms, competitive programming] ---- - -In computer science, the **KMP (Knuth-Morris-Pratt) Algorithm** is an efficient pattern-matching algorithm that searches for occurrences of a pattern in a text. It achieves linear time complexity by precomputing an auxiliary array called the LPS (Longest Prefix Suffix) array, which helps skip unnecessary comparisons during the search. - - - -## Definition: - -The KMP (Knuth-Morris-Pratt) algorithm is an efficient pattern-matching algorithm that searches for occurrences of a pattern in a text in O(n) time, where `n` is the length of the text. It achieves this by precomputing an auxiliary array called the LPS (Longest Prefix Suffix) array, which is used to skip unnecessary comparisons during the search. - -## Explanation: - -Given a pattern and a text, the KMP algorithm precomputes the LPS array, which stores the length of the longest proper prefix of the pattern that is also a suffix for each position in the pattern. This allows the algorithm to avoid rechecking characters that have already been matched, resulting in efficient string searching. - -### LPS Array: - -The LPS array helps in determining how much the pattern should be shifted without re-evaluating characters that have already been matched. For every mismatch during the search, the LPS array tells how many characters can be skipped. - - - -## Code - -### Code Implementation (Python): - -```python -def calculate_lps(pattern): - """Preprocesses the pattern and computes the LPS array. - - Args: - pattern: The pattern string. - - Returns: - The LPS (Longest Prefix Suffix) array for the given pattern. - """ - lps = [0] * len(pattern) - length = 0 # length of the previous longest prefix suffix - i = 1 - - while i < len(pattern): - if pattern[i] == pattern[length]: - length += 1 - lps[i] = length - i += 1 - else: - if length != 0: - length = lps[length - 1] - else: - lps[i] = 0 - i += 1 - - return lps - - -def kmp_search(pattern, text): - """Performs KMP algorithm for pattern matching. - - Args: - pattern: The pattern to be searched. - text: The text in which the pattern is searched. - - Returns: - A list of starting indices where the pattern is found in the text. - """ - m = len(pattern) - n = len(text) - lps = calculate_lps(pattern) - i = 0 # index for text - j = 0 # index for pattern - result = [] - - while i < n: - if pattern[j] == text[i]: - i += 1 - j += 1 - - if j == m: - result.append(i - j) - j = lps[j - 1] - elif i < n and pattern[j] != text[i]: - if j != 0: - j = lps[j - 1] - else: - i += 1 - - return result -``` - -### Code Implementation (C++): - -```cpp -#include -#include -using namespace std; - -vector calculate_lps(const string& pattern) { - int m = pattern.length(); - vector lps(m); - int length = 0; // length of the previous longest prefix suffix - int i = 1; - - while (i < m) { - if (pattern[i] == pattern[length]) { - length++; - lps[i] = length; - i++; - } else { - if (length != 0) { - length = lps[length - 1]; - } else { - lps[i] = 0; - i++; - } - } - } - - return lps; -} - -vector kmp_search(const string& pattern, const string& text) { - int m = pattern.length(); - int n = text.length(); - vector lps = calculate_lps(pattern); - vector result; - - int i = 0; // index for text - int j = 0; // index for pattern - - while (i < n) { - if (pattern[j] == text[i]) { - i++; - j++; - } - - if (j == m) { - result.push_back(i - j); - j = lps[j - 1]; - } else if (i < n && pattern[j] != text[i]) { - if (j != 0) { - j = lps[j - 1]; - } else { - i++; - } - } - } - - return result; -} - -int main() { - string text = "ABABDABACDABABCABAB"; - string pattern = "ABABCABAB"; - vector result = kmp_search(pattern, text); - - cout << "Pattern found at indices: "; - for (int i : result) { - cout << i << " "; - } - cout << endl; - - return 0; -} -``` - -### Code Implementation (Java): - -```java -import java.util.*; - -public class KMPAlgorithm { - - public static int[] calculate_lps(String pattern) { - int m = pattern.length(); - int[] lps = new int[m]; - int length = 0; - int i = 1; - - while (i < m) { - if (pattern.charAt(i) == pattern.charAt(length)) { - length++; - lps[i] = length; - i++; - } else { - if (length != 0) { - length = lps[length - 1]; - } else { - lps[i] = 0; - i++; - } - } - } - - return lps; - } - - public static List kmp_search(String pattern, String text) { - int m = pattern.length(); - int n = text.length(); - int[] lps = calculate_lps(pattern); - List result = new ArrayList<>(); - - int i = 0; // index for text - int j = 0; // index for pattern - - while (i < n) { - if (pattern.charAt(j) == text.charAt(i)) { - i++; - j++; - } - - if (j == m) { - result.add(i - j); - j = lps[j - 1]; - } else if (i < n && pattern.charAt(j) != text.charAt(i)) { - if (j != 0) { - j = lps[j - 1]; - } else { - i++; - } - } - } - - return result; - } - - public static void main(String[] args) { - String text = "ABABDABACDABABCABAB"; - String pattern = "ABABCABAB"; - List result = kmp_search(pattern, text); - System.out.println("Pattern found at indices: " + result); - } -} -``` -### Code Implementation (JavaScript): - -```javascript -function calculateLPS(pattern) { - const m = pattern.length; - const lps = new Array(m).fill(0); // Longest Prefix Suffix array - let length = 0; // Length of the previous longest prefix suffix - let i = 1; - - while (i < m) { - if (pattern[i] === pattern[length]) { - length++; - lps[i] = length; - i++; - } else { - if (length !== 0) { - length = lps[length - 1]; - } else { - lps[i] = 0; - i++; - } - } - } - - return lps; -} - -function kmpSearch(pattern, text) { - const m = pattern.length; - const n = text.length; - const lps = calculateLPS(pattern); - const result = []; - - let i = 0; // Index for text - let j = 0; // Index for pattern - - while (i < n) { - if (pattern[j] === text[i]) { - i++; - j++; - } - - if (j === m) { - result.push(i - j); // Pattern found at index i - j - j = lps[j - 1]; - } else if (i < n && pattern[j] !== text[i]) { - if (j !== 0) { - j = lps[j - 1]; - } else { - i++; - } - } - } - - return result; -} - -// Example usage -const text = "ABABDABACDABABCABAB"; -const pattern = "ABABCABAB"; -const result = kmpSearch(pattern, text); - -console.log("Pattern found at indices:", result.join(" ")); // Output the indices -``` - - - -## Explanation of the Code: - -- **calculate_lps:** This function computes the LPS array for the given pattern. The LPS array is used to determine the next positions to compare in case of a mismatch. -- **kmp_search:** This function performs the actual KMP search by using the LPS array to skip unnecessary comparisons in the text. It outputs all starting indices where the pattern is found. - -### Example Usage: - -For the text `text = "ABABDABACDABABCABAB"` and pattern `pattern = "ABABCABAB"`, the output will be: -``` -Pattern found at indices: [10] -``` - -## Applications in Competitive Programming - -### Pattern Matching: -The KMP algorithm is widely used in competitive programming due to its efficiency in searching for patterns in a text, making it useful in DNA sequence analysis, data compression, and other text-search problems. - -### String Matching: -KMP helps solve problems where multiple occurrences of a pattern need to be found, avoiding redundant comparisons, which makes it faster than brute-force approaches. - -### Substring Search: -This algorithm is useful in word processors, search engines, and file comparison tools where efficient substring searching is critical. diff --git a/docs/algorithms/string-algorithm/rabin-karp-algorithm.md b/docs/algorithms/string-algorithm/rabin-karp-algorithm.md deleted file mode 100644 index 0a831a62c..000000000 --- a/docs/algorithms/string-algorithm/rabin-karp-algorithm.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: rabin-karp-algorithm -title: "Rabin-Karp Algorithm" -sidebar_label: "Rabin-Karp" -sidebar_position: 7 -description: "A comprehensive guide to using the Rabin-Karp Algorithm for efficient pattern matching." -tags: [pattern matching, string algorithms, competitive programming] ---- - -Robins-Karp Algorithm is a string-searching algorithm that uses hashing to find an exact match of a pattern in a text. By comparing hash values of the pattern with the hash values of substrings of the text, it achieves an average time complexity of O(n + m), where `n` is the length of the text and `m` is the length of the pattern. - - - -## Explanation: - -The algorithm works by computing a hash value for the pattern and each substring of the text of the same length. If the hash values match, the substring and the pattern are compared character by character to confirm the match. This approach works efficiently in practice, especially when using a rolling hash to update the hash value of the substring in constant time. - -## Code Implementation: - - - - - ```python - def rabin_karp(text: str, pattern: str) -> list: - def hash_string(s: str) -> int: - return sum(ord(s[i]) * 101 ** i for i in range(len(s))) - - n, m = len(text), len(pattern) - pattern_hash = hash_string(pattern) - text_hash = hash_string(text[:m]) - indices = [] - - for i in range(n - m + 1): - if pattern_hash == text_hash and text[i:i + m] == pattern: - indices.append(i) - if i < n - m: - text_hash = (text_hash - ord(text[i]) * 101 ** (m - 1)) * 101 + ord(text[i + m]) - - return indices - - # Example Usage - text = "ABCCDABCDABCD" - pattern = "ABCD" - print("Pattern found at indices:", rabin_karp(text, pattern)) - ``` - - - - ```cpp - #include - #include - #include - - std::vector rabin_karp(const std::string& text, const std::string& pattern) { - auto hash_string = [](const std::string& s) -> int { - int hash = 0; - for (size_t i = 0; i < s.size(); ++i) { - hash += s[i] * 101 * i; - } - return hash; - }; - - int n = text.size(), m = pattern.size(); - int pattern_hash = hash_string(pattern); - int text_hash = hash_string(text.substr(0, m)); - std::vector indices; - - for (int i = 0; i <= n - m; ++i) { - if (pattern_hash == text_hash && text.substr(i, m) == pattern) { - indices.push_back(i); - } - if (i < n - m) { - text_hash = (text_hash - text[i] * 101 * (m - 1)) * 101 + text[i + m]; - } - } - - return indices; - } - - // Example Usage - int main() { - std::string text = "ABCCDABCDABCD"; - std::string pattern = "ABCD"; - std::vector indices = rabin_karp(text, pattern); - std::cout << "Pattern found at indices: "; - for (int idx : indices) { - std::cout << idx << " "; - } - return 0; - } - ``` - - - - - - - -## Explanation of the Code: - -- **rabin_karp:** This function implements the Rabin-Karp algorithm, where it computes the hash values for the pattern and substrings of the text. -- The rolling hash technique is used to efficiently update the hash values in constant time while sliding the pattern over the text. -- If the hash values match, a character-by-character comparison is done to confirm the match. - -### Example Usage: - -For the text `text = "ABCCDABCDABCD"` and pattern `pattern = "ABCD"`, the output will be: -``` -Pattern found at indices: [6, 10] -``` - - - -## Applications in Competitive Programming - -### Pattern Matching: -The Rabin-Karp algorithm is efficient for finding multiple occurrences of a pattern in a text, making it suitable for DNA sequence matching, plagiarism detection, and large-scale text search. - -### Rolling Hash: -The rolling hash function allows efficient recomputation of hash values, making this algorithm practical even for long texts and patterns. - -### Substring Search: -It is widely used for finding substrings within large text data, especially in applications like word processors, search engines, and databases. - - - -## Advantages - -- **Linear Time Complexity:** The algorithm has an average-case time complexity of O(n + m), where `n` is the length of the text and `m` is the length of the pattern. -- **Multiple Pattern Search:** It can search for multiple patterns in a single pass through the text. -- **Rolling Hash:** The rolling hash technique allows for efficient updates of hash values in constant time. -- **Space Efficiency:** The algorithm uses a constant amount of space for storing hash values and indices. -- **Simple Implementation:** The algorithm is relatively easy to implement and understand. -- **Robustness:** It can handle large datasets and multiple queries efficiently. -- **Practicality:** Suitable for real-world applications like text search, DNA sequence analysis, and plagiarism detection. -- **Scalability:** Works well with large texts and patterns due to its linear time complexity. - -## Conclusion - -The Rabin-Karp Algorithm is a powerful tool for pattern matching in strings, offering a balance between time complexity and practicality. By leveraging hashing and the rolling hash technique, it efficiently finds occurrences of a pattern in a text, making it a valuable algorithm in competitive programming and real-world applications. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/Naive-String-Matching-Algorithm.md b/docs/algorithms/string-algorithms/Naive-String-Matching-Algorithm.md deleted file mode 100644 index a58d14077..000000000 --- a/docs/algorithms/string-algorithms/Naive-String-Matching-Algorithm.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: naive-string-matching -title: Naive String Matching Algorithm -sidebar_label: Naive String Matching -tags: [String Matching, Naive Approach, Algorithms, DSA] -description: Simple method to find all occurrences of a pattern within a text by comparing each character. ---- - -# Naive String Matching Algorithm - -## Description - -The **Naive String Matching Algorithm** is a straightforward method for finding all occurrences of a pattern (substring) within a given text (string). This algorithm works by checking for the presence of the pattern at each possible position in the text. It does this by comparing characters one by one, making it easy to understand and implement, but it is not the most efficient approach for larger datasets. - -### Problem Definition - -- **Input**: - - A string `txt` of length `n`. - - A pattern `pat` of length `m`. - -- **Output**: - - The starting indices of all occurrences of `pat` in `txt`. - -### Algorithm Overview - -1. **Initialization**: Start from the first character of the text. -2. **Outer Loop**: For each position in the text (from `0` to `n - m`), check if the pattern matches the substring of the text starting at that position. -3. **Inner Loop**: For each character in the pattern, compare it with the corresponding character in the text: - - If a mismatch occurs, break out of the inner loop and move to the next starting position in the text. - - If all characters match, record the starting index of the match. -4. **Continue Searching**: Repeat the process for the next starting position in the text. -5. **Termination**: Continue until the end of the text is reached. - -### Time Complexity - -- The worst-case time complexity is `O(n * m)`, where `n` is the length of the text and `m` is the length of the pattern. This can occur when every character of the text needs to be compared with every character of the pattern (e.g., when the text and pattern are similar). - -### Space Complexity - -- The space complexity is `O(1)` since the algorithm uses a constant amount of space regardless of the input size. - -### C++ Implementation - -```cpp -#include -#include - -using namespace std; - -void naiveStringMatch(const string& txt, const string& pat) { - int n = txt.length(); - int m = pat.length(); - - for (int i = 0; i <= n - m; i++) { - int j; - for (j = 0; j < m; j++) { - if (txt[i + j] != pat[j]) - break; - } - if (j == m) { - cout << "Pattern found at index " << i << endl; - } - } -} - -int main() { - string txt = "AABAACAADAABAAABAA"; - string pat = "AABA"; - naiveStringMatch(txt, pat); - return 0; -} -``` \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/_category_.json b/docs/algorithms/string-algorithms/_category_.json deleted file mode 100644 index d87510339..000000000 --- a/docs/algorithms/string-algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "String Algorithms", - "position": 3, - "link": { - "type": "generated-index", - "description": "Learn about some String Algorithms." - } - } \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/apostolico-giancarlo-algorithm.md b/docs/algorithms/string-algorithms/apostolico-giancarlo-algorithm.md deleted file mode 100644 index a3d51e73f..000000000 --- a/docs/algorithms/string-algorithms/apostolico-giancarlo-algorithm.md +++ /dev/null @@ -1,100 +0,0 @@ ---- - -id: apostolico-giancarlo-algo -sidebar_position: 1 -title: Apostolico–Giancarlo Algorithm -sidebar_label: Apostolico–Giancarlo Algorithm - ---- - -### Definition: - -The Apostolico–Giancarlo algorithm is an advanced string matching algorithm designed for efficient searching of a pattern in a text by minimizing redundant comparisons. It utilizes the knowledge gained from previous mismatches to skip unnecessary character comparisons. - -### Characteristics: - -- **Efficient Skipping**: - - This algorithm reduces the number of comparisons by reusing information about previously matched characters and skipping over sections of text that cannot possibly match the pattern. - -- **Text Scanning**: - - It processes the text in a left-to-right fashion, scanning characters and performing checks to see if the pattern matches. - -- **Optimal Shifts**: - - Apostolico–Giancarlo optimizes the pattern shifting process after mismatches by using suffix information, ensuring fewer comparisons in cases of repeated patterns. - -- **Suboptimal on Small Patterns**: - - While efficient for longer patterns, its performance may not be as significant for smaller ones compared to simpler algorithms like Knuth-Morris-Pratt (KMP). - -### Time Complexity: - -- **Best Case: $O\left(\frac{n}{m}\right)$** - In the best-case scenario, the algorithm performs optimally, making only a fraction of comparisons proportional to the length of the text divided by the length of the pattern. - -- **Average Case: $O(n)$** - On average, the Apostolico–Giancarlo algorithm makes approximately linear scans through the text, resulting in efficient performance for most practical use cases. - -- **Worst Case: $O(n \times m)$** - In the worst case, if the pattern has repeated sections that align poorly with the text, the algorithm could degrade to quadratic time complexity, where `n` is the text length and `m` is the pattern length. - -### Space Complexity: - -- **Space Complexity: $O(m + n)$** - The algorithm requires additional space for storing suffix and shift tables, but the space overhead is linear with respect to both the pattern and the text size. - -### C++ Implementation: - -**Iterative Approach** -```cpp -#include -#include -#include -using namespace std; - -void computeSuffixArray(const string& pattern, vector& suffixArray) { - int m = pattern.length(); - suffixArray[m - 1] = m; - for (int i = m - 2; i >= 0; --i) { - int j = i; - while (j >= 0 && pattern[j] == pattern[m - 1 - (i - j)]) { - --j; - } - suffixArray[i] = i - j; - } -} - -void apostolicoGiancarloSearch(const string& text, const string& pattern) { - int n = text.length(); - int m = pattern.length(); - if (m > n) return; - - vector suffixArray(m); - computeSuffixArray(pattern, suffixArray); - - int i = 0; - while (i <= n - m) { - int j = m - 1; - while (j >= 0 && pattern[j] == text[i + j]) { - --j; - } - if (j < 0) { - cout << "Pattern found at index " << i << endl; - i += suffixArray[0]; // Shift based on the suffix array - } else { - i += max(1, suffixArray[j]); - } - } -} - -int main() { - string text = "ABAAABCDABC"; - string pattern = "ABC"; - - apostolicoGiancarloSearch(text, pattern); - - return 0; -} -``` - -### Summary: - -The Apostolico–Giancarlo algorithm is an advanced string matching algorithm that leverages optimal shifts and pattern reuse to efficiently find patterns within text. Though it offers significant performance advantages for large and repetitive patterns, it is not always the first choice for small or simple patterns. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/berry-ravindran-algorithm.md b/docs/algorithms/string-algorithms/berry-ravindran-algorithm.md deleted file mode 100644 index 0f04d7e6b..000000000 --- a/docs/algorithms/string-algorithms/berry-ravindran-algorithm.md +++ /dev/null @@ -1,276 +0,0 @@ ---- - -id: berry-ravindran-algorithm -sidebar_position: 23 -title: Berry-Ravindran Algorithm -sidebar_label: Berry-Ravindran Algorithm - ---- - -### Definition: - -The Berry-Ravindran Algorithm is an efficient pattern matching algorithm that combines features of the Quick Search and Zhu-Takaoka algorithms. It uses two consecutive characters after the current window to determine shift distances, making it particularly effective for medium to large pattern lengths and alphabets. - -### Characteristics: - -- **Bad Character Rule**: - - Two-character lookup - - Extended shifting strategy - - Efficient skip calculation - -- **Preprocessing Phase**: - - Two-dimensional shift table - - Character pair analysis - - Shift optimization - -- **Right-to-Left Scanning**: - - Pattern comparison - - Efficient shifting - - Quick mismatch detection - -- **Extended Window**: - - Next character examination - - Pair-based shifting - - Optimized jumps - -### Time Complexity: - -- **Preprocessing: $O(m + σ²)$** - - Where m is pattern length - - σ is alphabet size - - Two-dimensional table - -- **Searching: $O(m \times n)$** - - Where n is text length - - Sublinear in practice - - Better average case - -### Space Complexity: - -- **Space Usage: $O(σ²)$** - - Shift table storage - - Two-character indices - - Constant pattern space - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class BerryRavindran { -private: - static const int ALPHABET_SIZE = 256; - - // Compute bad character shift table for two characters - vector> computeShiftTable(const string& pattern) { - int m = pattern.length(); - vector> shiftTable(ALPHABET_SIZE, - vector(ALPHABET_SIZE)); - - // Initialize with maximum shift - for (int i = 0; i < ALPHABET_SIZE; i++) { - for (int j = 0; j < ALPHABET_SIZE; j++) { - shiftTable[i][j] = m + 2; - } - } - - // Fill shift values for pattern characters - for (int i = 0; i <= m - 1; i++) { - // Last character pair gets shift of 1 - if (i == m - 1) { - for (int k = 0; k < ALPHABET_SIZE; k++) { - shiftTable[pattern[i]][k] = 1; - } - continue; - } - - // Other positions get m - i - shiftTable[pattern[i]][pattern[i + 1]] = m - i; - } - - return shiftTable; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocessing - auto shiftTable = computeShiftTable(pattern); - - // Searching phase - int pos = 0; - while (pos <= n - m) { - // Compare pattern with text from right to left - int j = m - 1; - while (j >= 0 && pattern[j] == text[pos + j]) { - j--; - } - - if (j < 0) { - // Pattern found - matches.push_back(pos); - pos++; - } else { - // Calculate shift using two characters after current window - if (pos + m + 1 >= n) { - // End of text reached - break; - } - - unsigned char nextChar1 = text[pos + m]; - unsigned char nextChar2 = text[pos + m + 1]; - pos += shiftTable[nextChar1][nextChar2]; - } - } - - return matches; - } - - // Function to visualize shift table - void printShiftTable(const string& pattern) { - auto shiftTable = computeShiftTable(pattern); - cout << "Shift Table (showing non-default values):" << endl; - - for (int i = 0; i < ALPHABET_SIZE; i++) { - for (int j = 0; j < ALPHABET_SIZE; j++) { - if (shiftTable[i][j] != pattern.length() + 2) { - cout << "(" << (char)i << "," << (char)j << "): " - << shiftTable[i][j] << endl; - } - } - } - } -}; - -// Demonstration class -class BerryRavindranDemo { -public: - static void demonstrateAlgorithm() { - BerryRavindran algo; - - // Example 1: Basic pattern matching - string text = "ABCABCDABABCDABCDABDE"; - string pattern = "ABCDABD"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - vector matches = algo.search(text, pattern); - - cout << "\nPattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Example 2: Show shift table - cout << "\nShift table for pattern '" << pattern << "':" << endl; - algo.printShiftTable(pattern); - - // Example 3: Different pattern - pattern = "AABAAA"; - text = "AABAABAAAABAAA"; - cout << "\nNew Text: " << text << endl; - cout << "New Pattern: " << pattern << endl; - - matches = algo.search(text, pattern); - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - BerryRavindranDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Two-Character Shifts**: - - Enhanced bad character rule - - Pair-based lookup - - Maximum shift calculation - -2. **Efficient Preprocessing**: - - Two-dimensional shift table - - Pattern analysis - - Shift optimization - -3. **Fast Scanning**: - - Right-to-left comparison - - Quick shift decisions - - Optimal skip values - -### Applications: - -1. **Text Processing**: - - Pattern matching - - Text search - - Document analysis - -2. **Information Retrieval**: - - String searching - - Content scanning - - Pattern detection - -3. **Data Analysis**: - - Sequence matching - - Pattern recognition - - Content filtering - -4. **File Systems**: - - File searching - - Content indexing - - Pattern matching - -### Advanced Features: - -1. **Algorithm Variants**: - - Multiple pattern matching - - Case-insensitive matching - - Unicode support - -2. **Implementation Optimizations**: - - Cache-efficient versions - - Memory-efficient variants - - Parallel processing - -### Performance Characteristics: - -1. **Best Case**: - - O(n/m) comparisons - - Large shifts - - Efficient skipping - -2. **Average Case**: - - Sublinear time - - Better than Boyer-Moore - - Efficient for large alphabets - -3. **Worst Case**: - - O(mn) comparisons - - Pattern dependent - - Rare in practice - -### Summary: - -The Berry-Ravindran Algorithm represents an efficient approach to pattern matching by utilizing two-character lookahead for shift calculations. Its combination of features from Quick Search and Zhu-Takaoka algorithms makes it particularly effective for practical applications. - -The algorithm's strength lies in its enhanced shifting strategy, which allows for larger jumps in the text by considering two characters after the current window. The implementation provides both the core functionality and additional features for analysis and visualization. - -The practical applications range from simple text searches to complex pattern matching scenarios. Its improved average-case performance makes it particularly valuable in situations where efficient string matching is crucial, such as in text editors and search engines. - -The algorithm's innovative approach to shift calculation, while requiring additional preprocessing space, provides significant benefits in terms of reduced comparisons and improved average-case performance, making it a valuable addition to the string matching algorithm family. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/bitap-algorithm.md b/docs/algorithms/string-algorithms/bitap-algorithm.md deleted file mode 100644 index fa2d59b5e..000000000 --- a/docs/algorithms/string-algorithms/bitap-algorithm.md +++ /dev/null @@ -1,108 +0,0 @@ ---- - -id: bitap-algo -sidebar_position: 3 -title: Bitap Algorithm -sidebar_label: Bitap Algorithm - ---- - -### Definition: - -The Bitap algorithm, also known as the **Shift-Or**, **Shift-And**, or **Bitap for Approximate String Matching**, is a string matching algorithm that efficiently finds patterns in a text with possible mismatches or errors. The algorithm leverages bitwise operations to perform both exact and approximate string matching, making it ideal for fuzzy searching. - -### Characteristics: - -- **Bitwise Matching**: - - The Bitap algorithm uses bitwise operations to compare the pattern against the text. Each bit represents whether a character in the text matches a position in the pattern. - -- **Approximate Matching**: - - It supports approximate matching, where the pattern may have a certain number of mismatches, insertions, or deletions. This is especially useful in fields like text retrieval or DNA sequence matching. - -- **Pattern Masking**: - - The pattern is preprocessed into bitmasks, which are then used during the text scan to track how much of the pattern has been matched, including the handling of allowed errors. - -- **Linear Search with Errors**: - - The algorithm scans the text linearly, and the number of allowed errors (insertions, deletions, substitutions) is parameterized, allowing for flexible search criteria. - -### Time Complexity: - -- **Best Case: $O\left(\frac{n}{w}\right)$** - The best-case complexity is linear, as the algorithm processes `w` characters in parallel per word size `w` of the machine. - -- **Average Case: $O(n)$** - On average, the algorithm performs in linear time with respect to the text size `n`, especially for small patterns or when only a few errors are allowed. - -- **Worst Case: $O(n \times m)$** - In the worst case, if the pattern is large or if there are many errors allowed, the time complexity can degrade to quadratic, where `m` is the pattern length. - -### Space Complexity: - -- **Space Complexity: $O(m)$** - The algorithm requires space proportional to the pattern length `m` for storing bitmasks, making it efficient in terms of memory usage. - -### C++ Implementation: - -**Approximate Matching with `k` Allowed Errors** -```cpp -#include -#include -#include -using namespace std; - -#define CHAR_SIZE 256 // Extended ASCII - -void preprocessPattern(const string& pattern, vector& patternMask) { - int m = pattern.size(); - for (int i = 0; i < CHAR_SIZE; ++i) { - patternMask[i] = ~0; - } - for (int i = 0; i < m; ++i) { - patternMask[pattern[i]] &= ~(1 << i); - } -} - -void bitapSearch(const string& text, const string& pattern, int maxErrors) { - int n = text.size(); - int m = pattern.size(); - - if (m > n) return; - - vector patternMask(CHAR_SIZE); - preprocessPattern(pattern, patternMask); - - vector R(maxErrors + 1, ~0); - for (int i = 0; i <= maxErrors; ++i) { - R[i] = ~1; // All bits set except the least significant bit - } - - for (int i = 0; i < n; ++i) { - int oldR_jMinus1 = ~0; - for (int j = 0; j <= maxErrors; ++j) { - int temp = R[j]; - R[j] = ((R[j] << 1) | patternMask[text[i]]); - if (j > 0) { - R[j] &= (oldR_jMinus1 << 1) | (R[j - 1] << 1) | oldR_jMinus1; - } - oldR_jMinus1 = temp; - } - if ((R[maxErrors] & (1 << (m - 1))) == 0) { - cout << "Pattern found at index " << i - m + 1 << " with " << maxErrors << " allowed errors." << endl; - } - } -} - -int main() { - string text = "this is a simple example"; - string pattern = "example"; - int maxErrors = 1; // Allow 1 error (insertion, deletion, or substitution) - - bitapSearch(text, pattern, maxErrors); - - return 0; -} -``` - -### Summary: - -The Bitap algorithm is a highly efficient string matching technique that supports approximate matching, making it ideal for applications requiring fuzzy search capabilities. Its use of bitwise operations allows for fast text scanning, while its flexibility in handling errors sets it apart from other exact matching algorithms. Despite its quadratic worst-case complexity, it performs well for small patterns and a limited number of errors. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/bndm-algorithm.md b/docs/algorithms/string-algorithms/bndm-algorithm.md deleted file mode 100644 index 1401ec716..000000000 --- a/docs/algorithms/string-algorithms/bndm-algorithm.md +++ /dev/null @@ -1,108 +0,0 @@ ---- - -id: bndm-algo -sidebar_position: 2 -title: BNDM Algorithm -sidebar_label: BNDM Algorithm - ---- - -### Definition: - -The BNDM (Backward Nondeterministic Dawg Matching) algorithm is an efficient string matching algorithm derived from the Backward Dawg Matching (BDM) algorithm. It uses bitwise operations to simulate a nondeterministic automaton, matching the pattern in reverse order while scanning the text. - -### Characteristics: - -- **Bitwise Automaton Simulation**: - - BNDM represents the search pattern as a bitmask and simulates a nondeterministic automaton using bitwise operations. This reduces the number of character comparisons and enables efficient pattern matching. - -- **Reverse Pattern Matching**: - - The algorithm scans the pattern in reverse, comparing it against the text from right to left, which helps in faster identification of mismatches and skips. - -- **Efficient for Short Patterns**: - - BNDM is particularly efficient for short patterns, often outperforming other string matching algorithms like Boyer-Moore and Knuth-Morris-Pratt for small pattern sizes. - -- **Extension of BDM**: - - It improves upon the BDM algorithm by handling more general cases and providing better performance for non-trivial patterns. - -### Time Complexity: - -- **Best Case: $O\left(\frac{n}{w}\right)$** - In the best-case scenario, where `w` is the word size of the machine, the algorithm takes advantage of the word-level parallelism and makes few character comparisons. - -- **Average Case: $O(n)$** - On average, BNDM performs linear scans through the text, making it highly efficient for typical use cases, especially with short patterns. - -- **Worst Case: $O(n \times m)$** - In the worst case, when the text and pattern have poor alignment, BNDM may require multiple full scans of the text, leading to quadratic complexity, where `n` is the text length and `m` is the pattern length. - -### Space Complexity: - -- **Space Complexity: $O(m)$** - The space complexity of BNDM is linear with respect to the pattern length, as the algorithm stores bitmasks and tables based on the pattern. - -### C++ Implementation: - -**Iterative Approach** -```cpp -#include -#include -#include -using namespace std; - -#define CHAR_SIZE 256 // Assuming extended ASCII - -void preprocessPattern(const string& pattern, vector& B) { - int m = pattern.length(); - for (int i = 0; i < CHAR_SIZE; ++i) { - B[i] = 0; - } - for (int i = 0; i < m; ++i) { - B[pattern[i]] |= (1 << i); - } -} - -void BNDMSearch(const string& text, const string& pattern) { - int n = text.length(); - int m = pattern.length(); - - if (m > n) return; - - vector B(CHAR_SIZE); - preprocessPattern(pattern, B); - - for (int i = 0; i <= n - m; ) { - int j = m - 1; - int mask = (1 << j); - int D = -1; // Bit mask for the current window - - while (D && j >= 0) { - D &= B[text[i + j]]; - if (D) { - --j; - D <<= 1; - } - } - - if (j < 0) { - cout << "Pattern found at index " << i << endl; - } - - // Shift the window based on the number of bits set in D - i += (m - __builtin_ctz(D)); - } -} - -int main() { - string text = "ABCABCABCD"; - string pattern = "ABC"; - - BNDMSearch(text, pattern); - - return 0; -} -``` - -### Summary: - -The BNDM (Backward Nondeterministic Dawg Matching) algorithm is an efficient and powerful string matching technique, especially for small patterns. It leverages bitwise operations and reverse pattern matching to minimize unnecessary character comparisons, making it highly suitable for short strings and quick searches. Its linear time complexity in average cases makes it a solid choice for string matching tasks in practical applications. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/boyer-moore-algorithm.md b/docs/algorithms/string-algorithms/boyer-moore-algorithm.md deleted file mode 100644 index 6f8080d2d..000000000 --- a/docs/algorithms/string-algorithms/boyer-moore-algorithm.md +++ /dev/null @@ -1,290 +0,0 @@ ---- - -id: boyer-moore-algorithm -sidebar_position: 12 -title: Boyer-Moore Algorithm -sidebar_label: Boyer-Moore Algorithm - ---- - -### Definition: - -The Boyer-Moore Algorithm is a highly efficient string searching algorithm developed by Robert S. Boyer and J Strother Moore in 1977. It is considered one of the most efficient string matching algorithms in practice, particularly for large alphabets and long patterns. The algorithm scans the characters of the pattern from right to left and can skip portions of the text, making it sublinear in many cases. - -### Characteristics: - -- **Bad Character Rule**: - - Uses character-based shifting - - Skips characters not in pattern - - Efficient for large alphabets - -- **Good Suffix Rule**: - - Utilizes previously matched suffixes - - Enables larger shifts - - Complements bad character rule - -- **Preprocessing Phase**: - - Builds bad character table - - Constructs good suffix table - - Prepares for efficient shifts - -- **Right-to-Left Scanning**: - - Examines pattern from right to left - - Enables larger jumps in text - - Improves average-case performance - -### Time Complexity: - -- **Preprocessing: $O(m + σ)$** - - Where m is pattern length - - σ is alphabet size - - One-time computation - -- **Searching: $O(m \times n)$** - - Where n is text length - - Best case: O(n/m) - - Average case: O(n/m) - -### Space Complexity: - -- **Space Usage: $O(m + σ)$** - - Bad character table - - Good suffix table - - Pattern storage - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class BoyerMooreAlgorithm { -private: - static const int ALPHABET_SIZE = 256; - - // Compute the bad character table - void computeBadChar(const string& pattern, - vector& badChar) { - int m = pattern.length(); - - // Initialize table with -1 - fill(badChar.begin(), badChar.end(), -1); - - // Fill the actual bad character occurrences - for (int i = 0; i < m; i++) { - badChar[pattern[i]] = i; - } - } - - // Compute the good suffix table - void computeGoodSuffix(const string& pattern, - vector& goodSuffix) { - int m = pattern.length(); - vector suffix(m); - - // Compute suffix array - computeSuffixArray(pattern, suffix); - - // Initialize with m (pattern length) - fill(goodSuffix.begin(), goodSuffix.end(), m); - - // Case 1: matching suffixes - for (int i = m - 1; i >= 0; i--) { - if (suffix[i] == i + 1) { - for (int j = 0; j < m - 1 - i; j++) { - if (goodSuffix[j] == m) { - goodSuffix[j] = m - 1 - i; - } - } - } - } - - // Case 2: matching prefixes - for (int i = 0; i < m - 1; i++) { - goodSuffix[m - 1 - suffix[i]] = m - 1 - i; - } - } - - // Compute suffix array for good suffix rule - void computeSuffixArray(const string& pattern, - vector& suffix) { - int m = pattern.length(); - - suffix[m - 1] = m; - int g = m - 1; - int f = 0; - - for (int i = m - 2; i >= 0; i--) { - if (i > g && suffix[i + m - 1 - f] < i - g) { - suffix[i] = suffix[i + m - 1 - f]; - } else { - if (i < g) { - g = i; - } - f = i; - while (g >= 0 && pattern[g] == pattern[g + m - 1 - f]) { - g--; - } - suffix[i] = f - g; - } - } - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocessing - vector badChar(ALPHABET_SIZE); - vector goodSuffix(m); - - computeBadChar(pattern, badChar); - computeGoodSuffix(pattern, goodSuffix); - - // Searching phase - int s = 0; // shift - while (s <= n - m) { - int j = m - 1; - - // Match pattern from right to left - while (j >= 0 && pattern[j] == text[s + j]) { - j--; - } - - if (j < 0) { - // Pattern found - matches.push_back(s); - s += goodSuffix[0]; - } else { - // Calculate shift using both rules - int shift1 = j - badChar[text[s + j]]; - int shift2 = goodSuffix[j]; - s += max(1, max(shift1, shift2)); - } - } - - return matches; - } -}; - -// Demonstration class -class BoyerMooreDemo { -public: - static void demonstrateSearch() { - BoyerMooreAlgorithm algo; - string text = "ABAAABCDAABACABAABAAB"; - string pattern = "AABACAB"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - vector matches = algo.search(text, pattern); - - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - BoyerMooreDemo::demonstrateSearch(); - return 0; -} -``` - -### Key Features: - -1. **Bad Character Rule**: - - Rightmost occurrence lookup - - Character-based shifting - - Alphabet-dependent performance - -2. **Good Suffix Rule**: - - Suffix-based pattern matching - - Prefix-suffix relationships - - Optimized shifting strategy - -3. **Optimization Techniques**: - - Combined shift rules - - Efficient preprocessing - - Skip character optimization - -### Applications: - -1. **Text Processing**: - - Text editors - - Word processors - - Search utilities - -2. **Bioinformatics**: - - DNA sequence matching - - Protein pattern search - - Genomic analysis - -3. **Network Security**: - - Deep packet inspection - - Pattern matching - - Intrusion detection - -4. **Information Retrieval**: - - Search engines - - Document scanning - - Content filtering - -### Advanced Features: - -1. **Algorithm Variants**: - - Turbo Boyer-Moore - - Tuned Boyer-Moore - - Extended Boyer-Moore - -2. **Implementation Optimizations**: - - Cache-efficient versions - - Vectorized implementations - - Memory-optimized variants - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Sublinear average case - - Excellent practical performance - - Better for longer patterns - -2. **Trade-offs**: - - Complex preprocessing - - Higher space requirements - - Implementation complexity - -### Performance Characteristics: - -1. **Best Case**: - - O(n/m) comparisons - - Large character skips - - Non-matching suffixes - -2. **Average Case**: - - O(n/m) expected time - - Better than linear - - Practical efficiency - -3. **Worst Case**: - - O(mn) theoretical bound - - Rare in practice - - Still performs well - -### Summary: - -The Boyer-Moore Algorithm stands as one of the most efficient string matching algorithms in practical applications. Its innovative approach of scanning patterns from right to left, combined with two powerful shifting rules (bad character and good suffix), enables it to skip large portions of the text during the search process. - -The algorithm's efficiency stems from its ability to use preprocessing information about both individual characters and pattern suffixes to make intelligent decisions about how far to shift the pattern when a mismatch occurs. While the preprocessing phase and implementation are more complex compared to simpler algorithms, the superior searching performance, especially for longer patterns and larger alphabets, makes it a preferred choice in many real-world applications. - -The implementation provides a robust foundation for text processing tasks, with the flexibility to be optimized for specific use cases through various available variants and optimizations. Despite its theoretical worst-case complexity, Boyer-Moore consistently demonstrates excellent practical performance, making it a cornerstone algorithm in string matching applications. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/colussi-algorithm.md b/docs/algorithms/string-algorithms/colussi-algorithm.md deleted file mode 100644 index ef2aa05d2..000000000 --- a/docs/algorithms/string-algorithms/colussi-algorithm.md +++ /dev/null @@ -1,357 +0,0 @@ ---- - -id: colussi-algorithm -sidebar_position: 27 -title: Colussi Algorithm -sidebar_label: Colussi Algorithm - ---- - -### Definition: - -The Colussi Algorithm is an improvement over the Knuth-Morris-Pratt (KMP) algorithm that reduces the number of character comparisons. It divides pattern positions into two classes and uses a two-phase pattern scanning approach, leading to more efficient pattern matching by optimizing the order of character comparisons. - -### Characteristics: - -- **Two-Phase Scanning**: - - Position classification - - Optimized comparison order - - Reduced comparisons - -- **Pattern Analysis**: - - Position categorization - - Jump table computation - - Efficient preprocessing - -- **Enhanced Failure Function**: - - Advanced shift calculation - - Improved skip values - - Optimized backtracking - -- **Efficient Processing**: - - Reduced comparisons - - Smart position handling - - Quick mismatch detection - -### Time Complexity: - -- **Preprocessing: $O(m)$** - - Where m is pattern length - - Pattern analysis - - Table construction - -- **Searching: $O(n)$** - - Where n is text length - - Reduced comparisons - - Linear scan - -### Space Complexity: - -- **Space Usage: $O(m)$** - - Position tables - - Jump information - - Pattern data - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -class ColussiAlgorithm { -private: - struct PreprocessData { - vector jump; // Jump table - vector pos; // Position classification - vector next; // Next position to check - vector shift; // Shift values - }; - - // Preprocess pattern for efficient matching - PreprocessData preprocess(const string& pattern) { - int m = pattern.length(); - PreprocessData data; - data.jump.resize(m + 1, 0); - data.pos.resize(m, false); - data.next.resize(m, 0); - data.shift.resize(m + 1, 0); - - // Classify positions - for (int i = 0; i < m; i++) { - data.pos[i] = (i == 0 || pattern[i] != pattern[i-1]); - } - - // Compute jump table - int lastPos = -1; - for (int i = 0; i < m; i++) { - if (data.pos[i]) { - if (lastPos >= 0) { - data.next[lastPos] = i; - } - lastPos = i; - } - data.jump[i + 1] = lastPos; - } - - // Compute shift table - for (int i = 0; i < m; i++) { - if (data.pos[i]) { - int j = i; - while (j > 0 && !data.pos[j-1]) { - j--; - } - data.shift[i] = i - j; - } - } - - return data; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocessing - PreprocessData data = preprocess(pattern); - - // Searching phase - int i = 0; // text position - while (i <= n - m) { - int j = 0; // pattern position - bool matched = true; - - // First phase: check classified positions - while (j < m) { - if (data.pos[j]) { - if (text[i + j] != pattern[j]) { - matched = false; - break; - } - j = data.next[j]; - } else { - j++; - } - } - - if (matched) { - // Second phase: verify remaining positions - j = 0; - bool fullMatch = true; - while (j < m) { - if (!data.pos[j] && text[i + j] != pattern[j]) { - fullMatch = false; - break; - } - j++; - } - - if (fullMatch) { - matches.push_back(i); - } - } - - // Calculate shift - if (j == 0) { - i++; - } else { - i += data.shift[j]; - } - } - - return matches; - } - - // Enhanced search with additional optimizations - vector advancedSearch(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocessing - PreprocessData data = preprocess(pattern); - - // Character occurrence map - vector patternChars(256, false); - for (char c : pattern) { - patternChars[c] = true; - } - - // Searching with optimizations - int i = 0; - while (i <= n - m) { - // Quick character check - if (!patternChars[text[i]]) { - i++; - continue; - } - - int j = 0; - bool matched = true; - - // Two-phase scanning with early termination - for (j = 0; j < m && matched; j++) { - if (data.pos[j]) { - if (text[i + j] != pattern[j]) { - matched = false; - } - } - } - - if (matched) { - // Verify remaining positions - bool fullMatch = true; - for (j = 0; j < m; j++) { - if (!data.pos[j] && text[i + j] != pattern[j]) { - fullMatch = false; - break; - } - } - - if (fullMatch) { - matches.push_back(i); - } - } - - // Optimized shift calculation - i += matched ? 1 : max(1, data.shift[j]); - } - - return matches; - } -}; - -// Demonstration class -class ColussiDemo { -public: - static void demonstrateAlgorithm() { - ColussiAlgorithm algo; - - // Example 1: Basic pattern matching - string text = "AABAACAADAABAAABAA"; - string pattern = "AABAA"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - // Basic search - vector matches = algo.search(text, pattern); - cout << "\nBasic search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Advanced search - matches = algo.advancedSearch(text, pattern); - cout << "Advanced search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Example 2: Different pattern - text = "ABCABCDABABCDABCDABDE"; - pattern = "ABCDABD"; - cout << "\nText: " << text << endl; - cout << "Pattern: " << pattern << endl; - - matches = algo.advancedSearch(text, pattern); - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - ColussiDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Position Classification**: - - Two-phase scanning - - Optimized comparison order - - Smart position selection - -2. **Enhanced Processing**: - - Reduced comparisons - - Efficient shift calculation - - Quick mismatch detection - -3. **Advanced Optimization**: - - Character filtering - - Early termination - - Smart shifting - -### Applications: - -1. **Text Processing**: - - Pattern matching - - Text search - - Content analysis - -2. **String Analysis**: - - Pattern detection - - Content filtering - - Text verification - -3. **Data Processing**: - - String matching - - Pattern recognition - - Content searching - -4. **Performance-Critical Systems**: - - Real-time searching - - Efficient matching - - Fast text processing - -### Advanced Features: - -1. **Algorithm Variants**: - - Enhanced position classification - - Multiple pattern support - - Optimized scanning - -2. **Implementation Optimizations**: - - Character filtering - - Early termination - - Efficient shifting - -### Performance Characteristics: - -1. **Best Case**: - - O(n/m) comparisons - - Quick pattern detection - - Efficient skipping - -2. **Average Case**: - - Better than KMP - - Reduced comparisons - - Efficient processing - -3. **Worst Case**: - - O(n) comparisons - - Linear time guarantee - - Optimal performance - -### Summary: - -The Colussi Algorithm represents a significant improvement over the KMP algorithm by introducing position classification and two-phase scanning. Its innovative approach to pattern matching reduces the number of character comparisons while maintaining linear time complexity. - -The algorithm's strength lies in its ability to optimize the order of character comparisons through intelligent position classification and enhanced shift calculations. The implementation provides both basic and advanced features for efficient pattern matching. - -The practical applications of this algorithm extend to various text processing scenarios where performance is critical. Its reduced number of comparisons makes it particularly valuable in situations requiring efficient string matching. - -The algorithm's combination of theoretical improvements and practical optimizations makes it a powerful choice for pattern matching tasks, especially in performance-critical applications where reducing the number of comparisons is essential. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/commentz-walter-algorithm.md b/docs/algorithms/string-algorithms/commentz-walter-algorithm.md deleted file mode 100644 index de2b204b6..000000000 --- a/docs/algorithms/string-algorithms/commentz-walter-algorithm.md +++ /dev/null @@ -1,121 +0,0 @@ ---- - -id: commentz-walter-algo -sidebar_position: 4 -title: Commentz-Walter Algorithm -sidebar_label: Commentz-Walter Algorithm - ---- - -### Definition: - -The Commentz-Walter algorithm is an efficient string matching algorithm that combines the ideas of the Boyer-Moore algorithm and the Aho-Corasick algorithm. It is designed for multi-pattern matching, making it useful when searching for multiple patterns within a large text. By employing efficient pattern shifts and automaton-based techniques, it minimizes unnecessary comparisons. - -### Characteristics: - -- **Multi-Pattern Matching**: - - The algorithm can handle multiple search patterns simultaneously, unlike other algorithms that focus on matching a single pattern. It builds an automaton for multiple patterns, enabling fast searching. - -- **Backward Matching**: - - Like the Boyer-Moore algorithm, the Commentz-Walter algorithm compares the pattern with the text from right to left, allowing it to skip over portions of the text when mismatches occur. - -- **Efficient Shift Table**: - - It utilizes a shift table, much like Boyer-Moore, to determine how far to skip when a mismatch occurs, improving the performance compared to simpler algorithms. - -- **Combines Automaton and Heuristic Approaches**: - - The algorithm uses an automaton (like in Aho-Corasick) to quickly match prefixes of the patterns and applies the Boyer-Moore heuristic to skip sections of the text, resulting in a powerful combination. - -### Time Complexity: - -- **Best Case: $O\left(\frac{n}{m}\right)$** - In the best case, the algorithm achieves sublinear performance due to the pattern skipping mechanism, where `n` is the text length and `m` is the minimum length of the patterns. - -- **Average Case: $O(n)$** - On average, the Commentz-Walter algorithm processes the text in linear time, making it highly efficient for most practical scenarios involving multiple patterns. - -- **Worst Case: $O(n \times m)$** - The worst-case complexity occurs when the text and patterns have poor alignment, leading to more comparisons and resulting in quadratic time complexity. - -### Space Complexity: - -- **Space Complexity: $O(m)$** - The space complexity is linear with respect to the total length of the patterns, as the algorithm stores shift tables and automata structures for efficient pattern matching. - -### C++ Implementation: - -**Iterative Approach for Multi-Pattern Matching** -```cpp -#include -#include -#include -#include -using namespace std; - -#define CHAR_SIZE 256 // Extended ASCII - -// Preprocessing the pattern for building the bad character shift table -void preprocessBadCharacterShift(const vector& patterns, unordered_map& badCharShift, int maxPatternLength) { - for (int i = 0; i < CHAR_SIZE; ++i) { - badCharShift[i] = maxPatternLength; // Default shift is the length of the longest pattern - } - for (const auto& pattern : patterns) { - for (int i = 0; i < pattern.size(); ++i) { - badCharShift[pattern[i]] = maxPatternLength - i - 1; - } - } -} - -// Commentz-Walter Algorithm -void commentzWalterSearch(const string& text, const vector& patterns) { - int n = text.size(); - int maxPatternLength = 0; - - // Find the maximum length of all patterns - for (const auto& pattern : patterns) { - maxPatternLength = max(maxPatternLength, (int)pattern.size()); - } - - // Preprocess bad character shift - unordered_map badCharShift; - preprocessBadCharacterShift(patterns, badCharShift, maxPatternLength); - - int i = 0; - while (i <= n - maxPatternLength) { - bool matched = false; - - // Compare all patterns in reverse order - for (const auto& pattern : patterns) { - int m = pattern.size(); - int j = m - 1; - - while (j >= 0 && pattern[j] == text[i + j]) { - --j; - } - - if (j < 0) { - cout << "Pattern \"" << pattern << "\" found at index " << i << endl; - matched = true; - } - } - - if (!matched) { - i += badCharShift[text[i + maxPatternLength - 1]]; // Shift based on the bad character rule - } else { - i += maxPatternLength; // Shift by the full length if matched - } - } -} - -int main() { - string text = "ABCABCABCDABC"; - vector patterns = {"ABC", "ABCD"}; - - commentzWalterSearch(text, patterns); - - return 0; -} -``` - -### Summary: - -The Commentz-Walter algorithm is a hybrid string matching technique that efficiently handles multiple patterns by combining the strengths of the Boyer-Moore heuristic and the Aho-Corasick automaton. It performs well in scenarios requiring the simultaneous search for multiple patterns within a large text. While its worst-case performance can be quadratic, its average case is linear, making it highly effective for practical applications. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/crochemores-algorithm.md b/docs/algorithms/string-algorithms/crochemores-algorithm.md deleted file mode 100644 index 940ee2f11..000000000 --- a/docs/algorithms/string-algorithms/crochemores-algorithm.md +++ /dev/null @@ -1,284 +0,0 @@ ---- - -id: crochemores-algorithm -sidebar_position: 9 -title: Crochemore's Algorithm -sidebar_label: Crochemore's Algorithm - ---- - -### Definition: - -Crochemore's Algorithm is a string matching algorithm developed by Maxime Crochemore that uses pattern periodicity properties to achieve efficient pattern matching. It's particularly notable for its optimal worst-case time complexity and its ability to handle periodic patterns efficiently. - -### Characteristics: - -- **Periodicity-Based Approach**: - - Exploits pattern periodicity for efficient matching - - Uses period-based shifts for pattern advancement - - Optimizes matching for repetitive patterns - -- **Border Analysis**: - - Computes pattern borders during preprocessing - - Uses border information for shift calculations - - Efficiently handles overlapping matches - -- **Memory Efficiency**: - - Requires minimal additional space - - In-place processing where possible - - Efficient handling of pattern information - -- **Optimal Complexity**: - - Achieves optimal worst-case time complexity - - Efficient for both periodic and non-periodic patterns - - Balanced preprocessing and searching phases - -### Time Complexity: - -- **Preprocessing: $O(m)$** - - Where m is the pattern length - - Includes border computation - - Period analysis of the pattern - -- **Searching: $O(n)$** - - Where n is the text length - - Linear time worst-case complexity - - Optimal for single pattern matching - -### Space Complexity: - -- **Space Usage: $O(m)$** - - Constant extra space beyond pattern storage - - Border information storage - - Period information maintenance - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -class CrochemoreAlgorithm { -private: - // Compute the border array for the pattern - vector computeBorder(const string& pattern) { - int m = pattern.length(); - vector border(m + 1, -1); - border[0] = -1; - - for (int i = 1; i <= m; i++) { - int b = border[i - 1]; - while (b >= 0 && pattern[b] != pattern[i - 1]) { - b = border[b]; - } - border[i] = b + 1; - } - return border; - } - - // Compute the period array - vector computePeriod(const string& pattern, const vector& border) { - int m = pattern.length(); - vector period(m + 1); - - for (int i = 1; i <= m; i++) { - if (border[i] > 0 && - pattern[border[i] - 1] != pattern[i - 1]) { - period[i] = i - border[i]; - } else { - period[i] = period[i - 1]; - } - } - return period; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0) return matches; - - // Preprocessing - vector border = computeBorder(pattern); - vector period = computePeriod(pattern, border); - - // Searching phase - int i = 0; // text position - int j = 0; // pattern position - - while (i <= n - m) { - while (j < m && pattern[j] == text[i + j]) { - j++; - } - - if (j == m) { - matches.push_back(i); - j = border[j]; - } - - if (j == 0) { - i++; - } else { - // Use period information for shifting - int shift = j - border[j]; - i += shift; - j = border[j]; - } - } - - return matches; - } - - // Advanced variant with critical factorization - vector searchWithCriticalFactorization(const string& text, - const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0) return matches; - - // Preprocessing - vector border = computeBorder(pattern); - vector period = computePeriod(pattern, border); - - // Find critical position - int critical = m / 2; // Simplified critical factorization - - // Searching with critical factorization - int i = 0; - while (i <= n - m) { - // Match forward from critical position - int j = critical; - while (j < m && pattern[j] == text[i + j]) { - j++; - } - - if (j == m) { - // Match backward from critical position - j = critical - 1; - while (j >= 0 && pattern[j] == text[i + j]) { - j--; - } - - if (j < 0) { - matches.push_back(i); - } - } - - // Compute shift using period information - int shift = max(1, j - border[j]); - i += shift; - } - - return matches; - } -}; - -// Demonstration class -class CrochemoreDemo { -public: - static void demonstrateSearch() { - CrochemoreAlgorithm algo; - string text = "ABABCABABABCABAB"; - string pattern = "ABABC"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - // Basic search - vector matches = algo.search(text, pattern); - cout << "Basic Search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Search with critical factorization - matches = algo.searchWithCriticalFactorization(text, pattern); - cout << "Critical Factorization Search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - CrochemoreDemo::demonstrateSearch(); - return 0; -} -``` - -### Key Features: - -1. **Pattern Analysis**: - - Border computation - - Period calculation - - Critical factorization - -2. **Matching Strategy**: - - Period-based shifting - - Border-based matching - - Efficient skip mechanism - -3. **Optimization Techniques**: - - Critical factorization - - Period-based shifts - - Border information usage - -### Applications: - -1. **Text Processing**: - - Pattern matching - - Text search systems - - Document processing - -2. **Bioinformatics**: - - DNA sequence analysis - - Protein pattern matching - - Genome sequencing - -3. **Data Analysis**: - - Pattern recognition - - Data mining - - Sequence analysis - -4. **String Processing**: - - Compiler design - - Text editors - - Search engines - -### Advanced Features: - -1. **Algorithm Variants**: - - Critical factorization version - - Multiple pattern matching - - Approximate matching - -2. **Implementation Optimizations**: - - Cache-efficient variants - - SIMD implementations - - Parallel processing - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Optimal worst-case complexity - - Efficient for periodic patterns - - Minimal space requirements - -2. **Trade-offs**: - - Complex implementation - - Preprocessing overhead - - Critical factorization computation - -### Summary: - -Crochemore's Algorithm represents a sophisticated approach to string matching that combines theoretical optimality with practical efficiency. Its use of pattern periodicity and border information makes it particularly effective for patterns with repetitive structures. The algorithm's optimal worst-case time complexity and efficient space usage make it suitable for applications where predictable performance is crucial. - -The implementation provides two variants: a basic version and an advanced version using critical factorization. Both versions demonstrate the algorithm's key features of period-based shifting and border-based matching. The algorithm's ability to handle periodic patterns efficiently and its optimal complexity characteristics make it a valuable tool in string matching applications, particularly where patterns may have repetitive structures. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/finite-state-automation-algorithm.md b/docs/algorithms/string-algorithms/finite-state-automation-algorithm.md deleted file mode 100644 index fbd9b5a0e..000000000 --- a/docs/algorithms/string-algorithms/finite-state-automation-algorithm.md +++ /dev/null @@ -1,148 +0,0 @@ ---- - -id: finite-state-automaton -sidebar_position: 6 -title: Finite State Automaton Algorithm -sidebar_label: Finite State Automaton Algorithm - ---- - -### Definition: - -The Finite State Automaton (FSA) algorithm is a string matching technique that constructs a mathematical model of states to perform pattern searching. It builds a state machine from the pattern, where each state represents a prefix of the pattern matched so far. The algorithm then processes the text character by character, transitioning between states to identify matches. - -### Characteristics: - -- **State-Based Matching**: - - The FSA algorithm constructs a deterministic finite automaton (DFA) where states represent the longest prefix of the pattern matched at any point. - - Each state transition is determined by the next character in the input text. - -- **Preprocessing Phase**: - - Creates a transition table that determines state transitions for each possible character. - - Pre-computation allows for efficient text processing. - -- **Exact Matching**: - - Designed for exact pattern matching, finding all occurrences of the pattern in the text. - - No approximate matching or wildcards are supported in the basic version. - -- **Memory Efficient Processing**: - - Once the automaton is constructed, text processing requires minimal additional memory. - - Each character is processed exactly once without backtracking. - -### Time Complexity: - -- **Preprocessing: $O(m|Σ|)$** - - Where m is the pattern length and |Σ| is the size of the alphabet. - - Building the transition table requires computing transitions for each state and character. - -- **Pattern Matching: $O(n)$** - - Where n is the text length. - - Linear time processing of the text, examining each character exactly once. - -### Space Complexity: - -- **Space Complexity: $O(m|Σ|)$** - - Storage required for the transition table, where m is the pattern length and |Σ| is the alphabet size. - - Each state needs transitions defined for every possible character. - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -#define CHAR_SIZE 256 // Extended ASCII - -class FiniteAutomaton { -private: - vector> transitionTable; - int patternLength; - - // Compute prefix function for pattern - int getNextState(string& pattern, int state, char x) { - if (state < patternLength && x == pattern[state]) - return state + 1; - - for (int ns = state; ns > 0; ns--) { - if (pattern[ns-1] == x) { - int i; - for (i = 0; i < ns-1; i++) - if (pattern[i] != pattern[state-ns+1+i]) - break; - if (i == ns-1) - return ns; - } - } - return 0; - } - -public: - // Constructor to build the automaton - FiniteAutomaton(string& pattern) { - patternLength = pattern.length(); - transitionTable.resize(patternLength + 1, vector(CHAR_SIZE)); - - // Build transition table - for (int state = 0; state <= patternLength; state++) { - for (int x = 0; x < CHAR_SIZE; x++) { - transitionTable[state][x] = getNextState(pattern, state, x); - } - } - } - - // Search pattern in text - void search(string& text) { - int state = 0; - int n = text.length(); - - for (int i = 0; i < n; i++) { - state = transitionTable[state][text[i]]; - if (state == patternLength) { - cout << "Pattern found at index: " - << i - patternLength + 1 << endl; - } - } - } -}; - -int main() { - string text = "AABAACAADAABAAABAA"; - string pattern = "AABA"; - - FiniteAutomaton fa(pattern); - fa.search(text); - - return 0; -} -``` - -### Key Features: - -1. **Pattern Preprocessing**: - - Constructs a complete state machine before text processing begins - - Computes all possible transitions for each state - - Handles pattern structure analysis efficiently - -2. **State Transitions**: - - Each state represents a partial match of the pattern - - Transitions are deterministic and pre-computed - - No backtracking required during text processing - -3. **Failure Functions**: - - Handles cases where partial matches fail - - Efficiently moves to the next possible matching state - - Optimizes the matching process for repeated patterns - -### Applications: - -- Text editors and word processors -- Network intrusion detection systems -- DNA sequence analysis -- Compiler lexical analysis -- Pattern matching in large datasets - -### Summary: - -The Finite State Automaton algorithm represents a powerful approach to string matching by utilizing state machines. Its preprocessing phase creates a comprehensive transition table that enables efficient text processing. While the initial preprocessing cost can be significant, especially for large alphabets, the linear-time text processing makes it highly efficient for scenarios where the same pattern is searched multiple times in different texts. The algorithm's deterministic nature and lack of backtracking make it particularly suitable for real-time applications and systems where predictable performance is crucial. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/kmp-algorithm.md b/docs/algorithms/string-algorithms/kmp-algorithm.md deleted file mode 100644 index 44ef01860..000000000 --- a/docs/algorithms/string-algorithms/kmp-algorithm.md +++ /dev/null @@ -1,400 +0,0 @@ ---- - -id: knuth-morris-pratt-algorithm -sidebar_position: 11 -title: Knuth-Morris-Pratt Algorithm -sidebar_label: Knuth-Morris-Pratt Algorithm - ---- - -### Definition: - -The Knuth-Morris-Pratt (KMP) Algorithm is a string matching algorithm developed by Donald Knuth, James H. Morris, and Vaughan Pratt. It improves upon naive string matching by utilizing information about previous character matches to avoid unnecessary comparisons, making it particularly efficient for patterns containing repeating subsequences. - -### Example with Explanation - -Consider a scenario where we have the following: - -- **Text**: `ABABDABACDABABCABAB` -- **Pattern**: `ABABCABAB` - -The goal of the KMP algorithm is to efficiently find all occurrences of the pattern in the text by using a precomputed "failure function." - -## 1. Failure Function (Partial Match Table) - -For the given pattern, the KMP algorithm builds a failure function (also called the partial match table) to help track the longest prefix that is also a suffix up to each position in the pattern. The failure function for the pattern `ABABCABAB` is constructed as follows: - -1. **Initialization**: - - We start by setting `π[1] = 0` for the first character in the pattern, as it has no proper prefix or suffix. - - The table at this stage: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | | | | | | | | | - ``` - -2. **Step-by-Step Table Construction**: - - - **At i = 2** (Substring `AB`): - - The prefix `A` and suffix `B` are different, so there is no prefix that is also a suffix. - - We set `π[2] = 0`. - - Updated table: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | 0 | | | | | | | | - ``` - - - **At i = 3** (Substring `ABA`): - - The longest prefix which is also a suffix is `A` (length 1). - - We set `π[3] = 1`. - - Updated table: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | 0 | 1 | | | | | | | - ``` - - - **At i = 4** (Substring `ABAB`): - - The longest prefix which is also a suffix is `AB` (length 2). - - We set `π[4] = 2`. - - Updated table: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | 0 | 1 | 2 | | | | | | - ``` - - - **At i = 5** (Substring `ABABC`): - - There is no prefix that is also a suffix here. - - We set `π[5] = 0`. - - Updated table: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | 0 | 1 | 2 | 0 | | | | | - ``` - - - **At i = 6** (Substring `ABABCA`): - - The longest prefix-suffix match is `A` (length 1). - - We set `π[6] = 1`. - - Updated table: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | 0 | 1 | 2 | 0 | 1 | | | | - ``` - - - **At i = 7** (Substring `ABABCAB`): - - The longest prefix-suffix match is `AB` (length 2). - - We set `π[7] = 2`. - - Updated table: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | 0 | 1 | 2 | 0 | 1 | 2 | | | - ``` - - - **At i = 8** (Substring `ABABCABA`): - - The longest prefix-suffix match is `ABA` (length 3). - - We set `π[8] = 3`. - - Updated table: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | 0 | 1 | 2 | 0 | 1 | 2 | 3 | | - ``` - - - **At i = 9** (Substring `ABABCABAB`): - - The longest prefix-suffix match is `ABAB` (length 4). - - We set `π[9] = 4`. - - Final table: - - ``` - | Sequence Position (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - |-------------------------|---|---|---|---|---|---|---|---|---| - | Pattern (P[i]) | A | B | A | B | C | A | B | A | B | - | Failure Function (π[i]) | 0 | 0 | 1 | 2 | 0 | 1 | 2 | 3 | 4 | - ``` - -This failure function table helps optimize the KMP pattern matching process by indicating how much the pattern should shift on a mismatch, ensuring no redundant comparisons are made. - -### 2. Matching Phase - -The KMP algorithm scans the text from left to right while comparing the pattern to each substring in the text. When a mismatch occurs, the algorithm uses the failure function to shift the pattern appropriately, ensuring that already-matched characters do not need to be rechecked. - -#### Step-by-Step Matching for `ABABCABAB` in `ABABDABACDABABCABAB`: - -1. **Initialize**: - - Text (T) = `ABABDABACDABABCABAB` - - Pattern (P) = `ABABCABAB` - - Start at the first character of the text and pattern. - -2. **Match Characters**: - - **T[0] to T[4]** (Text substring `ABABD`) matches **P[0] to P[4]**. A mismatch occurs at **T[4] (D)** and **P[4] (C)**. - -3. **Use Failure Function**: - - At mismatch, 4 characters have matched (`k = 4`). - - Use the formula: `shift = k - π[k]`, where π[4] = 2. - - **Shift**: `shift = 4 - 2 = 2`. Move the pattern 2 characters to the right. - -4. **Continue Matching**: - - Resume comparison with **T[2] to T[7]** and **P[0] to P[5]**. Another mismatch occurs at **T[7] (C)** and **P[5] (A)**. - - With **k = 3** matched characters, **π[3] = 1**. - - **Shift**: `shift = 3 - 1 = 2`. Move the pattern 2 characters right. - -5. **Repeat Process**: - - Continue aligning and comparing until **T[10] to T[18]** perfectly matches **P[0] to P[8]**. - - Pattern `ABABCABAB` is found at **position 10** in the text. - -6. **Result**: - - Pattern `ABABCABAB` occurs at index 10 in the text. - -By using the failure function for shifts, KMP avoids redundant comparisons, resulting in a linear time complexity for the matching phase. - - -### Characteristics: - -- **Failure Function**: - - Computes partial match table (also called failure function) - - Tracks longest proper prefixes that are also suffixes - - Enables efficient backtracking - -- **Linear Time Matching**: - - Never backtracks in the main text - - Utilizes preprocessed information - - Maintains constant space complexity - -- **Preprocessing Phase**: - - Builds failure function array - - Analyzes pattern structure - - Enables optimal shifts during search - -- **Left-to-Right Scanning**: - - Scans both pattern and text left to right - - Uses failure function for mismatches - - Maintains linear time complexity - -### Time Complexity: - -- **Preprocessing: $O(m)$** - - Where m is pattern length - - Constructs failure function - - One-time computation - -- **Searching: $O(n)$** - - Where n is text length - - Linear time guaranteed - - No backtracking in text - -### Space Complexity: - -- **Space Usage: $O(m)$** - - Failure function array - - No additional dynamic space - - Independent of text length - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -class KMPAlgorithm { -private: - // Compute the failure function - vector computeLPSArray(const string& pattern) { - int m = pattern.length(); - vector lps(m, 0); - - int len = 0; // length of previous longest prefix suffix - int i = 1; - - while (i < m) { - if (pattern[i] == pattern[len]) { - len++; - lps[i] = len; - i++; - } else { - if (len != 0) { - len = lps[len - 1]; - } else { - lps[i] = 0; - i++; - } - } - } - - return lps; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocessing: compute failure function - vector lps = computeLPSArray(pattern); - - // Searching phase - int i = 0; // index for text - int j = 0; // index for pattern - - while (i < n) { - if (pattern[j] == text[i]) { - i++; - j++; - } - - if (j == m) { - // Pattern found - matches.push_back(i - j); - j = lps[j - 1]; - } else if (i < n && pattern[j] != text[i]) { - if (j != 0) { - j = lps[j - 1]; - } else { - i++; - } - } - } - - return matches; - } -}; - -// Demonstration class -class KMPDemo { -public: - static void demonstrateSearch() { - KMPAlgorithm algo; - string text = "ABABDABACDABABCABAB"; - string pattern = "ABABCABAB"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - vector matches = algo.search(text, pattern); - - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - KMPDemo::demonstrateSearch(); - return 0; -} -``` - -### Key Features: - -1. **Failure Function**: - - Efficient prefix-suffix matching - - Optimal shift calculation - - Pattern preprocessing - -2. **Linear Time Guarantee**: - - No backtracking in text - - Optimal worst-case complexity - - Efficient pattern matching - -3. **Optimization Techniques**: - - Preprocessed pattern analysis - - Efficient state transitions - - Minimal character comparisons - -### Applications: - -1. **Text Processing**: - - Text editors - - File searching - - Document analysis - -2. **Bioinformatics**: - - DNA sequence matching - - Protein pattern analysis - - Genome sequencing - -3. **Network Security**: - - Packet inspection - - Signature detection - - Data filtering - -4. **Information Retrieval**: - - Pattern matching - - Text mining - - Content searching - -### Advanced Features: - -1. **Algorithm Variants**: - - Multiple pattern matching - - Circular string matching - - Approximate matching - -2. **Implementation Optimizations**: - - Cache-friendly versions - - Parallel implementations - - Memory-efficient variants - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Linear time guarantee - - No text backtracking - - Efficient for repetitive patterns - -2. **Trade-offs**: - - Preprocessing overhead - - Additional space requirement - - Complex implementation - -### Performance Characteristics: - -1. **Best Case**: - - O(n) comparisons - - Linear scanning - - Immediate mismatches - -2. **Average Case**: - - O(n) performance - - Consistent behavior - - Pattern-independent - -3. **Worst Case**: - - O(n) guaranteed - - No performance degradation - - Stable behavior - -### Summary: - -The Knuth-Morris-Pratt Algorithm represents a significant advancement in string matching algorithms by introducing the concept of the failure function. This innovation allows the algorithm to avoid unnecessary comparisons by utilizing information about previous matches, resulting in a guaranteed linear-time performance. - -The algorithm's efficiency comes from its ability to preprocess the pattern and build a failure function that enables optimal shifts during the matching phase. While it requires additional space for preprocessing, the KMP algorithm's guarantee of linear-time performance and its ability to handle repetitive patterns make it a valuable tool in various applications, from text processing to bioinformatics. - -The implementation combines elegant theoretical concepts with practical efficiency, making it a fundamental algorithm in computer science. Its consistent performance characteristics and lack of text backtracking make it particularly suitable for real-time applications and streaming data processing. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/lcs-algorithm.md b/docs/algorithms/string-algorithms/lcs-algorithm.md deleted file mode 100644 index e43dd3f8b..000000000 --- a/docs/algorithms/string-algorithms/lcs-algorithm.md +++ /dev/null @@ -1,330 +0,0 @@ ---- - -id: longest-common-subsequence-algorithm -sidebar_position: 16 -title: Longest Common Subsequence (LCS) Algorithm -sidebar_label: LCS Algorithm - ---- - -### Definition: - -The Longest Common Subsequence (LCS) Algorithm finds the longest subsequence that is present in two sequences in the same relative order. A subsequence is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements. Unlike substrings, subsequences need not be contiguous. - -### Characteristics: - -- **Dynamic Programming**: - - Builds solution table - - Uses optimal substructure - - Memoizes intermediate results - -- **Backtracking**: - - Reconstructs actual subsequence - - Traces optimal path - - Maintains solution history - -- **Multiple Solutions**: - - Handles multiple sequences - - Finds all possible LCS - - Supports various lengths - -- **Optimal Substructure**: - - Breaks into subproblems - - Combines local solutions - - Ensures global optimality - -### Time Complexity: - -- **Basic Version: $O(m \times n)$** - - Where m, n are sequence lengths - - Uses 2D dynamic programming - - Includes backtracking - -- **Space-Optimized: $O(min(m,n))$** - - Reduces memory usage - - Maintains only necessary rows - - Optional backtracking support - -### Space Complexity: - -- **Basic Version: $O(m \times n)$** - - Dynamic programming table - - Backtracking information - - Solution storage - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class LCSAlgorithm { -private: - // Structure to store cell information for backtracking - struct Cell { - int length; - bool isMatch; - Cell(int l = 0, bool m = false) : length(l), isMatch(m) {} - }; - - // Build the LCS table using dynamic programming - vector> buildLCSTable(const string& str1, - const string& str2) { - int m = str1.length(); - int n = str2.length(); - vector> dp(m + 1, vector(n + 1)); - - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (str1[i-1] == str2[j-1]) { - dp[i][j].length = dp[i-1][j-1].length + 1; - dp[i][j].isMatch = true; - } else { - dp[i][j].length = max(dp[i-1][j].length, - dp[i][j-1].length); - } - } - } - - return dp; - } - - // Reconstruct the LCS from the dp table - string backtrack(const vector>& dp, - const string& str1, const string& str2) { - string lcs; - int i = str1.length(); - int j = str2.length(); - - while (i > 0 && j > 0) { - if (dp[i][j].isMatch) { - lcs = str1[i-1] + lcs; - i--; j--; - } else if (dp[i-1][j].length > dp[i][j-1].length) { - i--; - } else { - j--; - } - } - - return lcs; - } - -public: - // Find the longest common subsequence - string findLCS(const string& str1, const string& str2) { - if (str1.empty() || str2.empty()) return ""; - - vector> dp = buildLCSTable(str1, str2); - return backtrack(dp, str1, str2); - } - - // Get the length of LCS - int getLCSLength(const string& str1, const string& str2) { - if (str1.empty() || str2.empty()) return 0; - - vector> dp = buildLCSTable(str1, str2); - return dp[str1.length()][str2.length()].length; - } - - // Space-optimized LCS length calculation - int getLCSLengthOptimized(const string& str1, const string& str2) { - if (str1.empty() || str2.empty()) return 0; - - int m = str1.length(); - int n = str2.length(); - vector prev(n + 1, 0); - vector curr(n + 1, 0); - - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (str1[i-1] == str2[j-1]) { - curr[j] = prev[j-1] + 1; - } else { - curr[j] = max(prev[j], curr[j-1]); - } - } - prev = curr; - } - - return curr[n]; - } - - // Find all longest common subsequences - vector findAllLCS(const string& str1, const string& str2) { - vector result; - if (str1.empty() || str2.empty()) return result; - - vector> dp = buildLCSTable(str1, str2); - backtrackAll(dp, str1, str2, str1.length(), str2.length(), - "", result); - - return result; - } - -private: - // Recursive backtracking to find all LCS - void backtrackAll(const vector>& dp, - const string& str1, const string& str2, - int i, int j, string current, - vector& result) { - if (i == 0 || j == 0) { - if (!current.empty()) { - reverse(current.begin(), current.end()); - result.push_back(current); - } - return; - } - - if (dp[i][j].isMatch) { - backtrackAll(dp, str1, str2, i-1, j-1, - current + str1[i-1], result); - } else { - if (i > 0 && dp[i-1][j].length == dp[i][j].length) { - backtrackAll(dp, str1, str2, i-1, j, current, result); - } - if (j > 0 && dp[i][j-1].length == dp[i][j].length) { - backtrackAll(dp, str1, str2, i, j-1, current, result); - } - } - } -}; - -// Demonstration class -class LCSDemo { -public: - static void demonstrateAlgorithm() { - LCSAlgorithm algo; - string str1 = "ABCDGH"; - string str2 = "AEDFHR"; - - cout << "String 1: " << str1 << endl; - cout << "String 2: " << str2 << endl; - - // Find LCS - string lcs = algo.findLCS(str1, str2); - cout << "Longest Common Subsequence: " << lcs << endl; - - // Get length - int length = algo.getLCSLength(str1, str2); - cout << "LCS Length: " << length << endl; - - // Space-optimized length calculation - int optLength = algo.getLCSLengthOptimized(str1, str2); - cout << "LCS Length (Optimized): " << optLength << endl; - - // Find all LCS - vector allLCS = algo.findAllLCS(str1, str2); - cout << "\nAll Longest Common Subsequences:" << endl; - for (const string& s : allLCS) { - cout << s << endl; - } - - // Demonstrate with different strings - str1 = "AGGTAB"; - str2 = "GXTXAYB"; - cout << "\nString 1: " << str1 << endl; - cout << "String 2: " << str2 << endl; - lcs = algo.findLCS(str1, str2); - cout << "Longest Common Subsequence: " << lcs << endl; - } -}; - -int main() { - LCSDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Dynamic Programming Solution**: - - Bottom-up approach - - Optimal substructure - - Memoization - -2. **Multiple Implementation Options**: - - Basic implementation - - Space-optimized version - - All-solutions variant - -3. **Optimization Techniques**: - - Memory efficiency - - Backtracking optimization - - Space-time trade-offs - -### Applications: - -1. **Bioinformatics**: - - DNA sequence alignment - - Protein sequence comparison - - Evolutionary distance - -2. **Text Processing**: - - Diff utilities - - Version control - - File comparison - -3. **Natural Language Processing**: - - Text similarity - - Plagiarism detection - - Document comparison - -4. **Data Analysis**: - - Pattern matching - - Sequence alignment - - Similarity metrics - -### Advanced Features: - -1. **Algorithm Variants**: - - Space-optimized version - - All-solutions finding - - Multiple sequence LCS - -2. **Implementation Optimizations**: - - Memory-efficient versions - - Parallel implementations - - Hirschberg's algorithm - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Optimal solution guaranteed - - Handles non-contiguous matches - - Versatile applications - -2. **Trade-offs**: - - Memory requirements - - Computational complexity - - Backtracking overhead - -### Performance Characteristics: - -1. **Best Case**: - - O(mn) operations - - Full table required - - Complete solution - -2. **Average Case**: - - O(mn) operations - - Consistent performance - - Predictable behavior - -3. **Worst Case**: - - O(mn) operations - - Space complexity trade-offs - - Backtracking considerations - -### Summary: - -The Longest Common Subsequence Algorithm represents a fundamental solution in sequence analysis and comparison. Its dynamic programming approach efficiently solves the problem of finding the longest shared subsequence between two sequences, with applications ranging from bioinformatics to text processing. - -The algorithm's strength lies in its ability to handle non-contiguous matches while maintaining optimal solution guarantees. The implementation provides multiple approaches, from basic dynamic programming to space-optimized versions and variants that can find all possible solutions. - -The practical applications of LCS extend beyond simple sequence matching to areas such as version control systems, DNA sequence analysis, and plagiarism detection. Its versatility and reliability make it a crucial tool in various fields where sequence comparison and analysis are essential. - -The ability to handle different requirements through various implementation options (basic, space-optimized, all-solutions) makes it adaptable to different use cases while maintaining its fundamental efficiency in finding the longest common subsequence between strings. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/levenshtein-distance-algorithm.md b/docs/algorithms/string-algorithms/levenshtein-distance-algorithm.md deleted file mode 100644 index d1d08fda5..000000000 --- a/docs/algorithms/string-algorithms/levenshtein-distance-algorithm.md +++ /dev/null @@ -1,372 +0,0 @@ ---- - -id: levenshtein-distance-algorithm -sidebar_position: 19 -title: Levenshtein Distance Algorithm -sidebar_label: Levenshtein Distance Algorithm - ---- - -### Definition: - -The Levenshtein Distance Algorithm, also known as Edit Distance, calculates the minimum number of single-character operations (insertions, deletions, or substitutions) required to transform one string into another. Developed by Vladimir Levenshtein in 1965, it is widely used in spell checking, DNA sequence analysis, and natural language processing. - -### Characteristics: - -- **Dynamic Programming**: - - Builds solution matrix - - Optimal substructure - - Bottom-up approach - -- **Edit Operations**: - - Character insertions - - Character deletions - - Character substitutions - -- **Distance Calculation**: - - Minimum operations count - - Operation costs tracking - - Path reconstruction - -- **Similarity Measurement**: - - String comparison - - Fuzzy matching - - Distance normalization - -### Time Complexity: - -- **Standard Version: $O(m \times n)$** - - Where m, n are string lengths - - Dynamic programming approach - - Matrix construction - -- **Space-Optimized: $O(min(m,n))$** - - Using two rows only - - Rolling array technique - - Constant space per row - -### Space Complexity: - -- **Standard Version: $O(m \times n)$** - - Full matrix storage - - Backtracking support - - Operation history - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class LevenshteinDistance { -private: - // Structure to store edit operation details - struct EditOperation { - enum Type { MATCH, SUBSTITUTE, INSERT, DELETE } type; - char from; - char to; - int cost; - - EditOperation(Type t, char f, char t2, int c) - : type(t), from(f), to(t2), cost(c) {} - }; - - // Store the edit path for backtracking - vector editPath; - - // Custom costs for operations - int insertCost = 1; - int deleteCost = 1; - int substituteCost = 1; - -public: - // Set custom costs for operations - void setCosts(int ins, int del, int sub) { - insertCost = ins; - deleteCost = del; - substituteCost = sub; - } - - // Calculate basic Levenshtein distance - int calculateDistance(const string& str1, const string& str2) { - int m = str1.length(); - int n = str2.length(); - - vector> dp(m + 1, vector(n + 1)); - - // Initialize first row and column - for (int i = 0; i <= m; i++) { - dp[i][0] = i * deleteCost; - } - for (int j = 0; j <= n; j++) { - dp[0][j] = j * insertCost; - } - - // Fill the matrix - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (str1[i-1] == str2[j-1]) { - dp[i][j] = dp[i-1][j-1]; // Match - } else { - dp[i][j] = min({ - dp[i-1][j] + deleteCost, // Deletion - dp[i][j-1] + insertCost, // Insertion - dp[i-1][j-1] + substituteCost // Substitution - }); - } - } - } - - return dp[m][n]; - } - - // Calculate distance and store edit path - int calculateDistanceWithPath(const string& str1, - const string& str2) { - editPath.clear(); - int m = str1.length(); - int n = str2.length(); - - vector> dp(m + 1, vector(n + 1)); - vector> operations( - m + 1, vector(n + 1)); - - // Initialize - for (int i = 0; i <= m; i++) { - dp[i][0] = i * deleteCost; - operations[i][0] = EditOperation::DELETE; - } - for (int j = 0; j <= n; j++) { - dp[0][j] = j * insertCost; - operations[0][j] = EditOperation::INSERT; - } - - // Fill matrix and track operations - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (str1[i-1] == str2[j-1]) { - dp[i][j] = dp[i-1][j-1]; - operations[i][j] = EditOperation::MATCH; - } else { - dp[i][j] = min({ - dp[i-1][j] + deleteCost, - dp[i][j-1] + insertCost, - dp[i-1][j-1] + substituteCost - }); - - if (dp[i][j] == dp[i-1][j] + deleteCost) { - operations[i][j] = EditOperation::DELETE; - } else if (dp[i][j] == dp[i][j-1] + insertCost) { - operations[i][j] = EditOperation::INSERT; - } else { - operations[i][j] = EditOperation::SUBSTITUTE; - } - } - } - } - - // Reconstruct edit path - int i = m, j = n; - while (i > 0 || j > 0) { - switch (operations[i][j]) { - case EditOperation::MATCH: - editPath.push_back(EditOperation( - EditOperation::MATCH, - str1[i-1], str2[j-1], 0)); - i--; j--; - break; - case EditOperation::SUBSTITUTE: - editPath.push_back(EditOperation( - EditOperation::SUBSTITUTE, - str1[i-1], str2[j-1], substituteCost)); - i--; j--; - break; - case EditOperation::INSERT: - editPath.push_back(EditOperation( - EditOperation::INSERT, - '\0', str2[j-1], insertCost)); - j--; - break; - case EditOperation::DELETE: - editPath.push_back(EditOperation( - EditOperation::DELETE, - str1[i-1], '\0', deleteCost)); - i--; - break; - } - } - - reverse(editPath.begin(), editPath.end()); - return dp[m][n]; - } - - // Get normalized distance (0 to 1) - double getNormalizedDistance(const string& str1, - const string& str2) { - int distance = calculateDistance(str1, str2); - return static_cast(distance) / - max(str1.length(), str2.length()); - } - - // Get edit path as string - string getEditPathDescription() { - string description; - for (const auto& op : editPath) { - switch (op.type) { - case EditOperation::MATCH: - description += "Match '" + string(1, op.from) + - "'\n"; - break; - case EditOperation::SUBSTITUTE: - description += "Substitute '" + string(1, op.from) + - "' with '" + string(1, op.to) + - "' (cost " + to_string(op.cost) + - ")\n"; - break; - case EditOperation::INSERT: - description += "Insert '" + string(1, op.to) + - "' (cost " + to_string(op.cost) + - ")\n"; - break; - case EditOperation::DELETE: - description += "Delete '" + string(1, op.from) + - "' (cost " + to_string(op.cost) + - ")\n"; - break; - } - } - return description; - } -}; - -// Demonstration class -class LevenshteinDemo { -public: - static void demonstrateAlgorithm() { - LevenshteinDistance algo; - string str1 = "kitten"; - string str2 = "sitting"; - - cout << "String 1: " << str1 << endl; - cout << "String 2: " << str2 << endl; - - // Basic distance calculation - int distance = algo.calculateDistance(str1, str2); - cout << "\nLevenshtein distance: " << distance << endl; - - // Normalized distance - double normalized = algo.getNormalizedDistance(str1, str2); - cout << "Normalized distance: " << normalized << endl; - - // Detailed edit path - distance = algo.calculateDistanceWithPath(str1, str2); - cout << "\nEdit operations:\n" << - algo.getEditPathDescription() << endl; - - // Custom costs demonstration - cout << "\nWith custom costs (Insert:2, Delete:2, Substitute:1):" - << endl; - algo.setCosts(2, 2, 1); - distance = algo.calculateDistance(str1, str2); - cout << "Modified distance: " << distance << endl; - } -}; - -int main() { - LevenshteinDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Dynamic Programming Implementation**: - - Optimal subproblem solution - - Memoization of results - - Path reconstruction - -2. **Flexible Operations**: - - Customizable operation costs - - Multiple distance metrics - - Edit path tracking - -3. **Optimization Options**: - - Space-efficient versions - - Early termination - - Path reconstruction - -### Applications: - -1. **Text Processing**: - - Spell checking - - Auto-correction - - Fuzzy search - -2. **Bioinformatics**: - - DNA sequence alignment - - Protein comparison - - Mutation analysis - -3. **Natural Language Processing**: - - Text similarity - - Language correction - - Speech recognition - -4. **Information Retrieval**: - - Search engines - - Pattern matching - - Document comparison - -### Advanced Features: - -1. **Algorithm Variants**: - - Damerau-Levenshtein distance - - Weighted operations - - Limited-window versions - -2. **Implementation Optimizations**: - - Memory-efficient versions - - Parallel processing - - Block matrix computation - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Intuitive distance metric - - Flexible operation costs - - Path reconstruction - -2. **Trade-offs**: - - Computational complexity - - Memory requirements - - Implementation complexity - -### Performance Characteristics: - -1. **Best Case**: - - O(min(m,n)) for identical strings - - Early termination possible - - Optimal substructure - -2. **Average Case**: - - O(mn) operations - - Predictable performance - - Consistent behavior - -3. **Worst Case**: - - O(mn) operations required - - Full matrix computation - - Maximum path length - -### Summary: - -The Levenshtein Distance Algorithm provides a robust and flexible approach to measuring string similarity and calculating edit distances. Its dynamic programming implementation ensures optimal solutions while supporting various customizations and optimizations. - -The algorithm's strength lies in its ability to handle different types of string transformations with customizable costs, making it adaptable to various applications. The implementation supports both basic distance calculation and detailed edit path reconstruction, providing comprehensive information about the transformation process. - -The practical applications span multiple domains, from text processing and spell checking to bioinformatics and natural language processing. Its ability to quantify string similarity makes it a fundamental tool in many modern applications requiring fuzzy string matching or error tolerance. - -The algorithm's versatility in handling different requirements through customizable operation costs and various implementation options makes it adaptable to different use cases while maintaining its fundamental efficiency in measuring string similarity and edit distances. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/manacher-algorithm.md b/docs/algorithms/string-algorithms/manacher-algorithm.md deleted file mode 100644 index b7794d6dc..000000000 --- a/docs/algorithms/string-algorithms/manacher-algorithm.md +++ /dev/null @@ -1,283 +0,0 @@ ---- - -id: manachers-algorithm -sidebar_position: 15 -title: Manacher's Algorithm -sidebar_label: Manacher's Algorithm - ---- - -### Definition: - -Manacher's Algorithm is a linear-time algorithm developed by Glenn K. Manacher in 1975 for finding all palindromic substrings in a string. It efficiently solves the problem by utilizing previously computed palindrome lengths and symmetry properties, avoiding redundant comparisons through the use of an auxiliary array. - -### Characteristics: - -- **Linear Time Processing**: - - Finds all palindromes in O(n) time - - Avoids redundant comparisons - - Utilizes symmetry properties - -- **LPS Array**: - - Stores palindrome lengths - - Enables efficient lookups - - Maintains symmetry information - -- **String Transformation**: - - Handles both odd and even length palindromes - - Special character insertion - - Unified palindrome detection - -- **Center Expansion**: - - Expands around centers - - Uses previous computations - - Optimizes palindrome detection - -### Time Complexity: - -- **Overall: $O(n)$** - - Linear time processing - - No preprocessing required - - Optimal complexity - -### Space Complexity: - -- **Space Usage: $O(n)$** - - LPS array storage - - Transformed string storage - - Auxiliary space for processing - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -class ManachersAlgorithm { -private: - // Transform string to handle both odd and even length palindromes - string transformString(const string& s) { - string transformed = "#"; - for (char c : s) { - transformed += c; - transformed += "#"; - } - return transformed; - } - -public: - // Find all palindromic substrings and their lengths - vector findPalindromes(const string& s) { - string t = transformString(s); - int n = t.length(); - vector lps(n, 0); // LPS array for palindrome lengths - - int center = 0; // Current center of palindrome - int right = 0; // Right boundary of current palindrome - - // Process all characters as potential centers - for (int i = 0; i < n; i++) { - // Initialize palindrome length at current position - if (i < right) { - int mirror = 2 * center - i; - lps[i] = min(right - i, lps[mirror]); - } - - // Expand around current position - int a = i + (1 + lps[i]); - int b = i - (1 + lps[i]); - while (b >= 0 && a < n && t[a] == t[b]) { - lps[i]++; - a++; - b--; - } - - // Update center and right boundary if needed - if (i + lps[i] > right) { - center = i; - right = i + lps[i]; - } - } - - return lps; - } - - // Get all palindromic substrings - vector getAllPalindromes(const string& s) { - vector palindromes; - string t = transformString(s); - vector lps = findPalindromes(s); - - for (int i = 0; i < t.length(); i++) { - int len = lps[i]; - if (len > 0) { - string palindrome; - for (int j = i - len; j <= i + len; j++) { - if (t[j] != '#') { - palindrome += t[j]; - } - } - if (!palindrome.empty()) { - palindromes.push_back(palindrome); - } - } - } - - return palindromes; - } - - // Get longest palindromic substring - string getLongestPalindrome(const string& s) { - string t = transformString(s); - vector lps = findPalindromes(s); - - int maxLen = 0; - int centerIndex = 0; - - for (int i = 0; i < t.length(); i++) { - if (lps[i] > maxLen) { - maxLen = lps[i]; - centerIndex = i; - } - } - - string longestPalindrome; - for (int i = centerIndex - maxLen; i <= centerIndex + maxLen; i++) { - if (t[i] != '#') { - longestPalindrome += t[i]; - } - } - - return longestPalindrome; - } -}; - -// Demonstration class -class ManachersDemo { -public: - static void demonstrateAlgorithm() { - ManachersAlgorithm algo; - string text = "babadada"; - - cout << "Text: " << text << endl; - - // Find longest palindrome - string longest = algo.getLongestPalindrome(text); - cout << "Longest palindrome: " << longest << endl; - - // Find all palindromes - vector allPalindromes = algo.getAllPalindromes(text); - cout << "\nAll palindromic substrings:" << endl; - for (const string& palindrome : allPalindromes) { - if (palindrome.length() > 1) { // Skip single-character palindromes - cout << palindrome << endl; - } - } - - // Show palindrome lengths - vector lps = algo.findPalindromes(text); - cout << "\nPalindrome lengths at each center:" << endl; - string transformed = "#" + string(text.begin(), text.end()) + "#"; - for (int i = 0; i < transformed.length(); i++) { - cout << transformed[i] << ": " << lps[i] << endl; - } - } -}; - -int main() { - ManachersDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Linear Time Processing**: - - Efficient palindrome detection - - No backtracking required - - Optimal time complexity - -2. **Symmetry Exploitation**: - - Mirror property usage - - Center-based expansion - - Boundary tracking - -3. **Optimization Techniques**: - - Unified even/odd handling - - Efficient boundary checking - - Minimal comparisons - -### Applications: - -1. **Text Processing**: - - Palindrome detection - - String analysis - - Pattern recognition - -2. **Bioinformatics**: - - DNA palindrome finding - - Sequence analysis - - Structural patterns - -3. **Data Compression**: - - Pattern identification - - Redundancy detection - - Compression optimization - -4. **String Analysis**: - - Text mining - - Pattern searching - - String manipulation - -### Advanced Features: - -1. **Algorithm Variants**: - - Streaming version - - Space-optimized version - - Multiple string processing - -2. **Implementation Optimizations**: - - Cache-efficient versions - - Memory-efficient variants - - Parallel implementations - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Linear time complexity - - Handles all palindromes - - No preprocessing needed - -2. **Trade-offs**: - - Space requirement - - Implementation complexity - - String transformation overhead - -### Performance Characteristics: - -1. **Best Case**: - - O(n) operations - - Linear scanning - - Optimal performance - -2. **Average Case**: - - O(n) operations - - Consistent performance - - Predictable behavior - -3. **Worst Case**: - - O(n) operations - - Guaranteed performance - - No degradation - -### Summary: - -Manacher's Algorithm represents a significant breakthrough in palindrome detection by providing a linear-time solution to find all palindromic substrings in a string. Its innovative approach of using symmetry properties and previously computed results eliminates redundant comparisons, making it highly efficient. - -The algorithm's strength lies in its ability to handle both odd and even length palindromes uniformly through string transformation, while maintaining linear time complexity. The use of the LPS array and center expansion technique allows for optimal palindrome detection without backtracking. - -The implementation provides a comprehensive solution for palindrome-related problems, offering functions to find the longest palindromic substring, all palindromic substrings, and palindrome lengths at each position. Its guaranteed linear-time performance and ability to find all palindromes make it an essential tool in string processing applications where palindrome detection is required. - -The algorithm's practical applications extend beyond simple palindrome detection to areas such as bioinformatics, data compression, and pattern recognition, where its efficient processing of palindromic structures provides valuable insights into string patterns and symmetries. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/needleman-wunsch-algorithm.md b/docs/algorithms/string-algorithms/needleman-wunsch-algorithm.md deleted file mode 100644 index 9936d2f76..000000000 --- a/docs/algorithms/string-algorithms/needleman-wunsch-algorithm.md +++ /dev/null @@ -1,319 +0,0 @@ ---- - -id: needleman-wunsch-algorithm -sidebar_position: 22 -title: Needleman-Wunsch Algorithm -sidebar_label: Needleman-Wunsch Algorithm - ---- - -### Definition: - -The Needleman-Wunsch Algorithm is a dynamic programming algorithm for global sequence alignment, finding the optimal alignment between two sequences by considering the entire length of both sequences. Developed by Saul B. Needleman and Christian D. Wunsch in 1970, it optimizes a scoring function based on matches, mismatches, and gaps. - -### Characteristics: - -- **Global Alignment**: - - End-to-end sequence alignment - - Complete sequence coverage - - Optimal overall score - -- **Scoring Matrix**: - - Match/mismatch rewards - - Gap penalties - - Progressive calculation - -- **Dynamic Programming**: - - Optimal substructure - - Matrix filling - - Backtracking - -- **Complete Solution**: - - Maximum score path - - Full sequence coverage - - Optimal alignment - -### Time Complexity: - -- **Matrix Computation: $O(m \times n)** - - Where m, n are sequence lengths - - Complete matrix filling - - Traceback included - -### Space Complexity: - -- **Standard Version: $O(m \times n)$** - - Scoring matrix storage - - Traceback information - - Alignment data - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class NeedlemanWunsch { -private: - struct Cell { - int score; - int direction; // 0: none, 1: diagonal, 2: up, 3: left - - Cell() : score(0), direction(0) {} - }; - - int matchScore; - int mismatchScore; - int gapScore; - - // Initialize first row and column of the matrix - void initializeMatrix(vector>& matrix, - int rows, int cols) { - // Initialize first row - for (int j = 1; j < cols; j++) { - matrix[0][j].score = matrix[0][j-1].score + gapScore; - matrix[0][j].direction = 3; // Left - } - - // Initialize first column - for (int i = 1; i < rows; i++) { - matrix[i][0].score = matrix[i-1][0].score + gapScore; - matrix[i][0].direction = 2; // Up - } - } - - // Fill the scoring matrix - vector> computeMatrix(const string& seq1, - const string& seq2) { - int m = seq1.length(); - int n = seq2.length(); - vector> matrix(m + 1, vector(n + 1)); - - // Initialize edges - initializeMatrix(matrix, m + 1, n + 1); - - // Fill the rest of the matrix - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - // Calculate scores for all possibilities - int match = matrix[i-1][j-1].score + - (seq1[i-1] == seq2[j-1] ? matchScore : mismatchScore); - int del = matrix[i-1][j].score + gapScore; - int ins = matrix[i][j-1].score + gapScore; - - // Find maximum score - matrix[i][j].score = max({match, del, ins}); - - // Store traceback direction - if (matrix[i][j].score == match) { - matrix[i][j].direction = 1; - } else if (matrix[i][j].score == del) { - matrix[i][j].direction = 2; - } else { - matrix[i][j].direction = 3; - } - } - } - - return matrix; - } - -public: - NeedlemanWunsch(int match = 1, int mismatch = -1, int gap = -2) - : matchScore(match), mismatchScore(mismatch), gapScore(gap) {} - - struct AlignmentResult { - string alignedSeq1; - string alignedSeq2; - int score; - - void print() const { - cout << "Score: " << score << endl; - cout << "Alignment:" << endl; - cout << alignedSeq1 << endl; - string middle(alignedSeq1.length(), ' '); - for (size_t i = 0; i < alignedSeq1.length(); i++) { - if (alignedSeq1[i] == alignedSeq2[i]) { - middle[i] = '|'; - } - } - cout << middle << endl; - cout << alignedSeq2 << endl; - } - }; - - // Main alignment function - AlignmentResult align(const string& seq1, const string& seq2) { - vector> matrix = computeMatrix(seq1, seq2); - string aligned1, aligned2; - int i = seq1.length(); - int j = seq2.length(); - int score = matrix[i][j].score; - - // Traceback - while (i > 0 || j > 0) { - if (i > 0 && j > 0 && matrix[i][j].direction == 1) { - // Diagonal - aligned1 = seq1[i-1] + aligned1; - aligned2 = seq2[j-1] + aligned2; - i--; j--; - } else if (i > 0 && matrix[i][j].direction == 2) { - // Up - aligned1 = seq1[i-1] + aligned1; - aligned2 = '-' + aligned2; - i--; - } else { - // Left - aligned1 = '-' + aligned1; - aligned2 = seq2[j-1] + aligned2; - j--; - } - } - - return {aligned1, aligned2, score}; - } - - // Set custom scoring parameters - void setScoringParameters(int match, int mismatch, int gap) { - matchScore = match; - mismatchScore = mismatch; - gapScore = gap; - } - - // Get scoring matrix for visualization - vector> getScoreMatrix(const string& seq1, - const string& seq2) { - auto matrix = computeMatrix(seq1, seq2); - vector> scores(matrix.size(), - vector(matrix[0].size())); - - for (size_t i = 0; i < matrix.size(); i++) { - for (size_t j = 0; j < matrix[0].size(); j++) { - scores[i][j] = matrix[i][j].score; - } - } - - return scores; - } -}; - -// Demonstration class -class NeedlemanWunschDemo { -public: - static void demonstrateAlgorithm() { - NeedlemanWunsch algo(1, -1, -2); // match, mismatch, gap - - // Example 1: Simple sequences - string seq1 = "GCATGCU"; - string seq2 = "GATTACA"; - - cout << "Sequence 1: " << seq1 << endl; - cout << "Sequence 2: " << seq2 << endl; - - auto result = algo.align(seq1, seq2); - result.print(); - - // Example 2: Different scoring parameters - cout << "\nWith different scoring parameters " - << "(match=2, mismatch=-1, gap=-1):" << endl; - algo.setScoringParameters(2, -1, -1); - result = algo.align(seq1, seq2); - result.print(); - - // Example 3: Longer sequences - seq1 = "ACGTACGTACGT"; - seq2 = "ACGTACGTAG"; - cout << "\nLonger sequences:" << endl; - cout << "Sequence 1: " << seq1 << endl; - cout << "Sequence 2: " << seq2 << endl; - result = algo.align(seq1, seq2); - result.print(); - } -}; - -int main() { - NeedlemanWunschDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Global Alignment**: - - Complete sequence coverage - - End-to-end alignment - - Maximum overall score - -2. **Scoring System**: - - Match/mismatch scores - - Gap penalties - - Customizable parameters - -3. **Matrix Operations**: - - Progressive filling - - Optimal path tracking - - Score maximization - -### Applications: - -1. **Sequence Analysis**: - - Full sequence comparison - - Pattern recognition - - Homology detection - -2. **Bioinformatics**: - - Gene comparison - - Protein alignment - - Evolutionary studies - -3. **Data Analysis**: - - String similarity - - Pattern matching - - Sequence classification - -4. **Database Search**: - - Sequence matching - - Similarity assessment - - Comparative analysis - -### Advanced Features: - -1. **Algorithm Variants**: - - Linear space version - - Banded alignment - - Affine gap penalties - -2. **Implementation Optimizations**: - - Memory efficiency - - Parallel processing - - Cache optimization - -### Performance Characteristics: - -1. **Best Case**: - - O(mn) operations - - Complete alignment - - Optimal solution - -2. **Average Case**: - - O(mn) operations - - Full matrix computation - - Predictable performance - -3. **Worst Case**: - - O(mn) operations - - Space-time trade-off - - Memory constraints - -### Summary: - -The Needleman-Wunsch Algorithm represents a fundamental approach to global sequence alignment, providing optimal solutions for comparing entire sequences. Its dynamic programming approach ensures the discovery of the best possible alignment between two sequences while considering matches, mismatches, and gaps. - -The algorithm's strength lies in its ability to find the optimal global alignment, considering the entire length of both sequences. The implementation provides both the core alignment functionality and additional features for visualization and analysis, making it suitable for various sequence comparison tasks. - -The practical applications of this algorithm extend from basic sequence comparison to complex biological sequence analysis. Its guarantee of finding the optimal global alignment makes it particularly valuable in applications where complete sequence comparison is essential. - -The algorithm's systematic approach to sequence alignment, combined with its flexibility in scoring parameters, makes it a fundamental tool in sequence analysis. Its continued relevance in modern applications demonstrates its importance in fields requiring accurate and complete sequence comparisons. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/not-so-naive-algorithm.md b/docs/algorithms/string-algorithms/not-so-naive-algorithm.md deleted file mode 100644 index a5de55cf4..000000000 --- a/docs/algorithms/string-algorithms/not-so-naive-algorithm.md +++ /dev/null @@ -1,317 +0,0 @@ ---- - -id: not-so-naive-algorithm -sidebar_position: 24 -title: Not So Naive Algorithm -sidebar_label: Not So Naive Algorithm - ---- - -### Definition: - -The Not So Naive Algorithm is an improvement over the naive string matching algorithm that optimizes character comparisons by utilizing information from previous matches. It reduces unnecessary comparisons by identifying patterns in the text and using this information to skip redundant checks. - -### Characteristics: - -- **Smart Comparisons**: - - Efficient comparison ordering - - Skip redundant checks - - Pattern analysis - -- **Pattern Preprocessing**: - - Pattern structure analysis - - Match history utilization - - Optimization setup - -- **Left-to-Right Scanning**: - - Linear text traversal - - Optimized comparison sequence - - Early mismatch detection - -- **Memory Efficiency**: - - Minimal additional storage - - Constant space overhead - - Simple implementation - -### Time Complexity: - -- **Preprocessing: $O(m)$** - - Where m is pattern length - - Pattern analysis - - One-time computation - -- **Searching: $O(n \times m)$** - - Where n is text length - - Better average case - - Optimized comparisons - -### Space Complexity: - -- **Space Usage: $O(1)$** - - Constant extra space - - No preprocessing storage - - Pattern storage only - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -class NotSoNaiveAlgorithm { -private: - // Check if pattern has periodicity - bool hasPeriodicPattern(const string& pattern) { - int m = pattern.length(); - for (int i = 1; i <= m/2; i++) { - bool isPeriodic = true; - for (int j = i; j < m; j++) { - if (pattern[j] != pattern[j - i]) { - isPeriodic = false; - break; - } - } - if (isPeriodic) { - return true; - } - } - return false; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - bool isPeriodic = hasPeriodicPattern(pattern); - - int i = 0; // text position - while (i <= n - m) { - int j = 0; // pattern position - - // First character comparison - if (text[i] == pattern[0]) { - // If pattern is not periodic, use optimized comparison - if (!isPeriodic) { - // Compare last character early - if (text[i + m - 1] != pattern[m - 1]) { - i++; - continue; - } - - // Compare remaining characters - j = 1; - while (j < m - 1 && pattern[j] == text[i + j]) { - j++; - } - - if (j == m - 1) { - matches.push_back(i); - } - } else { - // Use standard comparison for periodic patterns - j = 1; - while (j < m && pattern[j] == text[i + j]) { - j++; - } - - if (j == m) { - matches.push_back(i); - } - } - } - i++; - } - - return matches; - } - - // Advanced search with additional optimizations - vector advancedSearch(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Additional optimization: character frequency check - vector patternChars(256, false); - for (char c : pattern) { - patternChars[c] = true; - } - - int i = 0; - while (i <= n - m) { - // Skip if character not in pattern - if (!patternChars[text[i]]) { - i++; - continue; - } - - // Pattern matching with optimizations - if (text[i] == pattern[0]) { - bool mismatch = false; - - // Check last character early - if (text[i + m - 1] != pattern[m - 1]) { - i++; - continue; - } - - // Check middle character - int mid = m / 2; - if (text[i + mid] != pattern[mid]) { - i++; - continue; - } - - // Check remaining characters - for (int j = 1; j < m - 1; j++) { - if (j != mid && pattern[j] != text[i + j]) { - mismatch = true; - break; - } - } - - if (!mismatch) { - matches.push_back(i); - } - } - i++; - } - - return matches; - } -}; - -// Demonstration class -class NotSoNaiveDemo { -public: - static void demonstrateAlgorithm() { - NotSoNaiveAlgorithm algo; - - // Example 1: Basic pattern matching - string text = "ABCABCABCABC"; - string pattern = "ABCABC"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - vector matches = algo.search(text, pattern); - cout << "\nBasic search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Example 2: Advanced search - matches = algo.advancedSearch(text, pattern); - cout << "Advanced search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Example 3: Non-periodic pattern - text = "ABCDEFGABCDEFG"; - pattern = "DEFG"; - cout << "\nText: " << text << endl; - cout << "Pattern: " << pattern << endl; - - matches = algo.search(text, pattern); - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - NotSoNaiveDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Optimized Comparisons**: - - Smart character ordering - - Early mismatch detection - - Pattern-based optimization - -2. **Pattern Analysis**: - - Periodicity detection - - Character frequency - - Pattern structure - -3. **Simple Implementation**: - - Minimal overhead - - Easy to understand - - Efficient execution - -### Applications: - -1. **Text Processing**: - - Simple pattern matching - - Document searching - - Content analysis - -2. **Data Filtering**: - - Basic text filtering - - Pattern detection - - Content validation - -3. **String Searching**: - - Simple searches - - Pattern location - - Text analysis - -4. **Educational Use**: - - Algorithm teaching - - Pattern matching concepts - - Optimization techniques - -### Advanced Features: - -1. **Algorithm Variants**: - - Character frequency optimization - - Middle character checking - - Multiple pattern support - -2. **Implementation Optimizations**: - - Early termination - - Skip invalid characters - - Pattern-based skipping - -### Performance Characteristics: - -1. **Best Case**: - - O(n) comparisons - - Early mismatch detection - - Efficient skipping - -2. **Average Case**: - - Better than naive approach - - Reduced comparisons - - Practical efficiency - -3. **Worst Case**: - - O(nm) comparisons - - Pattern dependent - - Still better than naive - -### Summary: - -The Not So Naive Algorithm represents a practical improvement over the naive string matching approach by incorporating simple yet effective optimizations. Its straightforward implementation and improved performance make it suitable for educational purposes and simple pattern matching tasks. - -The algorithm's strength lies in its ability to reduce unnecessary comparisons while maintaining simplicity in implementation. By using pattern analysis and smart comparison ordering, it achieves better average-case performance than the naive approach without significant additional complexity. - -The practical applications of this algorithm are particularly relevant in scenarios where simplicity and understandability are prioritized over absolute performance. Its educational value in demonstrating pattern matching concepts and optimization techniques makes it a valuable tool for learning and teaching string algorithms. - -The algorithm's balance between simplicity and optimization makes it an excellent choice for situations where a more complex algorithm would be overkill, while still providing better performance than the basic naive approach. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/optimal-mismatch-algorithm.md b/docs/algorithms/string-algorithms/optimal-mismatch-algorithm.md deleted file mode 100644 index f726f1db0..000000000 --- a/docs/algorithms/string-algorithms/optimal-mismatch-algorithm.md +++ /dev/null @@ -1,337 +0,0 @@ ---- - -id: optimal-mismatch-algorithm -sidebar_position: 25 -title: Optimal Mismatch Algorithm -sidebar_label: Optimal Mismatch Algorithm - ---- - -### Definition: - -The Optimal Mismatch Algorithm is a pattern matching algorithm that optimizes the order of character comparisons to detect mismatches as early as possible. It analyzes the pattern to determine the most efficient sequence of character comparisons, minimizing the average number of comparisons needed to identify non-matches. - -### Characteristics: - -- **Optimal Comparison Order**: - - Character frequency analysis - - Probability-based ordering - - Early mismatch detection - -- **Pattern Analysis**: - - Character distribution study - - Position importance weighting - - Statistical optimization - -- **Adaptive Processing**: - - Dynamic comparison order - - Pattern-based optimization - - Efficient scanning - -- **Statistical Approach**: - - Probability calculations - - Character weight assignment - - Optimal sequence determination - -### Time Complexity: - -- **Preprocessing: $O(m \times log m)$** - - Where m is pattern length - - Character analysis - - Order optimization - -- **Searching: $O(n \times m)$** - - Where n is text length - - Optimized average case - - Pattern-dependent performance - -### Space Complexity: - -- **Space Usage: $O(m)$** - - Comparison order storage - - Pattern information - - Statistical data - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -#include -using namespace std; - -class OptimalMismatchAlgorithm { -private: - struct CharacterInfo { - char character; - int position; - double weight; // For probability-based decisions - - CharacterInfo(char c, int pos, double w) - : character(c), position(pos), weight(w) {} - }; - - // Analyze pattern for optimal comparison order - vector computeComparisonOrder(const string& pattern) { - vector charInfo; - - // Calculate character frequencies and positions - unordered_map frequency; - for (int i = 0; i < pattern.length(); i++) { - frequency[pattern[i]]++; - } - - // Create character information with weights - for (int i = 0; i < pattern.length(); i++) { - double weight = (1.0 - (double)frequency[pattern[i]] / - pattern.length()) * (pattern.length() - i); - charInfo.emplace_back(pattern[i], i, weight); - } - - // Sort based on weights (higher weight = earlier comparison) - sort(charInfo.begin(), charInfo.end(), - [](const CharacterInfo& a, const CharacterInfo& b) { - return a.weight > b.weight; - }); - - // Extract comparison order - vector order; - for (const auto& info : charInfo) { - order.push_back(info.position); - } - - return order; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Compute optimal comparison order - vector comparisonOrder = computeComparisonOrder(pattern); - - // Searching phase - for (int i = 0; i <= n - m; i++) { - bool match = true; - - // Compare characters in optimal order - for (int orderIndex : comparisonOrder) { - if (text[i + orderIndex] != pattern[orderIndex]) { - match = false; - break; - } - } - - if (match) { - matches.push_back(i); - } - } - - return matches; - } - - // Advanced search with additional optimizations - vector advancedSearch(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Compute optimal comparison order - vector comparisonOrder = computeComparisonOrder(pattern); - - // Create character occurrence map - vector isPatternChar(256, false); - for (char c : pattern) { - isPatternChar[c] = true; - } - - // First character in comparison order - int firstCheckPos = comparisonOrder[0]; - char firstCheckChar = pattern[firstCheckPos]; - - // Searching phase with optimizations - for (int i = 0; i <= n - m; i++) { - // Quick check for first character in optimal order - if (!isPatternChar[text[i + firstCheckPos]]) { - i += firstCheckPos; - continue; - } - - if (text[i + firstCheckPos] != firstCheckChar) { - continue; - } - - bool match = true; - // Compare remaining characters in optimal order - for (int j = 1; j < comparisonOrder.size(); j++) { - int pos = comparisonOrder[j]; - if (text[i + pos] != pattern[pos]) { - match = false; - break; - } - } - - if (match) { - matches.push_back(i); - } - } - - return matches; - } - - // Get comparison order for analysis - vector getComparisonOrder(const string& pattern) { - return computeComparisonOrder(pattern); - } -}; - -// Demonstration class -class OptimalMismatchDemo { -public: - static void demonstrateAlgorithm() { - OptimalMismatchAlgorithm algo; - - // Example 1: Basic pattern matching - string text = "ABAABAABAABAAB"; - string pattern = "ABAAB"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - // Show comparison order - vector order = algo.getComparisonOrder(pattern); - cout << "\nOptimal comparison order: "; - for (int pos : order) { - cout << pos << " "; - } - cout << endl; - - // Basic search - vector matches = algo.search(text, pattern); - cout << "Basic search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Advanced search - matches = algo.advancedSearch(text, pattern); - cout << "Advanced search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Example 2: Pattern with varying character frequencies - text = "ABCDEFABCDEFABCDEF"; - pattern = "DEFABC"; - cout << "\nText: " << text << endl; - cout << "Pattern: " << pattern << endl; - - order = algo.getComparisonOrder(pattern); - cout << "Optimal comparison order: "; - for (int pos : order) { - cout << pos << " "; - } - cout << endl; - - matches = algo.advancedSearch(text, pattern); - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - OptimalMismatchDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Optimal Comparison Ordering**: - - Statistical analysis - - Probability-based decisions - - Position weighting - -2. **Pattern Analysis**: - - Character frequency analysis - - Position importance - - Pattern structure study - -3. **Efficient Processing**: - - Early termination - - Optimal comparison sequence - - Statistical optimization - -### Applications: - -1. **Pattern Matching**: - - Optimized text search - - Pattern detection - - String matching - -2. **Text Analysis**: - - Content scanning - - Pattern recognition - - Text processing - -3. **Data Filtering**: - - Pattern-based filtering - - Content validation - - String searching - -4. **Performance Optimization**: - - Search optimization - - Comparison reduction - - Processing efficiency - -### Advanced Features: - -1. **Algorithm Variants**: - - Enhanced statistical analysis - - Dynamic order adjustment - - Multiple pattern support - -2. **Implementation Optimizations**: - - Character frequency caching - - Position importance weighting - - Early termination strategies - -### Performance Characteristics: - -1. **Best Case**: - - O(n/m) comparisons - - Early mismatch detection - - Optimal ordering benefit - -2. **Average Case**: - - Reduced comparisons - - Statistical efficiency - - Pattern-dependent performance - -3. **Worst Case**: - - O(nm) comparisons - - Pattern dependent - - Still maintains optimization - -### Summary: - -The Optimal Mismatch Algorithm represents an intelligent approach to pattern matching by utilizing statistical analysis and probability-based decisions to optimize character comparison order. Its ability to minimize the average number of comparisons makes it particularly efficient for patterns with varying character distributions. - -The algorithm's strength lies in its statistical approach to determining the most efficient comparison sequence, potentially reducing the number of comparisons needed to identify mismatches. The implementation provides both basic and advanced features for optimal pattern matching performance. - -The practical applications of this algorithm are particularly relevant in scenarios where pattern matching performance is crucial and patterns have distinct character frequency distributions. Its optimization techniques make it valuable for situations requiring efficient string matching with minimal average-case comparisons. - -The algorithm's combination of statistical analysis and optimization techniques makes it a sophisticated choice for pattern matching tasks where reducing the number of character comparisons is a priority, while still maintaining reasonable implementation complexity. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/quick-search-algorithm.md b/docs/algorithms/string-algorithms/quick-search-algorithm.md deleted file mode 100644 index e925b1e72..000000000 --- a/docs/algorithms/string-algorithms/quick-search-algorithm.md +++ /dev/null @@ -1,313 +0,0 @@ ---- - -id: quick-search-algorithm -sidebar_position: 26 -title: Quick Search Algorithm -sidebar_label: Quick Search Algorithm - ---- - -### Definition: - -The Quick Search Algorithm is a string matching algorithm that extends the Boyer-Moore approach by examining the character immediately following the current pattern window. It simplifies the bad character rule by only looking at the character after the current window position, making it particularly efficient for short patterns. - -### Characteristics: - -- **Next Character Rule**: - - Examines character after window - - Simplified bad character rule - - Quick shift calculation - -- **Preprocessing Phase**: - - Simple shift table - - Character-based lookup - - Efficient computation - -- **Right-to-Left Scanning**: - - Pattern comparison - - Next character analysis - - Efficient shifting - -- **Simple Implementation**: - - Minimal preprocessing - - Straightforward logic - - Easy maintenance - -### Time Complexity: - -- **Preprocessing: $O(m + σ)$** - - Where m is pattern length - - σ is alphabet size - - One-time computation - -- **Searching: $O(m \times n)$** - - Where n is text length - - Better average case - - Pattern-dependent performance - -### Space Complexity: - -- **Space Usage: $O(σ)$** - - Shift table storage - - Character-based indices - - Constant pattern space - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class QuickSearchAlgorithm { -private: - static const int ALPHABET_SIZE = 256; - - // Compute the bad character shift table - vector computeShiftTable(const string& pattern) { - int m = pattern.length(); - vector shift(ALPHABET_SIZE, m + 1); - - // Fill the shift table - for (int i = 0; i < m; i++) { - shift[pattern[i]] = m - i; - } - - return shift; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocessing - vector shift = computeShiftTable(pattern); - - // Searching phase - int pos = 0; - while (pos <= n - m) { - int i = 0; - - // Check pattern match - while (i < m && pattern[i] == text[pos + i]) { - i++; - } - - if (i == m) { - // Pattern found - matches.push_back(pos); - } - - // Calculate shift using character after the window - if (pos + m < n) { - pos += shift[text[pos + m]]; - } else { - break; - } - } - - return matches; - } - - // Advanced search with additional optimizations - vector advancedSearch(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocessing - vector shift = computeShiftTable(pattern); - - // Character occurrence map - vector patternChars(ALPHABET_SIZE, false); - for (char c : pattern) { - patternChars[c] = true; - } - - // First and last characters of pattern - char firstChar = pattern[0]; - char lastChar = pattern[m - 1]; - - // Searching phase with optimizations - int pos = 0; - while (pos <= n - m) { - // Quick check for first and last characters - if (text[pos] == firstChar && text[pos + m - 1] == lastChar) { - int i = 1; - while (i < m - 1 && pattern[i] == text[pos + i]) { - i++; - } - - if (i == m - 1) { - matches.push_back(pos); - } - } - - // Calculate shift using next character - if (pos + m < n) { - char nextChar = text[pos + m]; - // Additional optimization: if next character not in pattern - if (!patternChars[nextChar]) { - pos += m + 1; - } else { - pos += shift[nextChar]; - } - } else { - break; - } - } - - return matches; - } - - // Visualize shift table - void printShiftTable(const string& pattern) { - vector shift = computeShiftTable(pattern); - cout << "Shift Table (showing non-default values):" << endl; - for (int i = 0; i < ALPHABET_SIZE; i++) { - if (shift[i] != pattern.length() + 1) { - cout << (char)i << ": " << shift[i] << endl; - } - } - } -}; - -// Demonstration class -class QuickSearchDemo { -public: - static void demonstrateAlgorithm() { - QuickSearchAlgorithm algo; - - // Example 1: Basic pattern matching - string text = "GCATCGCAGAGAGTATACAGTACG"; - string pattern = "GCAGAGAG"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - // Show shift table - cout << "\nShift table for pattern:" << endl; - algo.printShiftTable(pattern); - - // Basic search - vector matches = algo.search(text, pattern); - cout << "\nBasic search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Advanced search - matches = algo.advancedSearch(text, pattern); - cout << "Advanced search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Example 2: Short pattern - text = "ABCABCDABABCDABCDABDE"; - pattern = "ABCD"; - cout << "\nText: " << text << endl; - cout << "Pattern: " << pattern << endl; - - matches = algo.advancedSearch(text, pattern); - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - QuickSearchDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Next Character Rule**: - - Simple shift calculation - - Efficient character skipping - - Pattern-based shifting - -2. **Efficient Preprocessing**: - - Simple shift table - - Character-based lookup - - Fast computation - -3. **Optimized Implementation**: - - Early termination checks - - Character occurrence filtering - - Quick shift decisions - -### Applications: - -1. **Text Processing**: - - Pattern matching - - Text search - - Document scanning - -2. **String Searching**: - - Content filtering - - Pattern detection - - Text analysis - -3. **Data Analysis**: - - Pattern recognition - - Content searching - - String matching - -4. **Real-time Processing**: - - Quick text search - - Stream processing - - Interactive applications - -### Advanced Features: - -1. **Algorithm Variants**: - - Enhanced character checking - - Multiple pattern support - - Case-insensitive matching - -2. **Implementation Optimizations**: - - Character filtering - - Early termination - - Efficient shifting - -### Performance Characteristics: - -1. **Best Case**: - - O(n/m) comparisons - - Efficient character skipping - - Quick pattern detection - -2. **Average Case**: - - Better than Boyer-Moore - - Reduced comparisons - - Efficient for short patterns - -3. **Worst Case**: - - O(mn) comparisons - - Pattern dependent - - Still maintains efficiency - -### Summary: - -The Quick Search Algorithm represents a practical simplification of the Boyer-Moore approach, focusing on the character following the current window for shift calculations. Its straightforward implementation and efficient performance make it particularly suitable for short patterns and real-time applications. - -The algorithm's strength lies in its simplified shifting strategy and minimal preprocessing requirements. While maintaining good average-case performance, it reduces implementation complexity compared to more sophisticated string matching algorithms. - -The practical applications range from basic text searching to real-time pattern matching scenarios. Its efficiency with short patterns and simple implementation make it a valuable choice for applications where implementation simplicity and quick pattern matching are priorities. - -The algorithm's balance of performance and simplicity makes it an excellent choice for many practical string matching applications, particularly when dealing with short patterns or requiring straightforward implementation. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/rabin-karp-algorithm.md b/docs/algorithms/string-algorithms/rabin-karp-algorithm.md deleted file mode 100644 index 2701df0d5..000000000 --- a/docs/algorithms/string-algorithms/rabin-karp-algorithm.md +++ /dev/null @@ -1,276 +0,0 @@ ---- - -id: rabin-karp-algorithm -sidebar_position: 13 -title: Rabin-Karp Algorithm -sidebar_label: Rabin-Karp Algorithm - ---- - -### Definition: - -The Rabin-Karp Algorithm is a string searching algorithm developed by Michael O. Rabin and Richard M. Karp in 1987. It uses hashing to efficiently find exact string matches or multiple pattern matches within a text. The algorithm is particularly effective for multiple pattern matching and plagiarism detection due to its ability to efficiently compute rolling hashes. - -### Characteristics: - -- **Rolling Hash Function**: - - Computes pattern hash value - - Updates hash efficiently - - Uses sliding window technique - -- **Multiple Pattern Matching**: - - Handles multiple patterns simultaneously - - Efficient for plagiarism detection - - Scales well with pattern count - -- **Preprocessing Phase**: - - Calculates pattern hash - - Prepares rolling hash - - Sets up modular arithmetic - -- **Left-to-Right Scanning**: - - Sequential text processing - - Constant-time hash updates - - Efficient window sliding - -### Time Complexity: - -- **Preprocessing: $O(m)$** - - Where m is pattern length - - Hash computation - - One-time calculation - -- **Searching: $O(m \times n)$** - - Where n is text length - - Average case: O(n + m) - - Worst case with spurious hits - -### Space Complexity: - -- **Space Usage: $O(1)$** - - Constant extra space - - Rolling hash storage - - Pattern hash storage - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class RabinKarpAlgorithm { -private: - // Large prime number for hash calculation - static const int PRIME = 101; - static const int ALPHABET_SIZE = 256; - - // Calculate hash value for a string - long long calculateHash(const string& str, int length) { - long long hash = 0; - for (int i = 0; i < length; i++) { - hash += str[i] * pow(PRIME, i); - } - return hash; - } - - // Calculate new rolling hash from previous hash - long long recalculateHash(long long oldHash, char oldChar, - char newChar, int patternLength, - long long powValue) { - oldHash -= oldChar; - oldHash /= PRIME; - oldHash += newChar * pow(PRIME, patternLength - 1); - return oldHash; - } - - // Check if two strings match - bool checkStrings(const string& text, const string& pattern, - int start) { - for (int i = 0; i < pattern.length(); i++) { - if (text[start + i] != pattern[i]) { - return false; - } - } - return true; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Calculate pattern hash - long long patternHash = calculateHash(pattern, m); - - // Calculate hash for first window of text - long long textHash = calculateHash(text, m); - - // Power value for rolling hash calculation - long long powValue = pow(PRIME, m - 1); - - // Slide pattern over text - for (int i = 0; i <= n - m; i++) { - if (patternHash == textHash) { - // Verify character by character on hash match - if (checkStrings(text, pattern, i)) { - matches.push_back(i); - } - } - - // Calculate hash for next window - if (i < n - m) { - textHash = recalculateHash(textHash, text[i], - text[i + m], m, powValue); - } - } - - return matches; - } - - // Function for multiple pattern search - vector> multiPatternSearch(const string& text, - const vector& patterns) { - vector> allMatches; - for (const string& pattern : patterns) { - allMatches.push_back(search(text, pattern)); - } - return allMatches; - } -}; - -// Demonstration class -class RabinKarpDemo { -public: - static void demonstrateSearch() { - RabinKarpAlgorithm algo; - string text = "ABCCDDAEFGABCDABCDABDE"; - string pattern = "ABCD"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - vector matches = algo.search(text, pattern); - - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Demonstrate multiple pattern matching - vector patterns = {"ABCD", "CDD", "EFG"}; - cout << "\nMultiple Pattern Matching:" << endl; - vector> multiMatches = - algo.multiPatternSearch(text, patterns); - - for (size_t i = 0; i < patterns.size(); i++) { - cout << "Pattern '" << patterns[i] << "' found at: "; - for (int pos : multiMatches[i]) { - cout << pos << " "; - } - cout << endl; - } - } -}; - -int main() { - RabinKarpDemo::demonstrateSearch(); - return 0; -} -``` - -### Key Features: - -1. **Rolling Hash Function**: - - Constant-time updates - - Efficient sliding window - - Modular arithmetic - -2. **Multiple Pattern Support**: - - Simultaneous pattern matching - - Hash-based comparison - - Scalable matching - -3. **Optimization Techniques**: - - Efficient hash computation - - Quick hash updates - - Spurious hit handling - -### Applications: - -1. **Text Analysis**: - - Plagiarism detection - - Document similarity - - Content comparison - -2. **Bioinformatics**: - - DNA pattern matching - - Multiple sequence alignment - - Genomic pattern search - -3. **Network Security**: - - Network packet inspection - - Pattern-based filtering - - Signature detection - -4. **Information Retrieval**: - - Document indexing - - Content searching - - Pattern identification - -### Advanced Features: - -1. **Algorithm Variants**: - - Multiple pattern matching - - Approximate matching - - Parallel implementations - -2. **Implementation Optimizations**: - - Efficient hash functions - - Memory-efficient versions - - Cache-friendly variants - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Efficient multiple pattern matching - - Simple implementation - - Good average-case performance - -2. **Trade-offs**: - - Hash collision possibility - - Worst-case performance - - Mathematical overhead - -### Performance Characteristics: - -1. **Best Case**: - - O(n + m) comparisons - - No spurious hits - - Efficient hash matches - -2. **Average Case**: - - O(n + m) expected time - - Few spurious hits - - Practical efficiency - -3. **Worst Case**: - - O(mn) with many collisions - - Rare in practice - - Hash function dependent - -### Summary: - -The Rabin-Karp Algorithm represents a unique approach to string matching by leveraging the power of hashing techniques. Its primary strength lies in its ability to efficiently handle multiple pattern matching scenarios, making it particularly valuable in applications such as plagiarism detection and content analysis. - -The algorithm's efficiency stems from its use of rolling hash functions, which allow for constant-time updates as the pattern window slides through the text. While hash collisions can theoretically lead to worst-case performance, proper implementation and choice of hash function make such cases rare in practice. - -The implementation provides a robust foundation for both single and multiple pattern matching tasks, with the flexibility to be optimized for specific use cases. The algorithm's simple yet effective approach, combined with its practical performance characteristics, makes it a valuable tool in various text processing applications, especially those involving multiple pattern matching or content similarity analysis. - -The Rabin-Karp Algorithm's unique characteristics make it particularly well-suited for specialized applications where multiple pattern matching or content similarity detection is required, complementing other string matching algorithms in the broader landscape of text processing solutions. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/reverse-factor-algorithm.md b/docs/algorithms/string-algorithms/reverse-factor-algorithm.md deleted file mode 100644 index 4e8f6c5b4..000000000 --- a/docs/algorithms/string-algorithms/reverse-factor-algorithm.md +++ /dev/null @@ -1,345 +0,0 @@ ---- - -id: reverse-factor-algorithm -sidebar_position: 28 -title: Reverse Factor Algorithm -sidebar_label: Reverse Factor Algorithm - ---- - -### Definition: - -The Reverse Factor Algorithm is a string matching algorithm that utilizes suffix automaton concepts for pattern matching. It processes the pattern from right to left and builds a suffix automaton to efficiently identify matches. The algorithm is particularly effective for patterns with repeated suffixes. - -### Characteristics: - -- **Suffix Automaton**: - - State machine construction - - Suffix links - - Transition function - -- **Right-to-Left Processing**: - - Reverse pattern scanning - - Suffix-based matching - - Efficient state transitions - -- **Pattern Analysis**: - - Suffix structure - - State computation - - Transition table - -- **State Management**: - - Automaton states - - Transition tracking - - Match detection - -### Time Complexity: - -- **Preprocessing: $O(m)$** - - Where m is pattern length - - Automaton construction - - State computation - -- **Searching: $O(n)$** - - Where n is text length - - Linear scan - - State transitions - -### Space Complexity: - -- **Space Usage: $O(m|Σ|)$** - - Where |Σ| is alphabet size - - State information - - Transition table - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -#include -using namespace std; - -class ReverseFactor { -private: - struct State { - map transitions; - int suffixLink; - int length; - bool isFinal; - - State() : suffixLink(-1), length(0), isFinal(false) {} - }; - - vector automaton; - string pattern; - int states; - - // Build suffix automaton for reversed pattern - void buildAutomaton() { - automaton.clear(); - automaton.resize(2 * pattern.length()); - states = 0; - - // Initialize first state - automaton.push_back(State()); - states++; - - int last = 0; - // Process pattern from right to left - for (int i = pattern.length() - 1; i >= 0; i--) { - char c = pattern[i]; - - // Create new state - int current = states++; - automaton.push_back(State()); - automaton[current].length = automaton[last].length + 1; - - // Add transition from last to current state - int p = last; - while (p != -1 && !automaton[p].transitions.count(c)) { - automaton[p].transitions[c] = current; - p = automaton[p].suffixLink; - } - - if (p == -1) { - automaton[current].suffixLink = 0; - } else { - int q = automaton[p].transitions[c]; - if (automaton[p].length + 1 == automaton[q].length) { - automaton[current].suffixLink = q; - } else { - // Clone state - int clone = states++; - automaton.push_back(State()); - automaton[clone] = automaton[q]; - automaton[clone].length = automaton[p].length + 1; - - while (p != -1 && automaton[p].transitions[c] == q) { - automaton[p].transitions[c] = clone; - p = automaton[p].suffixLink; - } - - automaton[q].suffixLink = automaton[current].suffixLink = clone; - } - } - - last = current; - } - - // Mark final states - int state = last; - while (state != -1) { - automaton[state].isFinal = true; - state = automaton[state].suffixLink; - } - } - -public: - vector search(const string& text, const string& pat) { - vector matches; - pattern = pat; - - if (pattern.empty() || text.empty()) return matches; - - // Build automaton for reversed pattern - buildAutomaton(); - - // Searching phase - int state = 0; - for (int i = 0; i <= text.length() - pattern.length(); i++) { - state = 0; - bool matched = true; - - // Check pattern match from current position - for (int j = i + pattern.length() - 1; j >= i; j--) { - if (automaton[state].transitions.count(text[j])) { - state = automaton[state].transitions[text[j]]; - } else { - matched = false; - break; - } - } - - if (matched && automaton[state].isFinal) { - matches.push_back(i); - } - } - - return matches; - } - - // Advanced search with optimizations - vector advancedSearch(const string& text, const string& pat) { - vector matches; - pattern = pat; - - if (pattern.empty() || text.empty()) return matches; - - // Build automaton - buildAutomaton(); - - // Precompute character occurrence in pattern - vector patternChars(256, false); - for (char c : pattern) { - patternChars[c] = true; - } - - // Searching with optimizations - int state = 0; - for (int i = 0; i <= text.length() - pattern.length(); i++) { - // Quick check for pattern characters - if (!patternChars[text[i]]) { - continue; - } - - state = 0; - bool matched = true; - - // Check pattern match with early termination - for (int j = i + pattern.length() - 1; j >= i; j--) { - if (!automaton[state].transitions.count(text[j])) { - matched = false; - break; - } - state = automaton[state].transitions[text[j]]; - } - - if (matched && automaton[state].isFinal) { - matches.push_back(i); - } - } - - return matches; - } -}; - -// Demonstration class -class ReverseFactorDemo { -public: - static void demonstrateAlgorithm() { - ReverseFactor algo; - - // Example 1: Basic pattern matching - string text = "ACACABAACACABACACA"; - string pattern = "ACABA"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - // Basic search - vector matches = algo.search(text, pattern); - cout << "\nBasic search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Advanced search - matches = algo.advancedSearch(text, pattern); - cout << "Advanced search - Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Example 2: Pattern with repeating suffixes - text = "ABCABCABCABC"; - pattern = "ABCABC"; - cout << "\nText: " << text << endl; - cout << "Pattern: " << pattern << endl; - - matches = algo.advancedSearch(text, pattern); - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - ReverseFactorDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Suffix Automaton Construction**: - - Efficient state building - - Transition management - - Suffix link computation - -2. **Right-to-Left Processing**: - - Reverse pattern matching - - State transition optimization - - Efficient match detection - -3. **Optimized Implementation**: - - Character filtering - - Early termination - - State management - -### Applications: - -1. **Text Processing**: - - Pattern matching - - Suffix analysis - - Text searching - -2. **String Analysis**: - - Suffix detection - - Pattern recognition - - Text verification - -3. **Data Processing**: - - String matching - - Content filtering - - Pattern identification - -4. **Information Retrieval**: - - Document searching - - Pattern detection - - Content analysis - -### Advanced Features: - -1. **Algorithm Variants**: - - Multiple pattern support - - Enhanced state management - - Optimized transitions - -2. **Implementation Optimizations**: - - Character filtering - - State caching - - Transition optimization - -### Performance Characteristics: - -1. **Best Case**: - - O(n) operations - - Efficient state transitions - - Quick pattern detection - -2. **Average Case**: - - Linear time performance - - Efficient matching - - State-based optimization - -3. **Worst Case**: - - O(n) comparisons - - Linear scan guarantee - - Predictable performance - -### Summary: - -The Reverse Factor Algorithm represents a sophisticated approach to string matching using suffix automaton concepts. Its ability to process patterns from right to left and utilize state transitions makes it particularly effective for patterns with repeated suffixes. - -The algorithm's strength lies in its efficient state machine construction and transition management, enabling quick pattern matching through state transitions. The implementation provides both basic and optimized versions for different use cases. - -The practical applications of this algorithm extend to various text processing scenarios where suffix-based pattern matching is beneficial. Its linear time complexity and efficient state management make it particularly valuable for specific pattern matching requirements. - -The algorithm's combination of suffix automaton concepts and right-to-left processing provides a unique approach to pattern matching, making it especially useful in scenarios where traditional left-to-right algorithms might be less efficient. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/shift-or-algorithm.md b/docs/algorithms/string-algorithms/shift-or-algorithm.md deleted file mode 100644 index 0c8cf1def..000000000 --- a/docs/algorithms/string-algorithms/shift-or-algorithm.md +++ /dev/null @@ -1,100 +0,0 @@ ---- - -id: shift-or-algo -sidebar_position: 5 -title: Shift-Or Algorithm -sidebar_label: Shift-Or Algorithm - ---- - -### Definition: - -The Shift-Or algorithm, also known as the **Bitap algorithm for exact matching**, is a string matching technique that uses bitwise operations to perform efficient pattern searching. It is particularly suitable for exact matching tasks and handles fixed-length patterns by representing them as bitmasks. The algorithm processes the text and the pattern in parallel, allowing for quick and efficient searches. - -### Characteristics: - -- **Bitwise Matching**: - - The Shift-Or algorithm encodes the search pattern as a set of bitmasks, where each bit represents whether a character in the text matches a position in the pattern. This allows multiple pattern positions to be checked simultaneously using bitwise operations. - -- **Exact Matching**: - - The algorithm is designed for exact string matching, where no mismatches, insertions, or deletions are allowed. It performs efficiently for small patterns. - -- **Compact Representation**: - - Shift-Or uses bitwise shifting to represent pattern states, providing a compact and efficient approach to handling pattern matching. - -- **Linear Time Complexity**: - - The algorithm processes the input text linearly, making it highly efficient for exact matching tasks, particularly when the pattern length is small compared to the text length. - -### Time Complexity: - -- **Best Case: $O\left(\frac{n}{w}\right)$** - In the best case, where `w` is the word size of the machine, the algorithm processes multiple characters in parallel, leading to a faster search in practice. - -- **Average Case: $O(n)$** - On average, the algorithm performs in linear time with respect to the text length `n`, as it makes a single pass through the text. - -- **Worst Case: $O(n)$** - Even in the worst-case scenario, the Shift-Or algorithm maintains linear time complexity since it processes each character of the text once. - -### Space Complexity: - -- **Space Complexity: $O(m)$** - The algorithm requires space proportional to the pattern length `m` to store bitmasks, making it space-efficient for small patterns. - -### C++ Implementation: - -**Exact Matching** -```cpp -#include -#include -#include -using namespace std; - -#define CHAR_SIZE 256 // Extended ASCII - -void preprocessPattern(const string& pattern, vector& patternMask) { - int m = pattern.size(); - for (int i = 0; i < CHAR_SIZE; ++i) { - patternMask[i] = ~0; // Initialize all bits to 1 - } - for (int i = 0; i < m; ++i) { - patternMask[pattern[i]] &= ~(1 << i); // Set bitmask for the pattern - } -} - -void shiftOrSearch(const string& text, const string& pattern) { - int n = text.size(); - int m = pattern.size(); - - if (m > n) return; - - vector patternMask(CHAR_SIZE); - preprocessPattern(pattern, patternMask); - - int R = ~0; // All bits are initially set to 1 - int matchBit = 1 << (m - 1); // The bit that will indicate a match - - for (int i = 0; i < n; ++i) { - // Update the state - R = (R << 1) | patternMask[text[i]]; - - // If the matchBit is 0, a match is found - if ((R & matchBit) == 0) { - cout << "Pattern found at index " << i - m + 1 << endl; - } - } -} - -int main() { - string text = "abracadabra"; - string pattern = "abra"; - - shiftOrSearch(text, pattern); - - return 0; -} -``` - -### Summary: - -The Shift-Or algorithm is a highly efficient and compact exact string matching technique, using bitwise operations to process the text and the pattern in parallel. Its linear time complexity makes it ideal for exact matching tasks, especially for small patterns. With its ability to perform pattern matching using simple bitwise operations, the Shift-Or algorithm offers both speed and simplicity, making it a solid choice for exact string matching problems. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/simon-algorithm.md b/docs/algorithms/string-algorithms/simon-algorithm.md deleted file mode 100644 index 4501fc7f7..000000000 --- a/docs/algorithms/string-algorithms/simon-algorithm.md +++ /dev/null @@ -1,302 +0,0 @@ ---- - -id: simon-algorithm -sidebar_position: 18 -title: Simon Algorithm -sidebar_label: Simon Algorithm - ---- - -### Definition: - -While the Simon Algorithm is historically a quantum computing algorithm, this implementation focuses on the Shift-And Algorithm (also known as Bitap), which is a practical string matching algorithm using bit-parallel operations. The algorithm uses bitwise operations to efficiently find exact and approximate pattern matches in a text string. - -### Characteristics: - -- **Bit-Parallel Processing**: - - Uses bit manipulation - - Parallel character matching - - Efficient state tracking - -- **Pattern Preprocessing**: - - Bit mask creation - - Character position encoding - - State transition preparation - -- **Exact Matching**: - - Bitwise AND operations - - State vector updates - - Pattern occurrence tracking - -- **Fuzzy Matching Support**: - - Handles k-mismatches - - Approximate matching - - Error tolerance - -### Time Complexity: - -- **Preprocessing: $O(m + σ)$** - - Where m is pattern length - - σ is alphabet size - - One-time computation - -- **Searching: $O(n)$** - - Where n is text length - - Constant-time operations - - Bit-parallel efficiency - -### Space Complexity: - -- **Space Usage: $O(σ)$** - - Character mask storage - - Pattern information - - State vectors - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class ShiftAndAlgorithm { -private: - static const int MAXCHAR = 256; - static const size_t WORD_SIZE = sizeof(unsigned long long) * 8; - - // Preprocess pattern to create bit masks - unordered_map createMasks( - const string& pattern) { - unordered_map masks; - - for (int i = 0; i < pattern.length(); i++) { - unsigned long long mask = 1ULL << i; - masks[pattern[i]] |= mask; - } - - return masks; - } - -public: - // Find exact matches - vector findPattern(const string& text, const string& pattern) { - vector matches; - int m = pattern.length(); - int n = text.length(); - - if (m == 0 || m > WORD_SIZE) return matches; - - // Create character masks - auto masks = createMasks(pattern); - - // Initialize state - unsigned long long state = 0; - unsigned long long matchMask = 1ULL << (m - 1); - - // Process text - for (int i = 0; i < n; i++) { - // Update state using bit operations - state = ((state << 1) | 1ULL) & - (masks[text[i]] | masks[text[i] + 32] | - masks[text[i] - 32]); - - // Check for match - if (state & matchMask) { - matches.push_back(i - m + 1); - } - } - - return matches; - } - - // Find approximate matches with k errors - vector findApproximatePattern(const string& text, - const string& pattern, - int k) { - vector matches; - int m = pattern.length(); - int n = text.length(); - - if (m == 0 || m > WORD_SIZE) return matches; - - // Create character masks - auto masks = createMasks(pattern); - - // Initialize states for k errors - vector states(k + 1, 0); - unsigned long long matchMask = 1ULL << (m - 1); - - // Process text - for (int i = 0; i < n; i++) { - // Store old states - unsigned long long oldState = states[0]; - unsigned long long charMask = masks[text[i]] | - masks[text[i] + 32] | - masks[text[i] - 32]; - - // Update state for exact match - states[0] = ((oldState << 1) | 1ULL) & charMask; - - // Update states for 1 to k errors - for (int e = 1; e <= k; e++) { - unsigned long long oldStateWithError = states[e]; - - // Substitution, deletion, and insertion - states[e] = (((oldState | oldStateWithError) << 1) | 1ULL) - & charMask | (oldStateWithError << 1) | - (oldState << 1); - } - - // Check for matches with up to k errors - for (int e = 0; e <= k; e++) { - if (states[e] & matchMask) { - matches.push_back(i - m + 1); - break; - } - } - } - - return matches; - } -}; - -// Demonstration class -class ShiftAndDemo { -public: - static void demonstrateAlgorithm() { - ShiftAndAlgorithm algo; - string text = "The quick brown fox jumps over the lazy dog"; - string pattern = "fox"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - // Exact matching - vector matches = algo.findPattern(text, pattern); - cout << "\nExact matches found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Approximate matching - pattern = "fax"; - int k = 1; // Allow 1 error - cout << "\nSearching for '" << pattern << "' with " - << k << " error(s)" << endl; - matches = algo.findApproximatePattern(text, pattern, k); - cout << "Approximate matches found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Case-insensitive matching - pattern = "FOX"; - cout << "\nCase-insensitive search for '" << pattern << "'" << endl; - matches = algo.findPattern(text, pattern); - cout << "Matches found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - ShiftAndDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Bit-Parallel Operations**: - - Efficient character matching - - State management - - Parallel processing - -2. **Flexible Matching**: - - Exact pattern matching - - Approximate matching - - Case-insensitive search - -3. **Optimization Techniques**: - - Bit manipulation - - State compression - - Efficient updates - -### Applications: - -1. **Text Processing**: - - Spell checking - - Search utilities - - Text editors - -2. **Information Retrieval**: - - Document searching - - Pattern matching - - Fuzzy search - -3. **Bioinformatics**: - - DNA sequence matching - - Protein analysis - - Sequence alignment - -4. **Data Mining**: - - Pattern discovery - - Text analysis - - Content filtering - -### Advanced Features: - -1. **Algorithm Variants**: - - Multiple pattern matching - - Regular expression matching - - Unicode support - -2. **Implementation Optimizations**: - - SIMD operations - - Cache optimization - - Memory efficiency - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Fast bit operations - - Built-in fuzzy matching - - Simple implementation - -2. **Trade-offs**: - - Pattern length limitation - - Memory access patterns - - Preprocessing overhead - -### Performance Characteristics: - -1. **Best Case**: - - O(n) operations - - Constant-time updates - - Efficient bit parallel - -2. **Average Case**: - - Linear time performance - - Predictable behavior - - Consistent speed - -3. **Worst Case**: - - O(n) guaranteed - - Pattern length bounded - - Stable performance - -### Summary: - -The Simon represents an efficient approach to string matching using bit-parallel operations. Its ability to handle both exact and approximate matching makes it particularly versatile for text processing applications. - -The algorithm's strength lies in its use of bitwise operations for parallel pattern matching, enabling efficient processing of text while supporting features like case-insensitive matching and error tolerance. The implementation provides both exact and approximate matching capabilities, making it suitable for various text processing needs. - -The practical applications range from simple text searches to more complex approximate matching scenarios, including spell checking and DNA sequence analysis. Its efficient implementation and support for fuzzy matching make it a valuable tool in modern text processing applications. - -The algorithm's limitations, such as pattern length restrictions, are offset by its speed and simplicity in implementation, making it a practical choice for many string matching applications where bit-parallel operations can be effectively utilized. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/smith-waterman-algorithm.md b/docs/algorithms/string-algorithms/smith-waterman-algorithm.md deleted file mode 100644 index 0eb9bd7c3..000000000 --- a/docs/algorithms/string-algorithms/smith-waterman-algorithm.md +++ /dev/null @@ -1,322 +0,0 @@ ---- - -id: smith-waterman-algorithm -sidebar_position: 21 -title: Smith-Waterman Algorithm -sidebar_label: Smith-Waterman Algorithm - ---- - -### Definition: - -The Smith-Waterman Algorithm is a dynamic programming algorithm for local sequence alignment, calculating the optimal local alignment between two strings. Developed by Temple F. Smith and Michael S. Waterman in 1981, it identifies similar regions between sequences by comparing segments of all possible lengths and optimizing similarity scores. - -### Characteristics: - -- **Local Alignment**: - - Identifies similar subsequences - - Allows partial matches - - Optimizes local regions - -- **Scoring System**: - - Match/mismatch scores - - Gap penalties - - Customizable scoring matrix - -- **Dynamic Programming**: - - Matrix computation - - Optimal substructure - - Traceback mechanism - -- **Alignment Recovery**: - - Path reconstruction - - Maximum score tracking - - Alignment visualization - -### Time Complexity: - -- **Matrix Computation: $O(m \times n)$** - - Where m, n are sequence lengths - - Full matrix calculation - - Traceback included - -### Space Complexity: - -- **Standard Version: $O(m \times n)$** - - Scoring matrix - - Traceback information - - Alignment storage - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class SmithWaterman { -private: - struct Cell { - int score; - int direction; // 0: none, 1: diagonal, 2: up, 3: left - - Cell() : score(0), direction(0) {} - }; - - int matchScore; - int mismatchScore; - int gapScore; - - // Scoring matrix computation - vector> computeMatrix(const string& seq1, - const string& seq2) { - int m = seq1.length(); - int n = seq2.length(); - vector> matrix(m + 1, vector(n + 1)); - int maxScore = 0; - - // Fill the matrix - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - // Calculate scores for all possibilities - int match = matrix[i-1][j-1].score + - (seq1[i-1] == seq2[j-1] ? matchScore : mismatchScore); - int del = matrix[i-1][j].score + gapScore; - int ins = matrix[i][j-1].score + gapScore; - - // Find maximum score - matrix[i][j].score = max({0, match, del, ins}); - - // Store traceback direction - if (matrix[i][j].score == 0) { - matrix[i][j].direction = 0; - } else if (matrix[i][j].score == match) { - matrix[i][j].direction = 1; - } else if (matrix[i][j].score == del) { - matrix[i][j].direction = 2; - } else { - matrix[i][j].direction = 3; - } - } - } - - return matrix; - } - - // Find position of maximum score - pair findMaxScore(const vector>& matrix) { - int maxScore = 0; - pair maxPos(0, 0); - - for (int i = 0; i < matrix.size(); i++) { - for (int j = 0; j < matrix[0].size(); j++) { - if (matrix[i][j].score > maxScore) { - maxScore = matrix[i][j].score; - maxPos = {i, j}; - } - } - } - - return maxPos; - } - -public: - SmithWaterman(int match = 2, int mismatch = -1, int gap = -1) - : matchScore(match), mismatchScore(mismatch), gapScore(gap) {} - - struct AlignmentResult { - string alignedSeq1; - string alignedSeq2; - int score; - - void print() const { - cout << "Score: " << score << endl; - cout << "Alignment:" << endl; - cout << alignedSeq1 << endl; - string middle(alignedSeq1.length(), ' '); - for (size_t i = 0; i < alignedSeq1.length(); i++) { - if (alignedSeq1[i] == alignedSeq2[i]) { - middle[i] = '|'; - } - } - cout << middle << endl; - cout << alignedSeq2 << endl; - } - }; - - // Main alignment function - AlignmentResult align(const string& seq1, const string& seq2) { - vector> matrix = computeMatrix(seq1, seq2); - pair maxPos = findMaxScore(matrix); - - // Traceback - string aligned1, aligned2; - int i = maxPos.first; - int j = maxPos.second; - int score = matrix[i][j].score; - - while (i > 0 && j > 0 && matrix[i][j].score > 0) { - if (matrix[i][j].direction == 1) { - // Diagonal - aligned1 = seq1[i-1] + aligned1; - aligned2 = seq2[j-1] + aligned2; - i--; j--; - } else if (matrix[i][j].direction == 2) { - // Up - aligned1 = seq1[i-1] + aligned1; - aligned2 = '-' + aligned2; - i--; - } else if (matrix[i][j].direction == 3) { - // Left - aligned1 = '-' + aligned1; - aligned2 = seq2[j-1] + aligned2; - j--; - } - } - - return {aligned1, aligned2, score}; - } - - // Set custom scoring parameters - void setScoringParameters(int match, int mismatch, int gap) { - matchScore = match; - mismatchScore = mismatch; - gapScore = gap; - } - - // Get matrix for visualization - vector> getScoreMatrix(const string& seq1, - const string& seq2) { - auto matrix = computeMatrix(seq1, seq2); - vector> scores(matrix.size(), - vector(matrix[0].size())); - - for (size_t i = 0; i < matrix.size(); i++) { - for (size_t j = 0; j < matrix[0].size(); j++) { - scores[i][j] = matrix[i][j].score; - } - } - - return scores; - } -}; - -// Demonstration class -class SmithWatermanDemo { -public: - static void demonstrateAlgorithm() { - SmithWaterman algo(2, -1, -1); // match, mismatch, gap - - // Example 1: Simple DNA sequences - string seq1 = "ACGTACT"; - string seq2 = "ACGTACTA"; - - cout << "Sequence 1: " << seq1 << endl; - cout << "Sequence 2: " << seq2 << endl; - - auto result = algo.align(seq1, seq2); - result.print(); - - // Example 2: More complex alignment - seq1 = "AGTACGCAGT"; - seq2 = "AGCTACGT"; - cout << "\nSequence 1: " << seq1 << endl; - cout << "Sequence 2: " << seq2 << endl; - - result = algo.align(seq1, seq2); - result.print(); - - // Example 3: Different scoring parameters - cout << "\nWith different scoring parameters " - << "(match=3, mismatch=-2, gap=-2):" << endl; - algo.setScoringParameters(3, -2, -2); - result = algo.align(seq1, seq2); - result.print(); - } -}; - -int main() { - SmithWatermanDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Scoring System**: - - Customizable parameters - - Gap penalties - - Match/mismatch scores - -2. **Matrix Operations**: - - Dynamic programming matrix - - Traceback information - - Score optimization - -3. **Alignment Features**: - - Local alignment focus - - Multiple solutions handling - - Visual alignment output - -### Applications: - -1. **Bioinformatics**: - - DNA sequence alignment - - Protein sequence comparison - - Molecular analysis - -2. **Pattern Recognition**: - - Sequence similarity - - Pattern matching - - Motif discovery - -3. **Database Search**: - - Sequence databases - - Similarity search - - Homology detection - -4. **Sequence Analysis**: - - Mutation detection - - Evolutionary studies - - Comparative genomics - -### Advanced Features: - -1. **Algorithm Variants**: - - Affine gap penalties - - Multiple sequence alignment - - Memory-efficient versions - -2. **Implementation Optimizations**: - - SIMD instructions - - Parallel processing - - Memory management - -### Performance Characteristics: - -1. **Best Case**: - - O(mn) operations - - Complete alignment - - Optimal solution - -2. **Average Case**: - - O(mn) operations - - Consistent performance - - Predictable behavior - -3. **Worst Case**: - - O(mn) operations - - Full matrix computation - - Space-time trade-off - -### Summary: - -The Smith-Waterman Algorithm represents a fundamental approach to local sequence alignment, providing optimal solutions for identifying similar regions between sequences. Its dynamic programming approach ensures the discovery of the best possible local alignments while allowing for customizable scoring schemes. - -The algorithm's strength lies in its ability to find optimal local alignments without being affected by the overall sequence similarity. The implementation provides both the core alignment functionality and additional features for visualization and analysis, making it suitable for various sequence comparison tasks. - -The practical applications of this algorithm extend from basic sequence comparison to complex biological sequence analysis. Its ability to handle gaps and mismatches while maintaining optimal local alignment makes it particularly valuable in bioinformatics and other fields where sequence similarity analysis is crucial. - -The algorithm's guarantee of finding the optimal local alignment, combined with its flexibility in scoring parameters, makes it a fundamental tool in sequence analysis, despite its computational complexity. Its continued relevance in modern applications demonstrates its importance in the field of sequence alignment and analysis. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/suffix-array-algorithm.md b/docs/algorithms/string-algorithms/suffix-array-algorithm.md deleted file mode 100644 index b45b0e3da..000000000 --- a/docs/algorithms/string-algorithms/suffix-array-algorithm.md +++ /dev/null @@ -1,349 +0,0 @@ ---- - -id: suffix-array-algorithm -sidebar_position: 17 -title: Suffix Array Algorithm -sidebar_label: Suffix Array Algorithm - ---- - -### Definition: - -The Suffix Array Algorithm is a space-efficient data structure that stores all suffixes of a string in lexicographically sorted order. Combined with the LCP (Longest Common Prefix) array, it provides efficient solutions for various string processing problems, including pattern matching, substring searches, and string analysis. - -### Characteristics: - -- **Lexicographical Sorting**: - - Orders all suffixes - - Maintains position information - - Enables binary search - -- **LCP Array**: - - Stores common prefix lengths - - Enhances string operations - - Supports efficient queries - -- **Construction Methods**: - - Multiple building approaches - - Trade-offs in complexity - - Optimization options - -- **Space Efficiency**: - - Linear space usage - - Implicit suffix storage - - Compact representation - -### Time Complexity: - -- **Construction: $O(n \times log n)$** - - Using standard sorting - - Can be O(n) with specialized algorithms - - Includes LCP array construction - -- **Pattern Matching: $O(m \times log n)$** - - Where m is pattern length - - Uses binary search - - Additional O(m) for verification - -### Space Complexity: - -- **Overall: $O(n)$** - - Suffix array storage - - LCP array (optional) - - Auxiliary space for construction - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class SuffixArray { -private: - string text; - vector suffixArray; - vector lcpArray; - - // Compute suffix array using prefix doubling - void buildSuffixArray() { - int n = text.length(); - vector rank(n); - vector tempRank(n); - vector,int>> pairs(n); - - // Initialize with single character ranks - for (int i = 0; i < n; i++) { - rank[i] = text[i]; - suffixArray[i] = i; - } - - for (int len = 1; len < n; len *= 2) { - // Create pairs for sorting - for (int i = 0; i < n; i++) { - pairs[i] = {{rank[i], - i + len < n ? rank[i + len] : -1}, i}; - } - - // Sort suffixes - sort(pairs.begin(), pairs.end()); - - // Update ranks - tempRank[pairs[0].second] = 0; - for (int i = 1; i < n; i++) { - tempRank[pairs[i].second] = tempRank[pairs[i-1].second]; - if (pairs[i].first != pairs[i-1].first) { - tempRank[pairs[i].second]++; - } - } - rank = tempRank; - - // Check if all ranks are unique - if (rank[pairs[n-1].second] == n-1) break; - } - - // Store final suffix array - for (int i = 0; i < n; i++) { - suffixArray[i] = pairs[i].second; - } - } - - // Compute LCP array using Kasai's algorithm - void buildLCPArray() { - int n = text.length(); - vector rank(n); - lcpArray.resize(n); - - // Compute rank array (inverse of suffix array) - for (int i = 0; i < n; i++) { - rank[suffixArray[i]] = i; - } - - int k = 0; // Length of previous LCP - for (int i = 0; i < n; i++) { - if (rank[i] == n-1) { - k = 0; - continue; - } - - int j = suffixArray[rank[i] + 1]; - - // Compute LCP - while (i + k < n && j + k < n && - text[i + k] == text[j + k]) { - k++; - } - - lcpArray[rank[i]] = k; - - if (k > 0) k--; - } - } - -public: - SuffixArray(const string& str) : text(str) { - suffixArray.resize(text.length()); - buildSuffixArray(); - buildLCPArray(); - } - - // Pattern matching using binary search - vector findPattern(const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - // Binary search for lower bound - int low = 0, high = n - 1; - while (low <= high) { - int mid = (low + high) / 2; - int cmp = text.compare(suffixArray[mid], m, pattern); - - if (cmp == 0) { - // Found a match, gather all occurrences - int start = mid; - while (start > 0 && - text.compare(suffixArray[start-1], m, pattern) == 0) { - start--; - } - int end = mid; - while (end < n-1 && - text.compare(suffixArray[end+1], m, pattern) == 0) { - end++; - } - - for (int i = start; i <= end; i++) { - matches.push_back(suffixArray[i]); - } - break; - } - - if (cmp < 0) { - low = mid + 1; - } else { - high = mid - 1; - } - } - - sort(matches.begin(), matches.end()); - return matches; - } - - // Get longest common prefix at position i - int getLCP(int i) { - return lcpArray[i]; - } - - // Get suffix array - const vector& getSuffixArray() const { - return suffixArray; - } - - // Get LCP array - const vector& getLCPArray() const { - return lcpArray; - } - - // Get all suffixes in sorted order - vector getAllSuffixes() { - vector suffixes; - for (int pos : suffixArray) { - suffixes.push_back(text.substr(pos)); - } - return suffixes; - } -}; - -// Demonstration class -class SuffixArrayDemo { -public: - static void demonstrateAlgorithm() { - string text = "banana$"; - SuffixArray sa(text); - - cout << "Text: " << text << endl; - - // Display suffix array - cout << "\nSuffix Array:" << endl; - vector suffixes = sa.getAllSuffixes(); - const vector& positions = sa.getSuffixArray(); - for (size_t i = 0; i < suffixes.size(); i++) { - cout << positions[i] << ": " << suffixes[i] << endl; - } - - // Display LCP array - cout << "\nLCP Array:" << endl; - const vector& lcp = sa.getLCPArray(); - for (size_t i = 0; i < lcp.size()-1; i++) { - cout << "LCP[" << i << "]: " << lcp[i] << endl; - } - - // Pattern matching demonstration - string pattern = "ana"; - cout << "\nSearching for pattern: " << pattern << endl; - vector matches = sa.findPattern(pattern); - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - SuffixArrayDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Efficient Construction**: - - Multiple building methods - - LCP array computation - - Rank array utilization - -2. **Pattern Matching Support**: - - Binary search capability - - Multiple occurrence handling - - Linear space usage - -3. **Enhanced Operations**: - - Longest common prefix queries - - Substring searches - - Lexicographical ordering - -### Applications: - -1. **String Processing**: - - Pattern matching - - Substring searches - - String analysis - -2. **Bioinformatics**: - - Genome sequence analysis - - DNA pattern matching - - Sequence comparison - -3. **Data Compression**: - - Burrows-Wheeler transform - - Text indexing - - Compression algorithms - -4. **Text Mining**: - - Document analysis - - String similarity - - Pattern discovery - -### Advanced Features: - -1. **Algorithm Variants**: - - DC3/Skew algorithm - - SA-IS algorithm - - Linear-time construction - -2. **Implementation Optimizations**: - - Cache-efficient versions - - Memory-optimized variants - - Parallel construction - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Space efficiency - - Fast pattern matching - - Versatile applications - -2. **Trade-offs**: - - Construction complexity - - Memory requirements - - Implementation complexity - -### Performance Characteristics: - -1. **Best Case**: - - O(n log n) construction - - O(m log n) pattern matching - - Linear space usage - -2. **Average Case**: - - Consistent performance - - Efficient pattern matching - - Predictable behavior - -3. **Worst Case**: - - O(n log n) construction - - O(m + log n) pattern matching - - Linear space requirement - -### Summary: - -The Suffix Array Algorithm represents a powerful and space-efficient approach to string processing and pattern matching. Its ability to store all suffixes in sorted order while maintaining linear space complexity makes it a valuable tool for various string-related applications. - -The algorithm's strength lies in its combination of space efficiency and fast pattern matching capabilities. When coupled with the LCP array, it provides enhanced functionality for string processing tasks, including longest common prefix queries and efficient substring searches. - -The implementation provides a comprehensive solution for string processing needs, offering pattern matching, suffix enumeration, and LCP queries. The algorithm's versatility and efficiency make it particularly valuable in applications ranging from text processing to bioinformatics, where efficient string operations are crucial. - -The ability to support various construction methods and optimizations allows for adaptation to specific use cases, while maintaining its fundamental efficiency in handling string-related operations. Its practical applications in data compression, text mining, and sequence analysis demonstrate its significance in modern computing applications. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/sunday-algorithm.md b/docs/algorithms/string-algorithms/sunday-algorithm.md deleted file mode 100644 index f336dddeb..000000000 --- a/docs/algorithms/string-algorithms/sunday-algorithm.md +++ /dev/null @@ -1,245 +0,0 @@ ---- - -id: sunday-algorithm -sidebar_position: 14 -title: Sunday Algorithm -sidebar_label: Sunday Algorithm - ---- - -### Definition: - -The Sunday Algorithm is a string matching algorithm developed by Daniel M. Sunday in 1990. It extends the Boyer-Moore approach by examining the character immediately following the pattern's alignment window to determine shift distances. This modification often results in larger shifts, making it particularly efficient for short patterns and large alphabets. - -### Characteristics: - -- **Next Character Rule**: - - Examines character after current window - - Determines maximum possible shift - - Enables larger jumps in text - -- **Shift Table**: - - Preprocesses pattern for shifts - - Character-based lookup - - Simple calculation method - -- **Preprocessing Phase**: - - Builds shift lookup table - - One-time computation - - Alphabet-dependent preprocessing - -- **Left-to-Right Pattern Comparison**: - - Pattern comparison from left - - Uses preprocessed shift values - - Efficient character skipping - -### Time Complexity: - -- **Preprocessing: $O(m + σ)$** - - Where m is pattern length - - σ is alphabet size - - One-time table construction - -- **Searching: $O(m \times n)$** - - Where n is text length - - Best case: O(n/m) - - Average case: sublinear - -### Space Complexity: - -- **Space Usage: $O(σ)$** - - Shift table storage - - Alphabet size dependent - - Constant pattern storage - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class SundayAlgorithm { -private: - // Compute the shift table for the pattern - unordered_map computeShiftTable(const string& pattern) { - unordered_map shiftTable; - int m = pattern.length(); - - // Initialize all characters with pattern length + 1 - for (int i = 0; i < 256; i++) { - shiftTable[i] = m + 1; - } - - // Fill the actual shifts for pattern characters - for (int i = 0; i < m; i++) { - shiftTable[pattern[i]] = m - i; - } - - return shiftTable; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocess pattern - unordered_map shiftTable = computeShiftTable(pattern); - - // Searching phase - int pos = 0; - while (pos <= n - m) { - int i = 0; - - // Try to match pattern at current position - while (i < m && pattern[i] == text[pos + i]) { - i++; - } - - if (i == m) { - // Pattern found - matches.push_back(pos); - } - - // Calculate shift based on next character - if (pos + m < n) { - pos += shiftTable[text[pos + m]]; - } else { - break; - } - } - - return matches; - } -}; - -// Demonstration class -class SundayDemo { -public: - static void demonstrateSearch() { - SundayAlgorithm algo; - string text = "GCATCGCAGAGAGTATACAGTACG"; - string pattern = "GCAGAGAG"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - vector matches = algo.search(text, pattern); - - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Demonstrate with different pattern - pattern = "TACG"; - cout << "\nSearching for pattern: " << pattern << endl; - matches = algo.search(text, pattern); - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - SundayDemo::demonstrateSearch(); - return 0; -} -``` - -### Key Features: - -1. **Next Character Rule**: - - Examines character beyond window - - Maximum possible shifts - - Efficient skip calculation - -2. **Shift Table**: - - Character-based lookup - - Simple preprocessing - - Efficient shift values - -3. **Optimization Techniques**: - - Quick character lookups - - Efficient shift calculation - - Minimal comparisons - -### Applications: - -1. **Text Processing**: - - Document searching - - Text editors - - Word processors - -2. **Pattern Matching**: - - String searching - - Content filtering - - Data analysis - -3. **Information Retrieval**: - - Document scanning - - Content indexing - - Pattern detection - -4. **Bioinformatics**: - - DNA sequence matching - - Protein pattern search - - Genomic analysis - -### Advanced Features: - -1. **Algorithm Variants**: - - Multiple pattern matching - - Case-insensitive matching - - Unicode support - -2. **Implementation Optimizations**: - - Cache-friendly versions - - Memory-efficient variants - - Parallel implementations - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Simpler implementation than Boyer-Moore - - Better average-case performance - - Larger shifts possible - -2. **Trade-offs**: - - Additional memory for shift table - - Pattern length dependent - - Alphabet size dependency - -### Performance Characteristics: - -1. **Best Case**: - - O(n/m) comparisons - - Maximum character skips - - Optimal shifting - -2. **Average Case**: - - Sublinear performance - - Efficient for short patterns - - Good practical speed - -3. **Worst Case**: - - O(mn) theoretical bound - - Rare in practice - - Still maintains efficiency - -### Summary: - -The Sunday Algorithm represents a practical improvement over traditional string matching algorithms through its innovative use of the next character rule. Its simplicity in implementation combined with efficient shifting makes it particularly effective for real-world applications, especially when dealing with short patterns and large alphabets. - -The algorithm's strength lies in its ability to determine shifts based on characters following the current window, often allowing it to skip more characters than algorithms like Boyer-Moore. While it maintains the same worst-case complexity as other string matching algorithms, its practical performance and ease of implementation make it a valuable choice for many text processing applications. - -The implementation provides a straightforward yet efficient approach to string matching, with the flexibility to be optimized for specific use cases. Its balanced combination of simplicity and performance, particularly for short patterns, makes it a practical choice in many string matching scenarios, complementing the broader family of string searching algorithms. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/turbo-boyer-moore-algorithm.md b/docs/algorithms/string-algorithms/turbo-boyer-moore-algorithm.md deleted file mode 100644 index 561867a41..000000000 --- a/docs/algorithms/string-algorithms/turbo-boyer-moore-algorithm.md +++ /dev/null @@ -1,313 +0,0 @@ ---- - -id: turbo-boyer-moore-algorithm -sidebar_position: 20 -title: Turbo Boyer-Moore Algorithm -sidebar_label: Turbo Boyer-Moore Algorithm - ---- - -### Definition: - -The Turbo Boyer-Moore Algorithm is an enhanced version of the classic Boyer-Moore algorithm that improves performance by utilizing information from previous comparisons. It reduces the number of character comparisons by remembering matched portions of the pattern and using this information for subsequent shifts. - -### Characteristics: - -- **Memory Utilization**: - - Stores previous match information - - Turbo shifting technique - - Factor-based optimization - -- **Enhanced Shifting**: - - Advanced bad character rule - - Improved good suffix rule - - Turbo shift calculation - -- **Pattern Analysis**: - - Preprocessing phase - - Factor recognition - - Match history tracking - -- **Efficient Scanning**: - - Right-to-left scanning - - Skip character technique - - Match factorization - -### Time Complexity: - -- **Preprocessing: $O(m + σ)$** - - Where m is pattern length - - σ is alphabet size - - One-time computation - -- **Searching: $O(n)$** - - Where n is text length - - Sublinear in practice - - Better than original Boyer-Moore - -### Space Complexity: - -- **Space Usage: $O(m + σ)$** - - Pattern storage - - Shift tables - - Match memory - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class TurboBoyerMoore { -private: - static const int ALPHABET_SIZE = 256; - - // Compute bad character rule - vector computeBadChar(const string& pattern) { - vector badChar(ALPHABET_SIZE, -1); - int m = pattern.length(); - - for (int i = 0; i < m; i++) { - badChar[pattern[i]] = i; - } - - return badChar; - } - - // Compute good suffix rule - vector computeGoodSuffix(const string& pattern) { - int m = pattern.length(); - vector goodSuffix(m + 1, 0); - vector suffix = computeSuffixArray(pattern); - - for (int i = 0; i < m; i++) { - goodSuffix[i] = m; - } - - for (int i = m - 1; i >= 0; i--) { - if (suffix[i] == i + 1) { - for (int j = 0; j < m - 1 - i; j++) { - if (goodSuffix[j] == m) { - goodSuffix[j] = m - 1 - i; - } - } - } - } - - for (int i = 0; i <= m - 2; i++) { - goodSuffix[m - 1 - suffix[i]] = m - 1 - i; - } - - return goodSuffix; - } - - // Compute suffix array - vector computeSuffixArray(const string& pattern) { - int m = pattern.length(); - vector suffix(m, m); - int g = m - 1; - int f = m - 1; - - for (int i = m - 2; i >= 0; i--) { - if (i > g && suffix[i + m - 1 - f] < i - g) { - suffix[i] = suffix[i + m - 1 - f]; - } else { - if (i < g) { - g = i; - } - f = i; - while (g >= 0 && pattern[g] == pattern[g + m - 1 - f]) { - g--; - } - suffix[i] = f - g; - } - } - - return suffix; - } - -public: - // Main search function - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0) return matches; - - // Preprocessing - vector badChar = computeBadChar(pattern); - vector goodSuffix = computeGoodSuffix(pattern); - - // Searching phase with turbo shift - int j = 0; // text position - while (j <= n - m) { - int i = m - 1; // pattern position - int lastMismatch = -1; - int turboShift = 0; - - // Right to left scan with memory - while (i >= 0 && lastMismatch == -1) { - if (pattern[i] != text[j + i]) { - lastMismatch = i; - } - i--; - } - - if (lastMismatch == -1) { - // Pattern found - matches.push_back(j); - turboShift = goodSuffix[0]; - } else { - // Calculate shifts - int bcShift = lastMismatch - badChar[text[j + lastMismatch]]; - int gsShift = goodSuffix[lastMismatch]; - turboShift = max(bcShift, gsShift); - - // Turbo shift optimization - if (lastMismatch < m - 1) { - turboShift = max(turboShift, - m - 1 - lastMismatch); - } - } - - j += turboShift; - } - - return matches; - } -}; - -// Demonstration class -class TurboDemo { -public: - static void demonstrateAlgorithm() { - TurboBoyerMoore algo; - string text = "GCATCGCAGAGAGTATACAGTACG"; - string pattern = "GCAGAGAG"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - vector matches = algo.search(text, pattern); - - cout << "\nPattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - - // Additional test case - text = "AABAACAADAABAAABAA"; - pattern = "AABA"; - cout << "\nText: " << text << endl; - cout << "Pattern: " << pattern << endl; - - matches = algo.search(text, pattern); - - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - TurboDemo::demonstrateAlgorithm(); - return 0; -} -``` - -### Key Features: - -1. **Turbo Shifting**: - - Enhanced shift calculation - - Memory-based optimization - - Efficient skip mechanism - -2. **Pattern Processing**: - - Advanced preprocessing - - Shift table generation - - Match history utilization - -3. **Optimization Techniques**: - - Match memory usage - - Factor-based shifts - - Skip calculations - -### Applications: - -1. **Text Processing**: - - Pattern matching - - Text search - - Document analysis - -2. **Information Retrieval**: - - Search engines - - Content filtering - - Pattern detection - -3. **Data Analysis**: - - String searching - - Pattern recognition - - Content scanning - -4. **File Systems**: - - File searching - - Content indexing - - Pattern matching - -### Advanced Features: - -1. **Algorithm Variants**: - - Multiple pattern matching - - Approximate matching - - Extended turbo shifts - -2. **Implementation Optimizations**: - - Cache efficiency - - Memory management - - Parallel processing - -### Comparison with Basic Boyer-Moore: - -1. **Advantages**: - - Better average performance - - Reduced comparisons - - Memory utilization - -2. **Trade-offs**: - - Implementation complexity - - Memory overhead - - Preprocessing time - -### Performance Characteristics: - -1. **Best Case**: - - O(n/m) comparisons - - Optimal shifting - - Maximum skip - -2. **Average Case**: - - Sublinear performance - - Efficient character skipping - - Better than basic Boyer-Moore - -3. **Worst Case**: - - O(n) guaranteed - - Linear scan - - Pattern dependent - -### Summary: - -The Turbo Boyer-Moore Algorithm represents a significant enhancement over the classic Boyer-Moore algorithm by incorporating memory of previous comparisons and utilizing advanced shifting techniques. Its ability to remember matched portions of the pattern and use this information for subsequent shifts makes it particularly efficient for pattern matching tasks. - -The algorithm's strength lies in its sophisticated shift calculations and memory utilization, which often result in fewer character comparisons than the original Boyer-Moore algorithm. The implementation provides both the basic functionality and advanced features that make it suitable for various text processing applications. - -The practical applications range from simple text searches to complex pattern matching scenarios. Its improved performance characteristics make it particularly valuable in situations where efficient string matching is crucial, such as in search engines and content analysis systems. - -The algorithm's enhancements, while adding some complexity to the implementation, provide tangible benefits in terms of reduced comparisons and improved average-case performance, making it a valuable tool in the string matching algorithm arsenal. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/two-way-string-matching-algorithm.md b/docs/algorithms/string-algorithms/two-way-string-matching-algorithm.md deleted file mode 100644 index 2537b2808..000000000 --- a/docs/algorithms/string-algorithms/two-way-string-matching-algorithm.md +++ /dev/null @@ -1,242 +0,0 @@ ---- - -id: two-way-string-matching -sidebar_position: 8 -title: Two-Way String-Matching Algorithm -sidebar_label: Two-Way String-Matching Algorithm - ---- - -### Definition: - -The Two-Way String-Matching Algorithm, developed by Crochemore and Perrin, is an efficient pattern matching algorithm that combines forward and backward scanning techniques. It improves upon classical algorithms by processing the pattern in both directions, reducing the number of character comparisons needed during the search phase. - -### Characteristics: - -- **Bidirectional Scanning**: - - Combines both left-to-right and right-to-left scanning - - Uses the advantages of both scanning directions - - Reduces the number of character comparisons - -- **Critical Factorization**: - - Divides the pattern into two parts based on its periodicity - - Uses the critical factorization theorem - - Optimizes the matching process based on pattern structure - -- **Efficient Shifting**: - - Employs maximal suffixes for efficient shift calculations - - Utilizes period information for better shifts - - Reduces the number of comparisons needed - -- **Pattern Preprocessing**: - - Analyzes pattern structure before searching - - Computes critical factorization points - - Prepares shift tables for both directions - -### Time Complexity: - -- **Preprocessing: $O(m)$** - - Where m is the length of the pattern - - Includes critical factorization computation - - Computing maximal suffixes and shift tables - -- **Searching: $O(n)$** - - Where n is the length of the text - - Best case performance of O(n/m) - - Sublinear on average - -### Space Complexity: - -- **Space Usage: $O(m)$** - - Where m is the pattern length - - Storage for preprocessing information - - Constant extra space during search phase - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class TwoWayStringMatcher { -private: - // Compute the maximal suffix for forward scanning - pair maximalSuffix(const string& pattern) { - int m = pattern.length(); - int ms = -1, j = 0, k = 1, p = 1; - - while (j + k < m) { - char a = pattern[j + k]; - char b = pattern[ms + k]; - - if (a < b) { - j += k; - k = 1; - p = j - ms; - } - else if (a == b) { - if (k != p) - k++; - else { - j += p; - k = 1; - } - } - else { // a > b - ms = j; - j = ms + 1; - k = 1; - p = 1; - } - } - return make_pair(ms, p); - } - - // Compute the maximal suffix for backward scanning - pair maximalSuffixReverse(const string& pattern) { - string revPattern = pattern; - reverse(revPattern.begin(), revPattern.end()); - return maximalSuffix(revPattern); - } - - // Find critical factorization point - int criticalFactorization(const string& pattern) { - auto [ms1, p1] = maximalSuffix(pattern); - auto [ms2, p2] = maximalSuffixReverse(pattern); - return max(ms1 + 1, (int)pattern.length() - ms2 - 2); - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0) return matches; - - // Preprocessing - int critical = criticalFactorization(pattern); - - // Searching phase - int i = 0; - while (i <= n - m) { - // Try matching at current position - int j; - - // Forward scan from critical point - for (j = critical; j < m && pattern[j] == text[i + j]; j++); - if (j < m) { - i++; - continue; - } - - // Backward scan from critical point - for (j = critical - 1; j >= 0 && pattern[j] == text[i + j]; j--); - if (j < 0) { - matches.push_back(i); - } - - // Shift pattern - i += max(1, critical - j); - } - - return matches; - } -}; - -class TwoWayStringMatcherDemo { -public: - static void demonstrateSearch() { - TwoWayStringMatcher matcher; - string text = "GCATCGCAGAGAGTATACAGTACG"; - string pattern = "GCAGAGAG"; - - vector matches = matcher.search(text, pattern); - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - TwoWayStringMatcherDemo::demonstrateSearch(); - return 0; -} -``` - -### Key Features: - -1. **Pattern Analysis**: - - Critical factorization computation - - Period calculation - - Maximal suffix computation - -2. **Scanning Strategy**: - - Forward scanning from critical point - - Backward scanning when needed - - Efficient shift calculation - -3. **Optimization Techniques**: - - Period-based shifts - - Critical factorization - - Bidirectional scanning - -### Applications: - -1. **Text Processing**: - - Text editors - - Document search - - Pattern matching systems - -2. **Bioinformatics**: - - DNA sequence matching - - Protein sequence analysis - - Genomic pattern finding - -3. **Information Retrieval**: - - Search engines - - Document indexing - - Content filtering - -4. **Network Security**: - - Intrusion detection - - Pattern-based monitoring - - Network traffic analysis - -### Advanced Features: - -1. **Variants and Extensions**: - - Multiple pattern matching - - Approximate matching - - Unicode support - -2. **Performance Optimizations**: - - SIMD implementations - - Cache-aware variants - - Parallel processing adaptations - -### Comparison with Other Algorithms: - -1. **Advantages**: - - Fewer comparisons on average - - Better worst-case behavior - - Efficient for periodic patterns - -2. **Trade-offs**: - - More complex preprocessing - - Additional memory for tables - - Implementation complexity - -### Summary: - -The Two-Way String-Matching Algorithm represents a sophisticated approach to pattern matching that combines the benefits of both forward and backward scanning. Its use of critical factorization and bidirectional scanning makes it particularly efficient for many practical applications. The algorithm's sublinear average-case performance and robust worst-case behavior make it suitable for situations where consistent performance is required. - -The implementation, while more complex than simpler string matching algorithms, provides excellent performance characteristics and is particularly well-suited for applications where pattern matching performance is crucial. The algorithm's ability to handle periodic patterns efficiently and its reduced number of character comparisons make it a valuable tool in the string matching algorithm arsenal. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/ukkonens-algorithm.md b/docs/algorithms/string-algorithms/ukkonens-algorithm.md deleted file mode 100644 index d3e6888cf..000000000 --- a/docs/algorithms/string-algorithms/ukkonens-algorithm.md +++ /dev/null @@ -1,266 +0,0 @@ ---- - -id: ukkonens-algorithm -sidebar_position: 7 -title: Ukkonen's Algorithm -sidebar_label: Ukkonen's Algorithm - ---- - -### Definition: - -Ukkonen's Algorithm is an online algorithm for constructing suffix trees in linear time. Published by Esko Ukkonen in 1995, it builds a suffix tree for a string by processing characters one by one from left to right. The algorithm is notable for its efficiency and the elegant way it handles suffix links to achieve linear time complexity. - -### Characteristics: - -- **Online Processing**: - - Processes text left to right, one character at a time - - Can handle streaming input - - Tree is always complete for currently processed text - -- **Implicit Suffixes**: - - Uses implicit suffixes to avoid explicitly storing all suffixes - - Maintains active points and suffix links for efficient navigation - - Handles rule extensions incrementally - -- **Suffix Links**: - - Uses suffix links to quickly move between related nodes - - Reduces traversal time during tree construction - - Essential for achieving linear time complexity - -- **Space Optimization**: - - Uses path compression to reduce space requirements - - Maintains only necessary internal nodes - - Efficiently handles repeated patterns - -### Time Complexity: - -- **Construction: $O(n)$** - - Where n is the length of the input string - - Amortized linear time for all operations - - Each phase processes one character in amortized constant time - -- **Space Complexity: $O(n)$** - - Storage for nodes and edges - - Additional space for suffix links - - Path compression keeps space requirement linear - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class SuffixTreeNode { -public: - unordered_map children; - SuffixTreeNode* suffixLink; - int start; - int* end; - int suffixIndex; - - SuffixTreeNode(int start, int* end) { - this->start = start; - this->end = end; - this->suffixIndex = -1; - this->suffixLink = nullptr; - } -}; - -class SuffixTree { -private: - string text; - SuffixTreeNode* root; - SuffixTreeNode* lastNewNode; - SuffixTreeNode* activeNode; - int activeEdge; - int activeLength; - int remainingSuffixCount; - int leafEnd; - int* rootEnd; - int* splitEnd; - vector size; - - bool walkDown(SuffixTreeNode* currNode) { - if (activeLength >= edgeLength(currNode)) { - activeEdge += edgeLength(currNode); - activeLength -= edgeLength(currNode); - activeNode = currNode; - return true; - } - return false; - } - - int edgeLength(SuffixTreeNode* n) { - return *(n->end) - n->start + 1; - } - - void extendSuffixTree(int pos) { - leafEnd = pos; - remainingSuffixCount++; - lastNewNode = nullptr; - - while (remainingSuffixCount > 0) { - if (activeLength == 0) - activeEdge = pos; - - if (activeNode->children.find(text[activeEdge]) == - activeNode->children.end()) { - activeNode->children[text[activeEdge]] = - new SuffixTreeNode(pos, &leafEnd); - - if (lastNewNode != nullptr) { - lastNewNode->suffixLink = activeNode; - lastNewNode = nullptr; - } - } else { - SuffixTreeNode* next = activeNode->children[text[activeEdge]]; - if (walkDown(next)) - continue; - - if (text[next->start + activeLength] == text[pos]) { - if (lastNewNode != nullptr && activeNode != root) { - lastNewNode->suffixLink = activeNode; - lastNewNode = nullptr; - } - activeLength++; - break; - } - - splitEnd = new int(next->start + activeLength - 1); - SuffixTreeNode* split = new SuffixTreeNode(next->start, splitEnd); - activeNode->children[text[activeEdge]] = split; - - split->children[text[pos]] = - new SuffixTreeNode(pos, &leafEnd); - next->start += activeLength; - split->children[text[next->start]] = next; - - if (lastNewNode != nullptr) - lastNewNode->suffixLink = split; - - lastNewNode = split; - } - - remainingSuffixCount--; - if (activeNode == root && activeLength > 0) { - activeLength--; - activeEdge = pos - remainingSuffixCount + 1; - } else if (activeNode != root) { - activeNode = activeNode->suffixLink != nullptr ? - activeNode->suffixLink : root; - } - } - } - - void setSuffixIndexByDFS(SuffixTreeNode* n, int labelHeight) { - if (n == nullptr) return; - - if (n->start != -1) - cout << "Start: " << n->start << " End: " << *(n->end) << endl; - - bool leaf = true; - for (auto& child : n->children) { - if (child.second != nullptr) { - leaf = false; - setSuffixIndexByDFS(child.second, - labelHeight + edgeLength(child.second)); - } - } - - if (leaf) { - n->suffixIndex = text.length() - labelHeight; - cout << "Suffix Index: " << n->suffixIndex << endl; - } - } - -public: - SuffixTree(string txt) { - text = txt; - rootEnd = new int(-1); - root = new SuffixTreeNode(-1, rootEnd); - activeNode = root; - activeEdge = -1; - activeLength = 0; - remainingSuffixCount = 0; - leafEnd = -1; - - for (int i = 0; i < text.length(); i++) - extendSuffixTree(i); - - int labelHeight = 0; - setSuffixIndexByDFS(root, labelHeight); - } - - ~SuffixTree() { - // Cleanup code here - } -}; - -int main() { - string txt = "banana$"; - SuffixTree tree(txt); - return 0; -} -``` - -### Key Features: - -1. **Extension Rules**: - - Rule 1: Add new leaf - - Rule 2: Split and add leaf - - Rule 3: Already exists (do nothing) - -2. **Important Concepts**: - - Active Point (Node, Edge, Length) - - Suffix Links - - End Point - - Remaining Suffixes - -3. **Optimization Techniques**: - - Skip/Count Trick - - Path Compression - - Smart Node Hopping - -### Applications: - -1. **String Processing**: - - Pattern matching - - Substring queries - - Common substring finding - -2. **Bioinformatics**: - - DNA sequence analysis - - Genome assembly - - Pattern finding in biological sequences - -3. **Text Processing**: - - Text editors - - Search engines - - Data compression - -4. **Database Systems**: - - Indexing - - Fast substring searches - - Query optimization - -### Advanced Features: - -1. **Generalized Suffix Trees**: - - Multiple string support - - Set matching operations - - Common substrings between strings - -2. **Memory Optimizations**: - - Compressed suffix trees - - Disk-based implementations - - Memory-efficient variants - -### Summary: - -Ukkonen's Algorithm represents a significant advancement in suffix tree construction, offering linear-time complexity through clever use of suffix links and active points. Its online nature makes it particularly suitable for streaming applications, while its efficiency makes it practical for large-scale text processing tasks. The algorithm's elegant handling of suffix links and its ability to process text incrementally have made it a fundamental tool in string processing and bioinformatics applications. - -The implementation, while complex, provides a robust foundation for building suffix trees that can be used in various applications ranging from pattern matching to genome analysis. The algorithm's ability to handle dynamic updates and its efficient space usage make it particularly valuable in modern applications where real-time processing of large text data is required. \ No newline at end of file diff --git a/docs/algorithms/string-algorithms/zhu-takaoka-algorithm.md b/docs/algorithms/string-algorithms/zhu-takaoka-algorithm.md deleted file mode 100644 index eb7d5ffb8..000000000 --- a/docs/algorithms/string-algorithms/zhu-takaoka-algorithm.md +++ /dev/null @@ -1,293 +0,0 @@ ---- - -id: zhu-takaoka-algorithm -sidebar_position: 10 -title: Zhu-Takaoka Algorithm -sidebar_label: Zhu-Takaoka Algorithm - ---- - -### Definition: - -The Zhu-Takaoka Algorithm is a string matching algorithm developed by R.F. Zhu and T. Takaoka as an improvement to the Boyer-Moore algorithm. It enhances the bad character rule by considering two consecutive characters instead of just one, leading to potentially larger shifts and better average-case performance. - -### Characteristics: - -- **Two-Character Bad Character Rule**: - - Uses pairs of characters for shift calculations - - Improves upon Boyer-Moore's single character approach - - Enables larger shifts in many cases - -- **Good Suffix Rule**: - - Incorporates the Boyer-Moore good suffix rule - - Combines with two-character bad character rule - - Optimizes shifting based on suffix matches - -- **Preprocessing Phase**: - - Computes two-character bad character table - - Builds good suffix shift table - - Prepares efficient lookup structures - -- **Right-to-Left Scanning**: - - Scans pattern from right to left - - Uses enhanced shift calculations - - Maintains Boyer-Moore efficiency - -### Time Complexity: - -- **Preprocessing: $O(m + σ²)$** - - Where m is pattern length - - σ is alphabet size - - Two-character table construction - -- **Searching: $O(n)$** - - Where n is text length - - Best case: O(n/m) - - Sublinear on average - -### Space Complexity: - -- **Space Usage: $O(m + σ²)$** - - Two-character bad character table - - Good suffix table - - Auxiliary preprocessing data - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -class ZhuTakaokaAlgorithm { -private: - static const int ALPHABET_SIZE = 256; - - // Compute the bad character table for two consecutive characters - void computeBadCharTable(const string& pattern, - vector>& badChar) { - int m = pattern.length(); - - // Initialize with pattern length - for (int i = 0; i < ALPHABET_SIZE; i++) { - for (int j = 0; j < ALPHABET_SIZE; j++) { - badChar[i][j] = m; - } - } - - // Fill the table with actual values - for (int i = 0; i < m - 1; i++) { - unsigned char first = pattern[i]; - unsigned char second = pattern[i + 1]; - badChar[first][second] = m - 1 - i; - } - } - - // Compute the good suffix table - void computeGoodSuffix(const string& pattern, - vector& goodSuffix) { - int m = pattern.length(); - vector suffix(m); - - // Case 1: matching suffixes - int lastPrefix = m; - for (int i = m - 1; i >= 0; i--) { - if (isPrefix(pattern, i + 1)) { - lastPrefix = i + 1; - } - goodSuffix[i] = lastPrefix + (m - 1 - i); - } - - // Case 2: matching suffixes that are not prefixes - for (int i = 0; i < m - 1; i++) { - int len = suffixLength(pattern, i); - if (len > 0) { - goodSuffix[m - 1 - len] = m - 1 - i + len; - } - } - } - - // Check if pattern[p..m] is a prefix of pattern - bool isPrefix(const string& pattern, int p) { - int m = pattern.length(); - for (int i = p, j = 0; i < m; i++, j++) { - if (pattern[i] != pattern[j]) { - return false; - } - } - return true; - } - - // Length of the longest suffix of pattern[0..p] that matches - // a suffix of pattern - int suffixLength(const string& pattern, int p) { - int m = pattern.length(); - int len = 0; - int i = p; - int j = m - 1; - - while (i >= 0 && pattern[i] == pattern[j]) { - len++; - i--; - j--; - } - return len; - } - -public: - vector search(const string& text, const string& pattern) { - vector matches; - int n = text.length(); - int m = pattern.length(); - - if (m == 0 || m > n) return matches; - - // Preprocessing - vector> badChar(ALPHABET_SIZE, - vector(ALPHABET_SIZE)); - vector goodSuffix(m); - - computeBadCharTable(pattern, badChar); - computeGoodSuffix(pattern, goodSuffix); - - // Searching phase - int i = 0; - while (i <= n - m) { - int j = m - 1; - - // Match pattern from right to left - while (j >= 0 && pattern[j] == text[i + j]) { - j--; - } - - if (j < 0) { - // Pattern found - matches.push_back(i); - i += goodSuffix[0]; - } else { - // Calculate shift - int shift1 = j < 1 ? 1 : - badChar[text[i + j - 1]][text[i + j]]; - int shift2 = goodSuffix[j]; - i += max(shift1, shift2); - } - } - - return matches; - } -}; - -// Demonstration class -class ZhuTakaokaDemo { -public: - static void demonstrateSearch() { - ZhuTakaokaAlgorithm algo; - string text = "GCATCGCAGAGAGTATACAGTACG"; - string pattern = "GCAGAGAG"; - - cout << "Text: " << text << endl; - cout << "Pattern: " << pattern << endl; - - vector matches = algo.search(text, pattern); - - cout << "Pattern found at positions: "; - for (int pos : matches) { - cout << pos << " "; - } - cout << endl; - } -}; - -int main() { - ZhuTakaokaDemo::demonstrateSearch(); - return 0; -} -``` - -### Key Features: - -1. **Enhanced Bad Character Rule**: - - Two-character lookup table - - Improved shift calculations - - Better average-case performance - -2. **Good Suffix Integration**: - - Boyer-Moore good suffix rule - - Suffix-based shifting - - Prefix-suffix relationships - -3. **Optimization Techniques**: - - Efficient preprocessing - - Combined shift strategies - - Right-to-left scanning - -### Applications: - -1. **Text Processing**: - - Text editors - - Document search - - Pattern matching systems - -2. **Bioinformatics**: - - DNA sequence analysis - - Protein pattern matching - - Genome searching - -3. **Network Security**: - - Intrusion detection - - Network monitoring - - Pattern-based filtering - -4. **Information Retrieval**: - - Search engines - - Content analysis - - Document indexing - -### Advanced Features: - -1. **Algorithm Variants**: - - Multiple pattern matching - - Approximate matching - - Unicode support - -2. **Implementation Optimizations**: - - Cache-efficient variants - - SIMD implementations - - Memory-efficient versions - -### Comparison with Boyer-Moore: - -1. **Advantages**: - - Larger shifts on average - - Better handling of patterns with repeating characters - - Improved performance for certain pattern types - -2. **Trade-offs**: - - Larger preprocessing space - - More complex implementation - - Additional preprocessing time - -### Performance Characteristics: - -1. **Best Case**: - - O(n/m) comparisons - - Occurs with non-matching characters - - Benefits from two-character shifts - -2. **Average Case**: - - Sublinear performance - - Better than Boyer-Moore for many patterns - - Efficient for large alphabets - -3. **Worst Case**: - - O(nm) theoretical bound - - Rare in practice - - Still maintains practical efficiency - -### Summary: - -The Zhu-Takaoka Algorithm represents a significant improvement over the Boyer-Moore algorithm through its innovative use of two-character bad character rules. This enhancement allows for potentially larger shifts during the matching process, leading to better average-case performance. The algorithm maintains the advantages of Boyer-Moore while adding its own optimizations. - -The implementation combines the enhanced bad character rule with the good suffix rule from Boyer-Moore, providing a robust and efficient string matching solution. The algorithm's ability to consider character pairs makes it particularly effective for patterns where single-character approaches might be less efficient. While it requires more preprocessing space and time than Boyer-Moore, the improved shifting strategy often leads to better overall performance, especially for certain types of patterns and larger alphabets. \ No newline at end of file diff --git a/docs/b-tree/B-Tree-1.md b/docs/b-tree/B-Tree-1.md deleted file mode 100644 index 5f3fe7f89..000000000 --- a/docs/b-tree/B-Tree-1.md +++ /dev/null @@ -1,437 +0,0 @@ ---- -id: b-tree-introduction -sidebar_position: 1 -title: Introduction of B-Tree -sidebar_label: Introduction of B-Tree -description: "A B-tree is a self-balancing tree data structure that maintains sorted data for efficient insertion, deletion, and search operations." -tags: [b-tree, algorithms, problem-solving, DSA, data structure] ---- - -The limitations of traditional binary search trees can be frustrating. Meet the B-Tree, the multi-talented data structure that can handle massive amounts of data with ease. When it comes to storing and searching large amounts of data, traditional binary search trees can become impractical due to their poor performance and high memory usage. B-Trees, also known as B-Tree or Balanced Tree, are a type of self-balancing tree that was specifically designed to overcome these limitations. - -Unlike traditional binary search trees, B-Trees are characterized by the large number of keys that they can store in a single node, which is why they are also known as “large key” trees. Each node in a B-Tree can contain multiple keys, which allows the tree to have a larger branching factor and thus a shallower height. This shallow height leads to less disk I/O, which results in faster search and insertion operations. B-Trees are particularly well suited for storage systems that have slow, bulky data access such as hard drives, flash memory, and CD-ROMs. - -B-Trees maintain balance by ensuring that each node has a minimum number of keys, so the tree is always balanced. This balance guarantees that the time complexity for operations such as insertion, deletion, and searching is always **O(log n)**, regardless of the initial shape of the tree. - -## Time Complexity of B-Tree:  - -| Sr. No. | Algorithm | Time Complexity | -|---------|------------|-----------------| -| 1. | Search | O(log n) | -| 2. | Insert | O(log n) | -| 3. | Delete | O(log n) | - -**Note:** `n` is the total number of elements in the B-tree. - -## Properties of B-Tree: - -* All leaves are at the same level. -* B-Tree is defined by the term minimum degree **t**. The value of **t** depends upon disk block size. -* Every node except the root must contain at least `t-1` keys. The root may contain a minimum of **1** key. -* All nodes (including root) may contain at most **(2 * t – 1)** keys. -* Number of children of a node is equal to the number of keys in it plus **1**. -* All keys of a node are sorted in increasing order. The child between two keys **k1** and **k2** contains all keys in the range from **k1** to **k2**. -* B-Tree grows and shrinks from the root, unlike Binary Search Tree. Binary Search Trees grow downward and also shrink from downward. -* Like other balanced Binary Search Trees, the time complexity to search, insert, and delete is **O(log n)**. -* Insertion of a node in B-Tree happens only at the leaf node. - -Following is an example of a B-Tree of minimum order 5: -**Note:** In practical B-Trees, the value of the minimum order is much more than 5.  - -We can see in the above diagram that all the leaf nodes are at the same level and all non-leaves have no empty sub-tree and have keys one less than the number of their children. - -## Interesting Facts about B-Trees: - -> The minimum height of the B-Tree that can exist with `n` number of nodes and `m` is the maximum number of children a node can have: -> **hmin = ⌈ logm (n + 1) ⌉ - 1** -> -> The maximum height of the B-Tree that can exist with `n` number of nodes and `t` is the minimum number of children that a non-root node can have: -> **hmax = ⌊ logt ( (n + 1) / 2 ) ⌋**, -> where **t = ⌈ m / 2 ⌉**. - -## Traversal in B-Tree: - -Traversal is also similar to inorder traversal of a Binary Tree. We start from the leftmost child, recursively print the leftmost child, then repeat the same process for the remaining children and keys. In the end, recursively print the rightmost child.  - -## Search Operation in B-Tree: - -Search is similar to the search in a Binary Search Tree. Let the key to be searched be `k`. - -* Start from the root and recursively traverse down. -* For every visited non-leaf node: - * If the node has the key, we simply return the node. - * Otherwise, we recurse down to the appropriate child (the child just before the first greater key) of the node. -* If we reach a leaf node and don’t find `k` in the leaf node, return `NULL`. - -Searching a B-Tree is similar to searching a binary tree. The algorithm is similar and goes with recursion. At each level, the search is optimized by using limiting values (separation values) to minimize unnecessary branches. If we reach a leaf node and don’t find the desired key, it will return `NULL`. - -## Algorithm for Searching an Element in a B-Tree: - -``` -struct Node { - int n; - int key[MAX_KEYS]; - Node* child[MAX_CHILDREN]; - bool leaf; -}; - -Node* BtreeSearch(Node* x, int k) { - int i = 0; - while (i < x->n && k > x->key[i]) { - i++; - } - if (i < x->n && k == x->key[i]) { - return x; - } - if (x->leaf) { - return nullptr; - } - return BtreeSearch(x->child[i], k); -} -``` - -## Examples: - -> **Input:** Search 120 in the given B-Tree. -> -> ![](./image/output253.png) -> -> -> **Solution:** -> -> ![](./image/output254.png) -> -> -> ![](./image/output255.png) -> -> -> ![](./image/output256.png) - -In this example, we can see that our search was reduced by just limiting the chances where the key containing the value could be present. Similarly, if within the above example we have to look for 180, then the control will stop at step 2 because the program will find that the key 180 is present within the current node. Similarly, if it’s to search for 90, then as `90 < 100`, it will go to the left subtree automatically, and the control flow will follow the same pattern as shown in the above example. - -Below is the implementation of the above approach: - -### C++ - - -``` -#include - -using namespace std; - -// A BTree node -class BTreeNode { - int* keys; // An array of keys - int t; // Minimum degree (defines the range for number - // of keys) - BTreeNode** C; // An array of child pointers - int n; // Current number of keys - bool leaf; // Is true when node is leaf. Otherwise false - -public: - BTreeNode(int _t, bool _leaf); // Constructor - // A function to traverse all nodes in a subtree rooted - // with this node - void traverse(); - // A function to search a key in the subtree rooted with - // this node. - BTreeNode* search(int k); // returns NULL if k is not present. - // Make the BTree friend of this so that we can access - // private members of this class in BTree functions - friend class BTree; -}; - -// A BTree -class BTree { - BTreeNode* root; // Pointer to root node - int t; // Minimum degree - -public: - // Constructor (Initializes tree as empty) - BTree(int _t) - { - root = NULL; - t = _t; - } - - // function to traverse the tree - void traverse() - { - if (root != NULL) - root->traverse(); - } - - // function to search a key in this tree - BTreeNode* search(int k) - { - return (root == NULL) ? NULL : root->search(k); - } -}; - -// Constructor for BTreeNode class -BTreeNode::BTreeNode(int _t, bool _leaf) -{ - // Copy the given minimum degree and leaf property - t = _t; - leaf = _leaf; - // Allocate memory for maximum number of possible keys - // and child pointers - keys = new int[2 * t - 1]; - C = new BTreeNode*[2 * t]; - // Initialize the number of keys as 0 - n = 0; -} - -// Function to traverse all nodes in a subtree rooted with -// this node -void BTreeNode::traverse() -{ - // There are n keys and n+1 children, traverse through n - // keys and first n children - int i; - for (i = 0; i < n; i++) { - // If this is not leaf, then before printing key[i], - // traverse the subtree rooted with child C[i]. - if (leaf == false) - C[i]->traverse(); - cout << " " << keys[i]; - } - // Print the subtree rooted with last child - if (leaf == false) - C[i]->traverse(); -} - -// Function to search key k in subtree rooted with this node -BTreeNode* BTreeNode::search(int k) -{ - // Find the first key greater than or equal to k - int i = 0; - while (i < n && k > keys[i]) - i++; - // If the found key is equal to k, return this node - if (keys[i] == k) - return this; - // If the key is not found here and this is a leaf node - if (leaf == true) - return NULL; - // Go to the appropriate child - return C[i]->search(k); -} -``` -### Java - -``` -// Java program to illustrate the sum of two numbers -// A BTree -class Btree { - public BTreeNode root; // Pointer to root node - public int t; // Minimum degree - - // Constructor (Initializes tree as empty) - Btree(int t) - { - this.root = null; - this.t = t; - } - - // function to traverse the tree - public void traverse() - { - if (this.root != null) - this.root.traverse(); - System.out.println(); - } - - // function to search a key in this tree - public BTreeNode search(int k) - { - if (this.root == null) - return null; - else - return this.root.search(k); - } -} - -// A BTree node -class BTreeNode { - int[] keys; // An array of keys - int t; // Minimum degree (defines the range for number - // of keys) - BTreeNode[] C; // An array of child pointers - int n; // Current number of keys - boolean leaf; // Is true when node is leaf. Otherwise false - - // Constructor - BTreeNode(int t, boolean leaf) - { - this.t = t; - this.leaf = leaf; - this.keys = new int[2 * t - 1]; - this.C = new BTreeNode[2 * t]; - this.n = 0; - } - - // A function to traverse all nodes in a subtree rooted - // with this node - public void traverse() - { - // There are n keys and n+1 children, traverse - // through n keys and first n children - int i = 0; - for (i = 0; i < this.n; i++) { - // If this is not leaf, then before printing - // key[i], traverse the subtree rooted with - // child C[i]. - if (this.leaf == false) { - C[i].traverse(); - } - System.out.print(keys[i] + " "); - } - // Print the subtree rooted with last child - if (leaf == false) - C[i].traverse(); - } - - // A function to search a key in the subtree rooted with - // this node. - BTreeNode search(int k) // returns NULL if k is not present. - { - // Find the first key greater than or equal to k - int i = 0; - while (i < n && k > keys[i]) - i++; - // If the found key is equal to k, return this node - if (keys[i] == k) - return this; - // If the key is not found here and this is a leaf - // node - if (leaf == true) - return null; - // Go to the appropriate child - return C[i].search(k); - } -} - -``` - - -### Python3 - -``` -# Create a node -class BTreeNode: - def __init__(self, leaf=False): - self.leaf = leaf - self.keys = [] - self.child = [] - -# Tree -class BTree: - def __init__(self, t): - self.root = BTreeNode(True) - self.t = t - - # Insert node - def insert(self, k): - root = self.root - if len(root.keys) == (2 * self.t) - 1: - temp = BTreeNode() - self.root = temp - temp.child.insert(0, root) - self.split_child(temp, 0) - self.insert_non_full(temp, k) - else: - self.insert_non_full(root, k) - - # Insert nonfull - def insert_non_full(self, x, k): - i = len(x.keys) - 1 - if x.leaf: - x.keys.append((None, None)) - while i >= 0 and k[0] < x.keys[i][0]: - x.keys[i + 1] = x.keys[i] - i -= 1 - x.keys[i + 1] = k - else: - while i >= 0 and k[0] < x.keys[i][0]: - i -= 1 - i += 1 - if len(x.child[i].keys) == (2 * self.t) - 1: - self.split_child(x, i) - if k[0] > x.keys[i][0]: - i += 1 - self.insert_non_full(x.child[i], k) - - # Split the child - def split_child(self, x, i): - t = self.t - y = x.child[i] - z = BTreeNode(y.leaf) - x.child.insert(i + 1, z) - x.keys.insert(i, y.keys[t - 1]) - z.keys = y.keys[t: (2 * t) - 1] - y.keys = y.keys[0: t - 1] - if not y.leaf: - z.child = y.child[t: 2 * t] - y.child = y.child[0: t - 1] - - # Print the tree - def print_tree(self, x, l=0): - print("Level ", l, " ", len(x.keys), end=":") - for i in x.keys: - print(i, end=" ") - print() - l += 1 - if len(x.child) > 0: - for i in x.child: - self.print_tree(i, l) - - # Search key in the tree - def search_key(self, k, x=None): - if x is not None: - i = 0 - while i < len(x.keys) and k > x.keys[i][0]: - i += 1 - if i < len(x.keys) and k == x.keys[i][0]: - return (x, i) - elif x.leaf: - return None - else: - return self.search_key(k, x.child[i]) - else: - return self.search_key(k, self.root) - -def main(): - b = BTree(3) - for i in range(10): - b.insert((i, "Value" + str(i))) - - b.print_tree(b.root) - -if __name__ == "__main__": - main() - -``` - - -## Applications of B-Trees - -- Used in large databases to access data stored on the disk. -- Searching for data in a dataset can be achieved in significantly less time using the B-Tree. -- Multilevel indexing can be achieved with the indexing feature. -- Most servers also use the B-tree approach. -- B-Trees are used in CAD systems to organize and search geometric data. -- B-Trees are also used in areas such as natural language processing, computer networks, and cryptography. - -## Advantages of B-Trees - -- Guaranteed time complexity of O(log n) for basic operations like insertion, deletion, and searching, making them suitable for large datasets and real-time applications. -- B-Trees are self-balancing. -- High concurrency and high throughput. -- Efficient storage utilization. - -## Disadvantages of B-Trees - -- B-Trees are based on disk-based data structures and can have high disk usage. -- Not the best for all cases. -- Slower in comparison to other data structures. diff --git a/docs/b-tree/B-Tree-2.md b/docs/b-tree/B-Tree-2.md deleted file mode 100644 index 397ff8c44..000000000 --- a/docs/b-tree/B-Tree-2.md +++ /dev/null @@ -1,542 +0,0 @@ ---- -id: b-tree-insert -sidebar_position: 2 -title: Insert Operation in B-Tree -sidebar_label: Insert Operation in B-Tree -description: "Inserting a key into a B-tree while maintaining its properties." -tags: [b-tree, algorithms, problem-solving, DSA, data structure] ---- - -# Insert Operation in B-Tree - -In the previous post, we introduced B-Trees and discussed the `search()` and `traverse()` functions. In this post, we will discuss the `insert()` operation. A new key is always inserted at the leaf node. Let the key to be inserted be `k`. Like in a Binary Search Tree (BST), we start from the root and traverse down until we reach a leaf node. Once we reach a leaf node, we insert the key there. Unlike BSTs, we have a predefined range on the number of keys that a node can contain. So before inserting a key into the node, we must ensure that there is extra space. - -**How do we ensure that a node has space available for a key before it is inserted?** We use an operation called `splitChild()`, which is used to split a child of a node. See the following diagram to understand the split. In this diagram, child `y` of `x` is being split into two nodes `y` and `z`. Note that the `splitChild` operation moves a key up, which is the reason B-Trees grow up, unlike BSTs, which grow down. - -![BTreeSplit](./image/BTreeSplit-1024x321.jpg) - -As discussed, to insert a new key, we go down from the root to the leaf. Before traversing down to a node, we first check if the node is full. If the node is full, we split it to create space. The complete algorithm is as follows: - -### Insertion Algorithm -1. Initialize `x` as root. -2. While `x` is not a leaf, do the following: - - **a)** Find the child of `x` that will be traversed next. Let the child be `y`. - - **b)** If `y` is not full, change `x` to point to `y`. - - **c)** If `y` is full, split it and change `x` to point to one of the two parts of `y`. If `k` is smaller than the middle key in `y`, set `x` as the first part of `y`. Otherwise, set it as the second part of `y`. When we split `y`, we move a key from `y` to its parent `x`. -3. The loop in step 2 stops when `x` is a leaf. `x` must have space for 1 extra key, as we have been splitting all nodes in advance. So, simply insert `k` into `x`. - -Note that the algorithm follows the Cormen book. This is a proactive insertion algorithm; before going down to a node, we split it if it is full. The advantage of this preemptive splitting is that we never traverse a node twice. If we were to only split a node after a new key is inserted (a reactive approach), we might end up traversing all nodes from the leaf to the root again, especially when all nodes on the path from the root to the leaf are full. This may cause a cascading effect where splitting occurs up to the root. - -However, there is a disadvantage to this proactive insertion: we may perform unnecessary splits. - -### Example Insertion Sequence - -Let us understand the algorithm with an example B-Tree of minimum degree `t` as 3 and a sequence of integers: 10, 20, 30, 40, 50, 60, 70, 80, and 90 in an initially empty B-Tree. Initially, the root is `NULL`. Let us first insert `10`. - -![Btree1](./image/Btree1.png) - -Next, let us insert `20`, `30`, `40`, and `50`. They will all be inserted in the root because the maximum number of keys a node can accommodate is \(2t - 1\), which is 5. - -![BTree2Ins](./image/BTree2Ins.png) - -Now, let us insert `60`. Since the root node is full, it will first split into two, and then `60` will be inserted into the appropriate child. - -![BTreeIns3](./image/BTreeIns3.png) - -Let us now insert `70` and `80`. These new keys will be inserted into the appropriate leaf without any splits. - -![BTreeIns4](./image/BTreeIns4.png) - -Finally, let us insert `90`. This insertion will cause a split, with the middle key moving up to the parent. - -![BTreeIns6](./image/BTreeIns6.png) - -Following are the implementations of the above proactive algorithm. - - -C++ ---- - -``` -#include -using namespace std; - -// A BTree node -class BTreeNode -{ - int *keys; // An array of keys - int t; // Minimum degree (defines the range for number of keys) - BTreeNode **C; // An array of child pointers - int n; // Current number of keys - bool leaf; // Is true when node is leaf. Otherwise false -public: - BTreeNode(int _t, bool _leaf); // Constructor - - // A utility function to insert a new key in the subtree rooted with - // this node. The assumption is, the node must be non-full when this - // function is called - void insertNonFull(int k); - - // A utility function to split the child y of this node. i is index of y in - // child array C[]. The Child y must be full when this function is called - void splitChild(int i, BTreeNode *y); - - // A function to traverse all nodes in a subtree rooted with this node - void traverse(); - - // A function to search a key in the subtree rooted with this node. - BTreeNode *search(int k); // returns NULL if k is not present. - -// Make BTree friend of this so that we can access private members of this -// class in BTree functions -friend class BTree; -}; - -// A BTree -class BTree -{ - BTreeNode *root; // Pointer to root node - int t; // Minimum degree -public: - // Constructor (Initializes tree as empty) - BTree(int _t) - { root = NULL; t = _t; } - - // function to traverse the tree - void traverse() - { if (root != NULL) root->traverse(); } - - // function to search a key in this tree - BTreeNode* search(int k) - { return (root == NULL)? NULL : root->search(k); } - - // The main function that inserts a new key in this B-Tree - void insert(int k); -}; - -// Constructor for BTreeNode class -BTreeNode::BTreeNode(int t1, bool leaf1) -{ - // Copy the given minimum degree and leaf property - t = t1; - leaf = leaf1; - - // Allocate memory for maximum number of possible keys - // and child pointers - keys = new int[2*t-1]; - C = new BTreeNode *[2*t]; - - // Initialize the number of keys as 0 - n = 0; -} - -// Function to traverse all nodes in a subtree rooted with this node -void BTreeNode::traverse() -{ - // There are n keys and n+1 children, traverse through n keys - // and first n children - int i; - for (i = 0; i < n; i++) - { - // If this is not leaf, then before printing key[i], - // traverse the subtree rooted with child C[i]. - if (leaf == false) - C[i]->traverse(); - cout << " " << keys[i]; - } - - // Print the subtree rooted with last child - if (leaf == false) - C[i]->traverse(); -} - -// Function to search key k in subtree rooted with this node -BTreeNode *BTreeNode::search(int k) -{ - // Find the first key greater than or equal to k - int i = 0; - while (i < n && k > keys[i]) - i++; - - // If the found key is equal to k, return this node - if (keys[i] == k) - return this; - - // If key is not found here and this is a leaf node - if (leaf == true) - return NULL; - - // Go to the appropriate child - return C[i]->search(k); -} - -// The main function that inserts a new key in this B-Tree -void BTree::insert(int k) -{ - // If tree is empty - if (root == NULL) - { - // Allocate memory for root - root = new BTreeNode(t, true); - root->keys[0] = k; // Insert key - root->n = 1; // Update number of keys in root - } - else // If tree is not empty - { - // If root is full, then tree grows in height - if (root->n == 2*t-1) - { - // Allocate memory for new root - BTreeNode *s = new BTreeNode(t, false); - - // Make old root as child of new root - s->C[0] = root; - - // Split the old root and move 1 key to the new root - s->splitChild(0, root); - - // New root has two children now. Decide which of the - // two children is going to have new key - int i = 0; - if (s->keys[0] < k) - i++; - s->C[i]->insertNonFull(k); - - // Change root - root = s; - } - else // If root is not full, call insertNonFull for root - root->insertNonFull(k); - } -} - -// A utility function to insert a new key in this node -// The assumption is, the node must be non-full when this -// function is called -void BTreeNode::insertNonFull(int k) -{ - // Initialize index as index of rightmost element - int i = n-1; - - // If this is a leaf node - if (leaf == true) - { - // The following loop does two things - // a) Finds the location of new key to be inserted - // b) Moves all greater keys to one place ahead - while (i >= 0 && keys[i] > k) - { - keys[i+1] = keys[i]; - i--; - } - - // Insert the new key at found location - keys[i+1] = k; - n = n+1; - } - else // If this node is not leaf - { - // Find the child which is going to have the new key - while (i >= 0 && keys[i] > k) - i--; - - // See if the found child is full - if (C[i+1]->n == 2*t-1) - { - // If the child is full, then split it - splitChild(i+1, C[i+1]); - - // After split, the middle key of C[i] goes up and - // C[i] is splitted into two. See which of the two - // is going to have the new key - if (keys[i+1] < k) - i++; - } - C[i+1]->insertNonFull(k); - } -} - -// A utility function to split the child y of this node -// Note that y must be full when this function is called -void BTreeNode::splitChild(int i, BTreeNode *y) -{ - // Create a new node which is going to store (t-1) keys - // of y - BTreeNode *z = new BTreeNode(y->t, y->leaf); - z->n = t - 1; - - // Copy the last (t-1) keys of y to z - for (int j = 0; j < t-1; j++) - z->keys[j] = y->keys[j+t]; - - // Copy the last t children of y to z - if (y->leaf == false) - { - for (int j = 0; j < t; j++) - z->C[j] = y->C[j+t]; - } - - // Reduce the number of keys in y - y->n = t - 1; - - // Since this node is going to have a new child, - // create space of new child - for (int j = n; j >= i+1; j--) - C[j+1] = C[j]; - - // Link the new child to this node - C[i+1] = z; - - // A key of y will move to this node. Find the location of - // new key and move all greater keys one space ahead - for (int j = n-1; j >= i; j--) - keys[j+1] = keys[j]; - - // Copy the middle key of y to this node - keys[i] = y->keys[t-1]; - - // Increment count of keys in this node - n = n + 1; -} - -// Driver program to test above functions -int main() -{ - BTree t(3); // A B-Tree with minimum degree 3 - t.insert(10); - t.insert(20); - t.insert(5); - t.insert(6); - t.insert(12); - t.insert(30); - t.insert(7); - t.insert(17); - - cout << "Traversal of the constructed tree is "; - t.traverse(); - - int k = 6; - (t.search(k) != NULL)? cout << "\nPresent" : cout << "\nNot Present"; - - k = 15; - (t.search(k) != NULL)? cout << "\nPresent" : cout << "\nNot Present"; - - return 0; -} -``` -JAVA ---- - -``` -import java.util.Arrays; - -class BTreeNode { - int[] keys; // An array of keys - int t; // Minimum degree - BTreeNode[] C; // An array of child pointers - int n; // Current number of keys - boolean leaf; // True if leaf node, otherwise false - - // Constructor - BTreeNode(int t, boolean leaf) { - this.t = t; - this.leaf = leaf; - this.keys = new int[2 * t - 1]; - this.C = new BTreeNode[2 * t]; - this.n = 0; - } - - // Function to traverse all nodes in a subtree rooted with this node - public void traverse() { - int i; - for (i = 0; i < n; i++) { - if (!leaf) { - C[i].traverse(); - } - System.out.print(keys[i] + " "); - } - if (!leaf) { - C[i].traverse(); - } - } - - // Function to search a key in subtree rooted with this node - public BTreeNode search(int k) { - int i = 0; - while (i < n && k > keys[i]) { - i++; - } - - if (i < n && keys[i] == k) { - return this; - } - - if (leaf) { - return null; - } - return C[i].search(k); - } - - // Insert a new key in this node - public void insertNonFull(int k) { - int i = n - 1; - - if (leaf) { - while (i >= 0 && keys[i] > k) { - keys[i + 1] = keys[i]; - i--; - } - keys[i + 1] = k; - n++; - } else { - while (i >= 0 && keys[i] > k) { - i--; - } - if (C[i + 1].n == 2 * t - 1) { - splitChild(i + 1, C[i + 1]); - - if (keys[i + 1] < k) { - i++; - } - } - C[i + 1].insertNonFull(k); - } - } - - // Split the child y of this node - public void splitChild(int i, BTreeNode y) { - BTreeNode z = new BTreeNode(y.t, y.leaf); - z.n = t - 1; - - for (int j = 0; j < t - 1; j++) { - z.keys[j] = y.keys[j + t]; - } - - if (!y.leaf) { - for (int j = 0; j < t; j++) { - z.C[j] = y.C[j + t]; - } - } - - y.n = t - 1; - - for (int j = n; j >= i + 1; j--) { - C[j + 1] = C[j]; - } - C[i + 1] = z; - - for (int j = n - 1; j >= i; j--) { - keys[j + 1] = keys[j]; - } - keys[i] = y.keys[t - 1]; - n++; - } -} - -class BTree { - BTreeNode root; - int t; // Minimum degree - - // Constructor - public BTree(int t) { - this.root = null; - this.t = t; - } - - // Function to traverse the tree - public void traverse() { - if (root != null) { - root.traverse(); - } - } - - // Function to search a key in this tree - public BTreeNode search(int k) { - return (root == null) ? null : root.search(k); - } - - // Insert a new key in this B-Tree - public void insert(int k) { - if (root == null) { - root = new BTreeNode(t, true); - root.keys[0] = k; - root.n = 1; - } else { - if (root.n == 2 * t - 1) { - BTreeNode s = new BTreeNode(t, false); - s.C[0] = root; - s.splitChild(0, root); - - int i = 0; - if (s.keys[0] < k) { - i++; - } - s.C[i].insertNonFull(k); - root = s; - } else { - root.insertNonFull(k); - } - } - } -} - -// Driver program to test above functions -public class Main { - public static void main(String[] args) { - BTree t = new BTree(3); // A B-Tree with minimum degree 3 - t.insert(10); - t.insert(20); - t.insert(5); - t.insert(6); - t.insert(12); - t.insert(30); - t.insert(7); - t.insert(17); - - System.out.print("Traversal of the constructed tree is: "); - t.traverse(); - - int k = 6; - System.out.println("\nSearch for key " + k + ": " + (t.search(k) != null ? "Present" : "Not Present")); - - k = 15; - System.out.println("Search for key " + k + ": " + (t.search(k) != null ? "Present" : "Not Present")); - } -} - -``` -**Output:** -Traversal of the constructed tree is: `5 6 7 10 12 17 20 30` -**Present** -**Not Present** - -The B-tree is a data structure similar to a binary search tree but allows multiple keys per node and has a higher fanout. This enables the B-tree to store a large amount of data efficiently, making it commonly used in databases and file systems. - -## Characteristics of B-Tree - -- **Balanced Tree:** All paths from the root to a leaf have the same length. -- **Minimum Degree `t`:** - - Each non-root node must contain at least \(t - 1\) keys and can contain at most \(2t - 1\) keys. - - The root can have at least one key and at most \(2t - 1\) keys. - - Each node can have at most \(2t\) children. - -## Supported Operations - -1. **Search(k):** Searches for a key `k` in the tree. -2. **Insert(k):** Inserts a key `k` into the tree. -3. **Delete(k):** Deletes a key `k` from the tree. - -### Search Operation -The search operation is similar to that of a binary search tree, where you traverse down the tree based on the comparison of the key. - -### Insert Operation -The insert operation is more complicated since inserting a key can cause a node to become full. If a node is full, it must be split into two nodes, and the median key is moved up to the parent node. - -### Delete Operation -The delete operation is also complex. Deleting a key can cause a node to have too few keys. If a node has too few keys, it can either merge with a sibling node or borrow a key from a sibling node. - -## Advantages of B-Trees - -- **Higher Fanout:** B-trees have a higher fanout than binary search trees, resulting in fewer disk accesses when searching for a key. -- **Balanced Structure:** All operations have a worst-case time complexity of \(O(\log n)\). -- **Self-Adjusting:** B-trees can adapt to changes in the dataset without requiring expensive rebalancing operations. diff --git a/docs/b-tree/B-Tree-3.md b/docs/b-tree/B-Tree-3.md deleted file mode 100644 index 55094c7a3..000000000 --- a/docs/b-tree/B-Tree-3.md +++ /dev/null @@ -1,864 +0,0 @@ ---- -id: b-tree-delete -sidebar_position: 3 -title: Delete Operation in B-Tree -sidebar_label: Delete Operation in B-Tree -description: "Removing a key from a B-tree while maintaining balance" -tags: [b-tree, algorithms, problem-solving, DSA, data structure] ---- - -# Delete Operation in B-Tree - -B-Trees are a type of data structure commonly known as a Balanced Tree that stores multiple data items efficiently. B-Trees provide ordered access to data in a database. In this article, we will explore the delete operation in the B-Tree, which is a self-balancing tree. - -## Deletion Process in B-Trees - -Deleting from a B-tree is more complicated than insertion because we can delete a key from any node—not just a leaf—and when we delete a key from an internal node, we will have to rearrange the node’s children. - -As with insertion, we must ensure that deletion does not violate B-tree properties. While we ensure that a node doesn’t get too big during insertion, we must ensure that a node doesn’t become too small during deletion (except that the root is allowed to have fewer than the minimum number \(t - 1\) of keys). A simple deletion approach might require backing up if a node (other than the root) along the path to where the key is to be deleted has the minimum number of keys. - -The deletion procedure removes the key `k` from the subtree rooted at `x`. This procedure guarantees that whenever it calls itself recursively on a node `x`, the number of keys in `x` is at least the minimum degree \(t\). This strengthened condition allows us to delete a key from the tree in one downward pass without having to "back up" (with one exception). If the root node `x` ever becomes an internal node having no keys, we delete `x`, and `x`’s only child `x.c1` becomes the new root of the tree, decreasing the height of the tree by one and preserving the property that the root of the tree contains at least one key (unless the tree is empty). - -## Various Cases of Deletion - -### Case 1: -If the key `k` is in node `x` and `x` is a leaf, delete the key `k` from `x`. - -### Case 2: -If the key `k` is in node `x` and `x` is an internal node, do the following: - -1. If the child `y` that precedes `k` in node `x` has at least `t` keys, find the predecessor `k0` of `k` in the subtree rooted at `y`. Recursively delete `k0`, and replace `k` with `k0` in `x`. -2. If `y` has fewer than `t` keys, examine the child `z` that follows `k` in node `x`. If `z` has at least `t` keys, find the successor `k0` of `k` in the subtree rooted at `z`. Recursively delete `k0`, and replace `k` with `k0` in `x`. -3. Otherwise, if both `y` and `z` have only \(t - 1\) keys, merge `k` and all of `z` into `y`, so that `x` loses both `k` and the pointer to `z`, and `y` now contains \(2t - 1\) keys. Then free `z` and recursively delete `k` from `y`. - -### Case 3: -If the key `k` is not present in internal node `x`, determine the child `x.c(i)` of the appropriate subtree that must contain `k`, if `k` is in the tree at all. If `x.c(i)` has only \(t - 1\) keys, execute steps 3a or 3b as necessary to ensure that we descend to a node containing at least \(t\) keys. Then finish by recursing on the appropriate child of `x`. - -1. If `x.c(i)` has only \(t - 1\) keys but has an immediate sibling with at least \(t\) keys, give `x.c(i)` an extra key by moving a key from `x` down into `x.c(i)`, moving a key from `x.c(i)`’s immediate left or right sibling up into `x`, and moving the appropriate child pointer from the sibling into `x.c(i)`. -2. If `x.c(i)` and both of `x.c(i)`’s immediate siblings have \(t - 1\) keys, merge `x.c(i)` with one sibling, which involves moving a key from `x` down into the new merged node to become the median key for that node. - -Since most of the keys in a B-tree are in the leaves, deletion operations are often used to delete keys from leaves. The recursive delete procedure acts in one downward pass through the tree, without having to back up. When deleting a key in an internal node, however, the procedure makes a downward pass through the tree but may have to return to the node from which the key was deleted to replace the key with its predecessor or successor. - -## Visualization of Deletion Process - -![Deletion Operation in B+ Trees](./image/delete2.png) - -*Deletion Operation in B+ Trees* - -The next processes are shown below in the figure. - -![Deletion Operation in B+ Trees](./image/delete.png) - -*Deletion Operation in B+ Trees* - -## Implementation - -Following is the implementation of the deletion process. - -C++ - -``` -#include -using namespace std; - -// A BTree node -class BTreeNode -{ - int *keys; // An array of keys - int t; // Minimum degree (defines the range for number of keys) - BTreeNode **C; // An array of child pointers - int n; // Current number of keys - bool leaf; // Is true when node is leaf. Otherwise false - -public: - - BTreeNode(int _t, bool _leaf); // Constructor - - // A function to traverse all nodes in a subtree rooted with this node - void traverse(); - - // A function to search a key in subtree rooted with this node. - BTreeNode *search(int k); // returns NULL if k is not present. - - // A function that returns the index of the first key that is greater - // or equal to k - int findKey(int k); - - // A utility function to insert a new key in the subtree rooted with - // this node. The assumption is, the node must be non-full when this - // function is called - void insertNonFull(int k); - - // A utility function to split the child y of this node. i is index - // of y in child array C[]. The Child y must be full when this - // function is called - void splitChild(int i, BTreeNode *y); - - // A wrapper function to remove the key k in subtree rooted with - // this node. - void remove(int k); - - // A function to remove the key present in idx-th position in - // this node which is a leaf - void removeFromLeaf(int idx); - - // A function to remove the key present in idx-th position in - // this node which is a non-leaf node - void removeFromNonLeaf(int idx); - - // A function to get the predecessor of the key- where the key - // is present in the idx-th position in the node - int getPred(int idx); - - // A function to get the successor of the key- where the key - // is present in the idx-th position in the node - int getSucc(int idx); - - // A function to fill up the child node present in the idx-th - // position in the C[] array if that child has less than t-1 keys - void fill(int idx); - - // A function to borrow a key from the C[idx-1]-th node and place - // it in C[idx]th node - void borrowFromPrev(int idx); - - // A function to borrow a key from the C[idx+1]-th node and place it - // in C[idx]th node - void borrowFromNext(int idx); - - // A function to merge idx-th child of the node with (idx+1)th child of - // the node - void merge(int idx); - - // Make BTree friend of this so that we can access private members of - // this class in BTree functions - friend class BTree; -}; - -class BTree -{ - BTreeNode *root; // Pointer to root node - int t; // Minimum degree -public: - - // Constructor (Initializes tree as empty) - BTree(int _t) - { - root = NULL; - t = _t; - } - - void traverse() - { - if (root != NULL) root->traverse(); - } - - // function to search a key in this tree - BTreeNode* search(int k) - { - return (root == NULL)? NULL : root->search(k); - } - - // The main function that inserts a new key in this B-Tree - void insert(int k); - - // The main function that removes a new key in this B-Tree - void remove(int k); - -}; - -BTreeNode::BTreeNode(int t1, bool leaf1) -{ - // Copy the given minimum degree and leaf property - t = t1; - leaf = leaf1; - - // Allocate memory for maximum number of possible keys - // and child pointers - keys = new int[2*t-1]; - C = new BTreeNode *[2*t]; - - // Initialize the number of keys as 0 - n = 0; -} - -// A utility function that returns the index of the first key that is -// greater than or equal to k -int BTreeNode::findKey(int k) -{ - int idx=0; - while (idxn < t) - fill(idx); - - // If the last child has been merged, it must have merged with the previous - // child and so we recurse on the (idx-1)th child. Else, we recurse on the - // (idx)th child which now has atleast t keys - if (flag && idx > n) - C[idx-1]->remove(k); - else - C[idx]->remove(k); - } - return; -} - -// A function to remove the idx-th key from this node - which is a leaf node -void BTreeNode::removeFromLeaf (int idx) -{ - - // Move all the keys after the idx-th pos one place backward - for (int i=idx+1; in >= t) - { - int pred = getPred(idx); - keys[idx] = pred; - C[idx]->remove(pred); - } - - // If the child C[idx] has less that t keys, examine C[idx+1]. - // If C[idx+1] has atleast t keys, find the successor 'succ' of k in - // the subtree rooted at C[idx+1] - // Replace k by succ - // Recursively delete succ in C[idx+1] - else if (C[idx+1]->n >= t) - { - int succ = getSucc(idx); - keys[idx] = succ; - C[idx+1]->remove(succ); - } - - // If both C[idx] and C[idx+1] has less that t keys,merge k and all of C[idx+1] - // into C[idx] - // Now C[idx] contains 2t-1 keys - // Free C[idx+1] and recursively delete k from C[idx] - else - { - merge(idx); - C[idx]->remove(k); - } - return; -} - -// A function to get predecessor of keys[idx] -int BTreeNode::getPred(int idx) -{ - // Keep moving to the right most node until we reach a leaf - BTreeNode *cur=C[idx]; - while (!cur->leaf) - cur = cur->C[cur->n]; - - // Return the last key of the leaf - return cur->keys[cur->n-1]; -} - -int BTreeNode::getSucc(int idx) -{ - - // Keep moving the left most node starting from C[idx+1] until we reach a leaf - BTreeNode *cur = C[idx+1]; - while (!cur->leaf) - cur = cur->C[0]; - - // Return the first key of the leaf - return cur->keys[0]; -} - -// A function to fill child C[idx] which has less than t-1 keys -void BTreeNode::fill(int idx) -{ - - // If the previous child(C[idx-1]) has more than t-1 keys, borrow a key - // from that child - if (idx!=0 && C[idx-1]->n>=t) - borrowFromPrev(idx); - - // If the next child(C[idx+1]) has more than t-1 keys, borrow a key - // from that child - else if (idx!=n && C[idx+1]->n>=t) - borrowFromNext(idx); - - // Merge C[idx] with its sibling - // If C[idx] is the last child, merge it with its previous sibling - // Otherwise merge it with its next sibling - else - { - if (idx != n) - merge(idx); - else - merge(idx-1); - } - return; -} - -// A function to borrow a key from C[idx-1] and insert it -// into C[idx] -void BTreeNode::borrowFromPrev(int idx) -{ - - BTreeNode *child=C[idx]; - BTreeNode *sibling=C[idx-1]; - - // The last key from C[idx-1] goes up to the parent and key[idx-1] - // from parent is inserted as the first key in C[idx]. Thus, the loses - // sibling one key and child gains one key - - // Moving all key in C[idx] one step ahead - for (int i=child->n-1; i>=0; --i) - child->keys[i+1] = child->keys[i]; - - // If C[idx] is not a leaf, move all its child pointers one step ahead - if (!child->leaf) - { - for(int i=child->n; i>=0; --i) - child->C[i+1] = child->C[i]; - } - - // Setting child's first key equal to keys[idx-1] from the current node - child->keys[0] = keys[idx-1]; - - // Moving sibling's last child as C[idx]'s first child - if(!child->leaf) - child->C[0] = sibling->C[sibling->n]; - - // Moving the key from the sibling to the parent - // This reduces the number of keys in the sibling - keys[idx-1] = sibling->keys[sibling->n-1]; - - child->n += 1; - sibling->n -= 1; - - return; -} - -// A function to borrow a key from the C[idx+1] and place -// it in C[idx] -void BTreeNode::borrowFromNext(int idx) -{ - - BTreeNode *child=C[idx]; - BTreeNode *sibling=C[idx+1]; - - // keys[idx] is inserted as the last key in C[idx] - child->keys[(child->n)] = keys[idx]; - - // Sibling's first child is inserted as the last child - // into C[idx] - if (!(child->leaf)) - child->C[(child->n)+1] = sibling->C[0]; - - //The first key from sibling is inserted into keys[idx] - keys[idx] = sibling->keys[0]; - - // Moving all keys in sibling one step behind - for (int i=1; in; ++i) - sibling->keys[i-1] = sibling->keys[i]; - - // Moving the child pointers one step behind - if (!sibling->leaf) - { - for(int i=1; i<=sibling->n; ++i) - sibling->C[i-1] = sibling->C[i]; - } - - // Increasing and decreasing the key count of C[idx] and C[idx+1] - // respectively - child->n += 1; - sibling->n -= 1; - - return; -} - -// A function to merge C[idx] with C[idx+1] -// C[idx+1] is freed after merging -void BTreeNode::merge(int idx) -{ - BTreeNode *child = C[idx]; - BTreeNode *sibling = C[idx+1]; - - // Pulling a key from the current node and inserting it into (t-1)th - // position of C[idx] - child->keys[t-1] = keys[idx]; - - // Copying the keys from C[idx+1] to C[idx] at the end - for (int i=0; in; ++i) - child->keys[i+t] = sibling->keys[i]; - - // Copying the child pointers from C[idx+1] to C[idx] - if (!child->leaf) - { - for(int i=0; i<=sibling->n; ++i) - child->C[i+t] = sibling->C[i]; - } - - // Moving all keys after idx in the current node one step before - - // to fill the gap created by moving keys[idx] to C[idx] - for (int i=idx+1; in += sibling->n+1; - n--; - - // Freeing the memory occupied by sibling - delete(sibling); - return; -} - -// The main function that inserts a new key in this B-Tree -void BTree::insert(int k) -{ - // If tree is empty - if (root == NULL) - { - // Allocate memory for root - root = new BTreeNode(t, true); - root->keys[0] = k; // Insert key - root->n = 1; // Update number of keys in root - } - else // If tree is not empty - { - // If root is full, then tree grows in height - if (root->n == 2*t-1) - { - // Allocate memory for new root - BTreeNode *s = new BTreeNode(t, false); - - // Make old root as child of new root - s->C[0] = root; - - // Split the old root and move 1 key to the new root - s->splitChild(0, root); - - // New root has two children now. Decide which of the - // two children is going to have new key - int i = 0; - if (s->keys[0] < k) - i++; - s->C[i]->insertNonFull(k); - - // Change root - root = s; - } - else // If root is not full, call insertNonFull for root - root->insertNonFull(k); - } -} - -// A utility function to insert a new key in this node -// The assumption is, the node must be non-full when this -// function is called -void BTreeNode::insertNonFull(int k) -{ - // Initialize index as index of rightmost element - int i = n-1; - - // If this is a leaf node - if (leaf == true) - { - // The following loop does two things - // a) Finds the location of new key to be inserted - // b) Moves all greater keys to one place ahead - while (i >= 0 && keys[i] > k) - { - keys[i+1] = keys[i]; - i--; - } - - // Insert the new key at found location - keys[i+1] = k; - n = n+1; - } - else // If this node is not leaf - { - // Find the child which is going to have the new key - while (i >= 0 && keys[i] > k) - i--; - - // See if the found child is full - if (C[i+1]->n == 2*t-1) - { - // If the child is full, then split it - splitChild(i+1, C[i+1]); - - // After split, the middle key of C[i] goes up and - // C[i] is splitted into two. See which of the two - // is going to have the new key - if (keys[i+1] < k) - i++; - } - C[i+1]->insertNonFull(k); - } -} - -// A utility function to split the child y of this node -// Note that y must be full when this function is called -void BTreeNode::splitChild(int i, BTreeNode *y) -{ - // Create a new node which is going to store (t-1) keys - // of y - BTreeNode *z = new BTreeNode(y->t, y->leaf); - z->n = t - 1; - - // Copy the last (t-1) keys of y to z - for (int j = 0; j < t-1; j++) - z->keys[j] = y->keys[j+t]; - - // Copy the last t children of y to z - if (y->leaf == false) - { - for (int j = 0; j < t; j++) - z->C[j] = y->C[j+t]; - } - - // Reduce the number of keys in y - y->n = t - 1; - - // Since this node is going to have a new child, - // create space of new child - for (int j = n; j >= i+1; j--) - C[j+1] = C[j]; - - // Link the new child to this node - C[i+1] = z; - - // A key of y will move to this node. Find location of - // new key and move all greater keys one space ahead - for (int j = n-1; j >= i; j--) - keys[j+1] = keys[j]; - - // Copy the middle key of y to this node - keys[i] = y->keys[t-1]; - - // Increment count of keys in this node - n = n + 1; -} - -// Function to traverse all nodes in a subtree rooted with this node -void BTreeNode::traverse() -{ - // There are n keys and n+1 children, traverse through n keys - // and first n children - int i; - for (i = 0; i < n; i++) - { - // If this is not leaf, then before printing key[i], - // traverse the subtree rooted with child C[i]. - if (leaf == false) - C[i]->traverse(); - cout << " " << keys[i]; - } - - // Print the subtree rooted with last child - if (leaf == false) - C[i]->traverse(); -} - -// Function to search key k in subtree rooted with this node -BTreeNode *BTreeNode::search(int k) -{ - // Find the first key greater than or equal to k - int i = 0; - while (i < n && k > keys[i]) - i++; - - // If the found key is equal to k, return this node - if (keys[i] == k) - return this; - - // If key is not found here and this is a leaf node - if (leaf == true) - return NULL; - - // Go to the appropriate child - return C[i]->search(k); -} - -void BTree::remove(int k) -{ - if (!root) - { - cout << "The tree is empty\n"; - return; - } - - // Call the remove function for root - root->remove(k); - - // If the root node has 0 keys, make its first child as the new root - // if it has a child, otherwise set root as NULL - if (root->n==0) - { - BTreeNode *tmp = root; - if (root->leaf) - root = NULL; - else - root = root->C[0]; - - // Free the old root - delete tmp; - } - return; -} - -// Driver program to test above functions -int main() -{ - BTree t(3); // A B-Tree with minimum degree 3 - - t.insert(1); - t.insert(3); - t.insert(7); - t.insert(10); - t.insert(11); - t.insert(13); - t.insert(14); - t.insert(15); - t.insert(18); - t.insert(16); - t.insert(19); - t.insert(24); - t.insert(25); - t.insert(26); - t.insert(21); - t.insert(4); - t.insert(5); - t.insert(20); - t.insert(22); - t.insert(2); - t.insert(17); - t.insert(12); - t.insert(6); - - cout << "Traversal of tree constructed is\n"; - t.traverse(); - cout << endl; - - t.remove(6); - cout << "Traversal of tree after removing 6\n"; - t.traverse(); - cout << endl; - - t.remove(13); - cout << "Traversal of tree after removing 13\n"; - t.traverse(); - cout << endl; - - t.remove(7); - cout << "Traversal of tree after removing 7\n"; - t.traverse(); - cout << endl; - - t.remove(4); - cout << "Traversal of tree after removing 4\n"; - t.traverse(); - cout << endl; - - t.remove(2); - cout << "Traversal of tree after removing 2\n"; - t.traverse(); - cout << endl; - - t.remove(16); - cout << "Traversal of tree after removing 16\n"; - t.traverse(); - cout << endl; - - return 0; -} -``` - -Java - -``` -// Define a Node class to represent a node in the binary tree -class Node { - int value; - Node left; - Node right; - - public Node(int value) { - this.value = value; - this.left = null; - this.right = null; - } - - @Override - public String toString() { - return "Node{" + - "value=" + value + - ", left=" + left + - ", right=" + right + - '}'; - } -} - - -// Define a BinaryTree class to represent the binary tree itself -class BinaryTree { - Node root; - - @Override - public String toString() { - return "BinaryTree{" + - "root=" + root + - '}'; - } - // Method to delete a node with the given value from the binary tree - void deleteNode(int value) { - // Call the deleteNodeFromTree method with the root node and the value to delete - root = deleteNodeFromTree(root, value); - } - - // Recursive method to delete a node with the given value from the binary tree - private Node deleteNodeFromTree(Node node, int value) { - // If the node is null, return null - if (node == null) { - return null; - } - - // If the value is less than the node's value, delete the node from the left subtree - if (value < node.value) { - node.left = deleteNodeFromTree(node.left, value); - } - // If the value is greater than the node's value, delete the node from the right subtree - else if (value > node.value) { - node.right = deleteNodeFromTree(node.right, value); - } - // If the value is equal to the node's value, delete the node - else { - // If the node has no children, set it to null - if (node.left == null && node.right == null) { - node = null; - } - // If the node has one child, replace it with its child - else if (node.left == null) { - node = node.right; - } else if (node.right == null) { - node = node.left; - } - // If the node has two children, replace it with the minimum value in its right subtree - else { - int minValue = findMinValue(node.right); - node.value = minValue; - node.right = deleteNodeFromTree(node.right, minValue); - } - } - // Return the modified node - return node; - } - - // Method to find the minimum value in a subtree - private int findMinValue(Node node) { - // Keep traversing left until the leftmost leaf is reached - while (node.left != null) { - node = node.left; - } - // Return the value of the leftmost leaf - return node.value; - } -} - -// Example usage -public class Main { - public static void main(String[] args) { - BinaryTree binaryTree = new BinaryTree(); - binaryTree.root = new Node(10); - binaryTree.root.left = new Node(5); - binaryTree.root.right = new Node(15); - binaryTree.root.left.left = new Node(2); - binaryTree.root.left.right = new Node(7); - binaryTree.root.right.left = new Node(12); - binaryTree.root.right.right = new Node(20); - - // Output the binary tree before deletion - System.out.println("Before deletion: "); - System.out.println(binaryTree); - // Delete the node with value 5 from the binary tree - binaryTree.deleteNode(5); - - // Output the binary tree after deletion - System.out.println("After deletion: "); - System.out.println(binaryTree); - } -} - -``` - -**Output:** -``` -Traversal of tree constructed is - 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 18 19 20 21 22 24 25 26 -Traversal of tree after removing 6 - 1 2 3 4 5 7 10 11 12 13 14 15 16 17 18 19 20 21 22 24 25 26 -Traversal of tree after removing 13 - 1 2 3 4 5 7 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26 -Traversal of tree after removing 7 - 1 2 3 4 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26 -Traversal of tree after removing 4 - 1 2 3 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26 -Traversal of tree after removing 2 - 1 3 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26 -Traversal of tree after removing 16 - 1 3 5 10 11 12 14 15 17 18 19 20 21 22 24 25 26 - -``` \ No newline at end of file diff --git a/docs/b-tree/B-tree Practice Problems.md b/docs/b-tree/B-tree Practice Problems.md deleted file mode 100644 index a7a8a3234..000000000 --- a/docs/b-tree/B-tree Practice Problems.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: b-tree-introduction -sidebar_position: 1 -title: Introduction of B-Tree -sidebar_label: Introduction of B-Tree -description: "A B-tree is a self-balancing tree data structure that maintains sorted data for efficient insertion, deletion, and search operations." -tags: [b-tree, algorithms, problem-solving, DSA, data structure] ---- - -# B-Tree Practice Problems - -### Easy B-Tree Problems: - -- [Insert Element in B-Tree](https://practice.geeksforgeeks.org/problems/insert-a-node-in-a-b-tree/1) -- [Delete Element from B-Tree](https://practice.geeksforgeeks.org/problems/deletion-in-a-b-tree/1) -- [Search for Element in B-Tree](https://practice.geeksforgeeks.org/problems/search-a-node-in-b-tree/1) -- [Find Height of B-Tree](https://practice.geeksforgeeks.org/problems/height-of-a-b-tree/1) -- [Traverse B-Tree](https://practice.geeksforgeeks.org/problems/traversals-in-a-b-tree/1) - -### Medium B-Tree Problems: - -- [Find Minimum and Maximum Element in B-Tree](https://practice.geeksforgeeks.org/problems/minimum-and-maximum-element-in-a-b-tree/1) -- [B-Tree Level Order Traversal](https://practice.geeksforgeeks.org/problems/level-order-traversal-in-b-tree/1) -- [Count Nodes at Each Level in B-Tree](https://practice.geeksforgeeks.org/problems/count-nodes-at-each-level-in-b-tree/1) -- [Range Search in B-Tree](https://practice.geeksforgeeks.org/problems/range-search-in-b-tree/1) -- [Find Kth Smallest Element in B-Tree](https://practice.geeksforgeeks.org/problems/kth-smallest-element-in-b-tree/1) - -### Hard B-Tree Problems: - -- [Merge Two B-Trees](https://practice.geeksforgeeks.org/problems/merge-two-b-trees/1) -- [Construct B-Tree from Given Traversals](https://practice.geeksforgeeks.org/problems/construct-a-b-tree-from-given-traversals/1) -- [Check if Two B-Trees are Identical](https://practice.geeksforgeeks.org/problems/check-if-two-b-trees-are-identical/1) -- [Serialize and Deserialize B-Tree](https://practice.geeksforgeeks.org/problems/serialize-and-deserialize-b-tree/1) -- [Validate B-Tree](https://practice.geeksforgeeks.org/problems/validate-a-b-tree/1) - ---- -# Guide to Solving B-Tree Problems - -B-Trees are a type of self-balancing search tree optimized for systems that read and write large blocks of data. They are widely used in databases and file systems. When solving B-Tree problems, it's essential to understand the structure, properties, and operations of B-Trees. - ---- - -## Table of Contents -1. [Understanding B-Tree Structure](#understanding-b-tree-structure) -2. [Key Properties of B-Trees](#key-properties-of-b-trees) -3. [Common B-Tree Operations](#common-b-tree-operations) -4. [Approach to Solving B-Tree Problems](#approach-to-solving-b-tree-problems) -5. [Points to Remember](#points-to-remember) - ---- - -## Understanding B-Tree Structure - -B-Trees have the following structure: -- **Order**: The order of a B-Tree determines the minimum and maximum number of children each node can have. -- **Node Structure**: Each node in a B-Tree contains multiple keys and has multiple children. -- **Leaf and Internal Nodes**: Leaf nodes contain data but have no children, while internal nodes help organize data. - -**Example:** A B-Tree of order 3 allows each node to have up to 3 children and 2 keys. - ---- - -## Key Properties of B-Trees - -1. **All leaves are at the same depth**: This property makes B-Trees balanced. -2. **Keys are stored in sorted order within each node**. -3. **Number of children per node**: - - A node with `n` keys has `n + 1` children. -4. **Balance**: B-Trees maintain balance by splitting and merging nodes as elements are added or removed. - ---- - -## Approach to Solving B-Tree Problems - -1. **Understand the Operation**: Identify whether the problem requires insertion, deletion, search, or traversal. -2. **Visualize the Tree Structure**: Draw out sample B-Tree structures if needed. This helps in visualizing how nodes split or merge. -3. **Consider Edge Cases**: Think about cases like an empty tree, a fully balanced tree, or a tree with just one node. -4. **Apply B-Tree Properties**: - - Ensure nodes are balanced. - - Maintain the order and number of keys within each node. -5. **Plan Node Splitting and Merging**: - - For insertion, know when and how to split nodes. - - For deletion, be ready to merge nodes or borrow from siblings to maintain balance. - ---- - -## Points to Remember - -- **Order Matters**: Always be mindful of the order of the B-Tree, as it determines how many keys each node can hold. -- **Balanced Tree Structure**: A B-Tree stays balanced by redistributing nodes. This ensures that search, insertion, and deletion are efficient. -- **Handling Underflow and Overflow**: - - **Overflow** occurs when a node exceeds the maximum allowed keys, requiring a split. - - **Underflow** happens during deletion, which may require merging nodes or borrowing keys. -- **Traversal**: - - B-Tree traversal is not the same as binary tree traversal. - - For range queries, Inorder traversal can be particularly useful as it gives keys in sorted order. - ---- - -By understanding these core concepts and approaches, you can efficiently solve B-Tree problems, from basic operations to complex queries and modifications. diff --git a/docs/b-tree/image/BTree2Ins.png b/docs/b-tree/image/BTree2Ins.png deleted file mode 100644 index 17e1ae48a3f081cf386109c37eb7cbd6a3527176..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3721 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 diff --git a/docs/b-tree/image/BTreeIns3.png b/docs/b-tree/image/BTreeIns3.png deleted file mode 100644 index 7c9634c9d97e96f1b6d212055c40d09d26375043..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10480 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�eu>7*@qj4^uHcy<9`Fa-&sb)WN7v<|E%Tao_ zP>gM#=g@o7Ant<bn~&M%yLH`hWxuRpE`w_Uff{&TQ;Nihkk!ey=NeOUrD zFNs4Sf?5s`<^0E=q)mBcDI|mMp350B&ijlqqd^~0Cb#jctDohcD6B8`>ld2FB|9zG z$$E}(#pe}Es)?bUW=9ZcUvhy|HljD6mCM7AqH0?3==jD9_C48syim{7lIl%ZYl@M) zw|p8Gq^M!3=7>FTe|7k!UmojeK*S^3s=KTcmOklz_D-6R@Njr)0@E5Sa7<7tLyolmmBB2k2QfRX4cyDRde_h6hZ_{-SGX#gvoO6<^Y;sT zt;!z{;UTbYJn8`RC5;H&)#G{bte(Z9{_MOGhWz9H1noE^d#uPM~E*|mJfRoi_c;rft00(HV zhF}?==V5Th`kt8=8_3^7}7S5*fOgP#aB-32|~ x-CPOciysp0f<9{B@G3L-fd-g_bMQ}O-DsBR#eP)LfL|#>RF$+8ixkk<{{dPGG1&kB diff --git a/docs/b-tree/image/BTreeIns4.png b/docs/b-tree/image/BTreeIns4.png deleted file mode 100644 index b8f86a2fa307625acdd7a1eb258b92fff286f225..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6671 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 diff --git a/docs/b-tree/image/BTreeIns6.png b/docs/b-tree/image/BTreeIns6.png deleted file mode 100644 index a88ed91638e3eb293babc0689e99145631a2dafc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6722 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 Di35|1 diff --git a/docs/b-tree/image/BTreeSplit-1024x321.jpg b/docs/b-tree/image/BTreeSplit-1024x321.jpg deleted file mode 100644 index 2e227ff8ca318b555f5a5a046032b75c9e9ce3f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49605 zcmbTe2_Tf++dn?CFWIthqX;EQ_H~l%St~?H${Io#3}eZ@l|l(awq%)P%{KNW*+ur5 zv1Okr%fuM}TlIXu-{*PX-~0Rh-^oq)ai4Qv*XO#FiA=F>jV1pAv*!kNJULUOGghpP{j;7K}Jq~f`a^*YT)T0 z;P)U37E0FBQtDKvOzf!7c(Pp%eU?KbbhW&N-E;^iEPc-_jFygrlZ%_@tca-Cx$`oz za`Fm_N*dQRwX}6~^={m}WoB-1+tU920|!SZXBY3sKE8fX|A6o(5s^{RF|o|4Uh=H685FR-T z2m(4ZeG@AN`gMhCIf44vOs-J=zS2QrZ(@I6xiZFN+InKyCt}IogwToQ%79EXxq&-r zO%R*00UK~f6+$QduO<_q*(9Cm_fwR4**t$<5GxIg?RPxF|Lc`o1&s7-G+>DEBod06YX#eMEu~NG5Y@E9q0)Hnhii~X1~QcH6|f(+RN1Q*x%>47~9&SH1kwV+|(DJk>nG zY4?<2H|ure%(k|(rZ0`e#5&4gk`>X;lYgq2<&EAd>z|2FKk0=K8NTs`w!Q&)YQb{BmU;XP*E_ z0093FLjDNsT>g8d5kCgUM_r{LUCm2!TIy68O2#LKe#`EdgJU@y3yNQ?51{Qgr@!QW z%@&9GoGQKcT|22`A zqz?0fl~(2|;H|1wU3F!d-o>|_2k2z;U!U(@(&dl}oA$A@vB!aTJI6>0&>FqrIdoJK z>};-!T%QkT^iCXWDy2%}H&|ab^E|JP%7U3BkzIpy9ocESGuw3p(#w4Z{$Rbe!7dus za5+n%0(Sv&vMb`v0mY>FogKQ0^egznX!S@fgeM&9P>kJTCIs$^ z4LyeQxC-z#;2B?z?OA4Kws9vC&3|}R}CR!9rFZ}#yo_z47rzv9=6}q2W8!*Ua zzAV|&EsL6P+-)a3!ySQi@wU+_))*@|r7o6hov7izTV&8m`Jm123dA2ue){9LlV*nr zBzhNkrDKH5T;l9`LJM}vgR8f!a%pnF#A5r~e4-sGevoA-(wr=WERw84>|m^V4)>51 zR(}MtymQc|L+C+oz_Df(X!?`R7gcO?r_L_!rVFNAmy#m0@;8oBjv|X$`Us9dal-89 zJ>n3|4U(lq<q_wHdd4$f+T5q@r$Y@dsm;sVcy_=PamZcEL0K?CY`k59 z$A|-3CsxU8WgSeL`{kyA=ecx625G7IttT9v{ftt5?#>Wym^p3^JGW7aTuG~uA6KHx z&)at^{hS~p_nm+3qrGqll^-(|qhe8=uI`RO%BLw$>*0feVOXqn+ZalSXpO76gQH$g z$O#_i@#{o!-GON$*7u(@1(yhyzgh??rRzv)AZwwFR)9zZP`4N2Z2@hV0%JTP^YE$l z=tkuZFp~t*2U@8gPX7V*O1L~*k>)dWChQ9T>iSmi7iCD@g0$39ri#lzux*!$wg(H>d~nn5tlOx>xyo&wk74kQrFd2xW_X7slItOQIH6GZ`RrVb zso}Yr;UiG!zP$$?)oFll>$GA1Nbr0+LD0T7+%)HmooMK&Zc4jX9-(WHsmmt?IoHj; zD8O=9Lv+Sd?^=&Eog-LbWS3)PdrRH6YjB&-Rnn*wQo5x%bmHzZz!|ChWj{I13Vsne z0)@p8U5D?FmMsipaSy%DKJV{jvuA)`x{ekw67)l+R;v1$;`WHF^%`}lq*PXL2V5?WA)RM%*jX*0V;A zMbV3uP>i5NF`JrYbxSR5qG!c=JW0jM`+$u!k(xG{RrB@^Odb!96gd0*M!hrZ?C$WX zaTO}K1g#*$tE7CF4L0Q15h&sa)ZHl`==ug8lr-4aHkQyf)?@_m{b)sLXRbLA!3Ry= z-Cr}q7nFLJl=wZb44a*K{ZK44X0n#DmV`rcB3jdt8~F!!h*r3oxL`r(^Hv)^oLsN9 zs1|O9P~o@k2rG6UF!dzrT?Vmb&R;a2Tz8&PeB7AyvFQ>~?>#{k*VR5NJNhOW+oka# zc~|G&!LS>j*q(4GVLU6iXO6GI6aS+n8Tz^d#drk5P>htNiYEvdZLrlH_|zAvIe-{4 zYws$JFB5o{J0M?2=I0_|H|8ZgY^n%W@498I&6G=czc$}z?*FRx(4KoLBRhv=5==72;1rl*&|k49}@*ihi(~ znOg|DXu-H05mg#&5j-;K7YhR)=s*#jw(PPV(Y^@A{v3v20lapYk63?Z9$DoDKQn^p z=}$!zIrl8$m+DZ_lV-X28WJ5%6ImSA4240_tdeM|Ycsd42F_T0>-x-b8U4hu``*>$ ztIuxm_K5qS7QGfXs}V*&)D{VN{AJs41U1oW-s!@rn`s*FlXo62r1jp8jo*+6kKad+ zKm8i~B})d+6y8J&jcS{tm)top5};Z5l3$*zdv9>w4W(SysScL*I-u?yYf{4%pvnlY z7>|uOT&l;ZRhx^rnkNqntS=tiKy0uUU@=d7rt#hUE$GLk%3I7X>5{EmUkxQ7rVZt> zt4my)Le-hMx6}4)#Y2MadeHkLN$quWY4}=QOSRxV^s{}*LYO_yw-B#kOz?3l6>gG# z|G`>oS)W;tN7?Hp^{lzwVp>T1kKu;r^Lrchn53{Q`3js|8fL=}E17hW`8rG)6X&6Z z6^j=2o>x$4nIuzC#5U>T=GH%EyP|NWM<5<2RsynPY-~5+da!UJcJ3Cvr*J1$t%t`8<(t+o-wkqSNXS8Yz=&r~IJlzezk?l}pa z^kZOh7hhvyT8*+Ad_1F>%OX2d>HV^$+xinPH_>%|fN-8r0r?;rWAHJ=`UvFW-0Ceb z^YcfVJJEZjAkaL14Z*0Qe{c!*@bEQJy%464H;=Aj;+>XAt*1izFIjds-BGl_f+(&l zfcTzOdf%eg*Q(1W+z~Ey_4UB3eYBkv>hx{8NN9WT4kkS+gJ6V;8@g_Y+X54O&hkNg z{TV5P+WB{>T`&RhqQg{@g8soZA}g?6Cb`SJ7+e}{k0`Ov_*}mJ?0MArkNwlz?B5xq zuqRCqc4H5#WO_68Hs_71a9=N3>MP3_KYutO_5>5Ki{!1sBcs=kKz6`d)Z45Cj=l&x z=Qs~%zT-TZiga316bdogBPV}W+mofV-lEWdk11WvBMtv>*k#zY0v>k#;Ghdq`DNe< z#AS|x2sWS+FScb_`7l>qGOlTJBFpiU(4>Z=qjg)UWH`h*5E*S-S(r%TcCutJ=P`dG zLs)DYw^@wZzmM>mbNKA*@!AiUB|g6aMpxA|BM9fft%#Ff2?I9xpy(lYktfhdynES& z?;n;_(M&Hg-cv9&&NkYTXx|zZV&^91EkBAF=&g0hGxrMlh$V=$Z1YaOqkrY`0iLeE z`7vV~PGDN}+xxl)nULR2@tB0PTJDVHyg^1b=wc2n-Gpupb9l>7ENZk&-_oTB^i@mQ z^k>I)t>53s51z8EQhVm4Ga|6xxsf|SFLjDld)(XcoA{=Wj14|M?Pln~hZliTPFtF6 z497m8)UoCK-&|CX*lil(4NRZDPP%g`wlOqE`pTm4_4o%m-!y{*!SS<71lwF_1%{#K z)a=^us<@-$+a5*71U}6B_T?pBn(gTz@olC~zy0c07;D4jt0VoTCEE17R+m<@?!Wx0 ze&GuFs_VS=VFFPfYxHEYzrN(k3jXTmVHI0K;Z+@qr86zD2@?_-xT`-p#oN2CmK0

    ?0iR~U4*@h9ixw_UXl1bMWxngC3BSjIJOVu$`4 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 diff --git a/docs/b-tree/image/Btree1.png b/docs/b-tree/image/Btree1.png deleted file mode 100644 index 9983d959cac3f56d602c38dc9e4c3c9490a4681a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2049 zcmd5-XHb({8vYW35D*fo2p0@R90RTbQbsTWHweMd^JOtK6#=PoL3#@!u+pR@fJzZX zlLMC`9i(`r2v-SG#9Res6|y2tMw$xj2QxdfzxMb3IORF#edf$L&vV}QroFADgqWfj z1VIuME3zX5p|X&h-4g$KQ5eD4V5{?? z5F~$ix1lJG8p{wQ!lsbTXp!yRb*d)2*k(eLQEv*iyIxIjhvwLZb&~qNmaGQYMn9?OnDkmW&R92Y-VC`InaYk>QFelt z>z~wb$VQSv6{g({r)T8iLykdQBE^WxU62F_mZ^(t~uapKpx1 z9UHdPRG2U~O)<>@uX%smO*rOXluf?-7#HLHv7>gCSPj(7#jL5Cha1o+(Rplsr5`(M z>08uh!jSF!&RprzN~v9paGkv4<)jw(39kpnk3m{&kK_rVV+E$BY}0$d{D%=QNq2`I zI*chX#5o#Q-#@OUjd5Vj2bAlJ($wuAg3Ndmf6mtHfVg4hDROK7>}ahM(K=2grQi|x zJ%A62zmV<#CUss<%ETTD_pt1UNwuP(O8U6I($UJD6|}`FWeqB zGOl?Lto-7yPh%-XUNI}&yz4;nZxBU=VnC%|duqE%+#!BLMYTtj_K5`94#-C0;WpKnXFsKVTS@eihlAlaidlk3a^5;CePB3ZDv& zPZy~ol0MBWTu++6Huw?ADRtTV=t)L?boG3a8aRhbcSrk7`a421L%@O>{(y2!9ve`;4mQy6^DW= z4*u5r24g?|W>YFn62>MzCXd^bGk4(!r#k0`VG`hSv_>b-UZ)0160)SbBRG8$`N`ujH@ zPjs1>l$OO9%*wcheqkaPVN!B%pUM24?VqbeE(dhRMTheLqU$vF_D89CM==}T6hmOH z^m^VHR7@3sBl*96r1K$g-V{0{1ot_bt|}75=kbOCAMdyn&v$L zLvqYe>9h~dIm9*0U^ef0OWX-G$FKIr7*-I#x1`O)Hk{654At7h#ZMT1a&Xb}a3wg< zqjfMwNh_aOuXD$$>YiCSQD%VTvKCcIqerit# zMs!1+W(FcwquOL+X&PuV^59N;C0C#CTo`f~4-~AQYP$_Wy5MJ8WttD23e3vE-`==H zFr47+rQsHjs+&I*e#P|g3tjXccC{hKaqCQKaHp+3J#?-mUMY&dXi=m6o&Hk1xx7$h z+D2goNuegAC>L$wk9^=N()!-neM^zLX-AjqH6g^9=OX^SY$Q2l?ZAITYb24oT$|1a zJFO*&=?x%!p3pQ)#uT2Jm!0I+&FlA7U9skf%fZ}p=PBKaf4Y0VINUm2VuI!nZ{@92 z?zxg>mv`@(CH(6nOQO-9@wlK%^t)kR5i7Le@z=ZGq{45*H(Da(RfP3xH75%jvJ{aY$%yYR@#4ACF2i4;C`qi7jm zT=qSH#^aGshq*W+iy_#jLjYK?!&M>F|8ZbFNlYV!-%{|#5e BnB@Qf diff --git a/docs/b-tree/image/delete.png b/docs/b-tree/image/delete.png deleted file mode 100644 index fcf54d2ab911f706a8d13b0efa404a1f60d590b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39552 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 diff --git a/docs/b-tree/image/delete2.png b/docs/b-tree/image/delete2.png deleted file mode 100644 index 410564370b0c1e171d6e41c7d37e699ae85e1601..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43420 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℘FC49_+J@fGtaq0V!0 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 PrFfyF@vQi%`N#hQi;k{N diff --git a/docs/b-tree/image/output254.png b/docs/b-tree/image/output254.png deleted file mode 100644 index b8c1226c6848819a4e700683a34b9e2f7456050c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39848 zcmdqJcU+Hs|2`frGLxi8#kyN=t<{DoQ(&w6vs2DQRz-($bdJ z_c-0x=l|c|zx#gN*X^R-o#*TI9LI4ykEftZDzXRm((EN6Avqu~C#6n8vLg(?p4q(% z|8$+y)xiJ#Yb2+xOhV#ul7!^89|_4H{MPLsBqT1pBqTp?kdTPPl8{i_KYgbrhCkS4 zs39kDEWd;VEb ziIsiKH*$)=^H?C{e)z{6 z&s$5%mZOUT1nf|CFHlEAu0|G)hB#x}BVQKr1_r+dkd?U|UkVX{+S|56d} z4`)l+n6)~ZV|&QRZkVOH3P=WC{rc*fXc(>V-6U4a04B$v%ULN-<4sEOB3jdzaMmM? zG}7hM*CnLyh&esXd&VRkOio3W>UtEnF;8yc;MGmJlZxB#dzJE@Xe*W zpObA`N>O}5f8h9sdk5@SPe-yZ*?TJ}EGORV?#WLz`q5e!N$xh0H|K_i3$1!P+PK>L`W8LC#HI!|UZ>3cacP}Br7GdEb$@@W&ZkdNm5q&&k?ol~ zdkeSR?mIZ}I;UH#r^xJ>nc=mJ%wV^)4Gz4WB>mj$rq1hc{-yo@J=^#xJX=R$4%;D7 z$LcnJr>$FZ${VvAdIf&(&+k4UxFO+^IkA$dWzbtN)vI4bV$*YeYtw#H%-uaUbyesV z?c=inw>Ibtyf&}N>{|cj%NF;9uZl9pcSm*g`$)Fb=r0znN*Vzp_n2jsxWZ(T|1SYY z3?2!UTc;?*)t;eZH?}-v-CFyWlb3wJyHk@-kc(^l)}W6a`>px`%7d1G(y^z0D zu~{|E#Qa?LpvGz4v@kYdQHKwa0^HZh3JS<6|GDlHzaU7(b1z)t?ufC*UC+(Z43ot! zz8~F(XZr5&8Qti9(|41H=8Qnik8d|b&ipU&r4mjo2xVSS`&a1bN!2r2st5KpBydJ^ zA7JpYWiMBL_?mx(Nbi`Kqa;{p4B%C%;(g-dpId^sC z2ALwGRC#iXxv@ytc9|WN+*f0N{j$%$ct~>h!vMLEWEugQ^edg3BxVg%8cg|?QEa-4 zb9WSDZq$><3QkTWdNxqiHwsK|HNQBd)USM{@C=KUsH@o3a(tn1wmw~LXhVX)UA8+L z>rSofA!({l^iDg4oCy8jg^yUMYiTJX{Z@}EMhk2Vm># z=F`qsakrYDnEibGhc$*f?v{S>ynT0fUTR{#<%XwXQb|dM;&iHVs`1L~HDiBrri#=2 z{7e7v9d&$__g0{P%Cn99F6mpn*9B)nx0)I?*UV8j0;we_>Pl^c{J|!iichc9J;xGfZ4=pKat7@74w41_i#)R-Ze&-o$cA5gOo6B>( z1qHk}NCd1*GZnmlkgv}xHhnO>bt`pmS9y7=)ACezx2F@)8+Q7g2;+&UBr$7><(6At zcXTE7e&5?GAYGGdl$sl$TGi6B$S-u%vh&s(@B6g@d&c`qQblKJJ|`E7x-~7@sjB7= zDx-6_&X!xTQo8F33Sx?SBVSm}v6`NVPmr?4LiP4U=<;v!B<5#s)?^|TA zJY-I#s*?#-8m=SVe>?aHgY8PkmDJ3x>pnILRBMZT@lQHm?(p>dzehlxDJ3MN$~wQb zpf!?{YqFs@tW3?kGW+D6zw3_&-roK1QWNt`;|f;OmZz0phV7%4cvqz2_$I^fr|;^& zTWm}p1e9w(Kk1ISUS|1tbH}&*P9-PtF(RE`Cd&+mcy!|W)9fk)^O+=miV2%P$XNQ7 z9RBT>fso55O?xFZr3QNU4VR)@bP{X(xv$@A&ocN-(^|AdI&O(;O1k~vRVGhF9{>7c z#6;4_`pwq($=XomD3zDlO8ru9)2ENT%+2HPuPG>K+N4dEeZs9Ic~RMjlHuwzr37o5 z0F8?B43Wv0>mNL4<5EY`uMaM+pS6w6OslPX!hL&lcFVC==gkWX?s^dyr9DXz5o~dN zZ+03QDG$3#{Qfpr(k&7C?B7;84<{#`cLHXQIQ__ZK2`K*f3;LLqQ7`CZ}3J)2*1lY zoBkf>CPx=R7qyL16GP=D{>~T#`kWNzD7*RYgr-fyF`&=EwYZjJa^`pS1 zyO8a2qo&{Y{7%Q2>q-Bt&jql3-@A`LUw@#?O5wDNNUPDJdHU63GWTznc`Aoj9OoZ1 znEZZD(AL^=j#gmzt*wpkj-k6A3-HxkE&bifP?(>ep_dgEHL=ZpJdEv5`()xR&NOn# z(%l6GsZYGVe}C}cmwmCmoyd4cx&eBMw{io+{k2=)DvOnB@9bmrW4&?0LG$9=Q0gbo z;o7(vx$EzY*_UR%8$6cH)y=C@t!ydE&8Tlm5Kncuzcgu?k&usQ<-tH=Zz>tFYJ#h4Pw1PIE-|*2hKC!OnzH}= zlHSsKt|C4@L-F!tN3m1(<;%i}4OLZb9+m=QDxKPl)%y-pQ`e1sexh6K$YR!Dii^{``>1nwlYMJ9vg`%dFG;?Ag}lt}d@@ ziwz$?2EB8cbe!oEes!&+w%BR>_r}WL+~VR3?HqmQiLd^TSQLkT{tPZIF7EjbbnCw7 zFW`MR+LLc(-BlG@drYA+>!|>R@daQEP(p2c!wKDx;Vzet2X*D#y zPw8rOdQnri>R9tGJ^r=e8$zwTvsO}4sb6zTUtBBs&TW#`ik$1(YjO!8p`iz?I$yB} z2t>A~spk1?-8y62CnqPj``qSlW{otJn!&+Dd^GvdqxDufW%puYVtNb^aqf5UWT~PP z2WvG^!?~tVrmt#g$=+LNXZ9(QjaJN^Jh>%MCb{y%hwWx&W*#dupPyauWz|T% z-}AkkRxvtuEE9>RDX*obw8gEqT_#MxCL)2X#O+Dy`T3Qz%DN*z%xSLM3Vf*awPdJq zYMpTY{rmT~;o*yQVRUg~H&4rk(Hi_&oXEab65SBP?C-zu|ExWD&ETbRu5x$P###`g0g^2@V>&6^u* z!p=X)-DU@NzVGOW7IFFc<=KTDKRaG3etsemyZKA5QJtKss%&!0rBZhXgr)4ppQQ}#9Qx5u zQ5RR5bDtqJ=jjNdGj!zPg9q;$sGY-b3--9#61MO*OqH~dT93T z+b5vE%sXto=y-AJgB(Cb`CRsG~QLrdg)YV)_Q%SvCOWN3|w9upS)cnsi zwHx0hkMh3P{3w#>@u+%ko3t99=+w!R_jL12=N6jJ9X@<`N30$v7boYhl@+s*`iF~C z-G?WAnv_vlnFb#atZHw1QISy7Q{k$);kxd(7KcmRW={_1u$>I1WRt83K9X^*Y>DgikB*ne6Aqqy)y(oph)S$DN@%kcl|-k&`q+~*HbZ#0 zzGA0SSy|3y9!o#IrtCXFBk;_9Zm38+wnGZdCxMaRts@sRGBT|D-wAT4mAX#T$ji%< z6crUAWMoBLrvfV~&Phl}=;-K_J`g(L!0E29IrRHHQnB;Zwc(+fkZhgYyGxUu5$oEO zjL1ZVXioWj%l01wWul?S&&qH(ZQ!sH{{8!7b{so)th%<=abZk(tU0k6Q5qB;PWm3< zgm1+8)_<$?wP;QKtoUT_1&X@6D+SgDgXP{&g&giact8$x*$h)TD8_K_XOMVm z*`8@&Ys-C24~e+*uTG(v+Bvyr&z|o%8(Jaz+sMB|G&I3UtX(}l>M06Q*?Zb2+cJDZ zLPB~N%^p_ge*4G~G(6Z}>=b~nbolmu+g)E@Vb5jGiHQmGd_5$FG?Dn%D8QgK4k23A`B&j|3_8*gMP7rr+a;oa-5m7Bj zmmAXgHBy5l_N^ph!N9-(6(eAEVf^rsBRgX=clUO6UCK3-zIWib4Bj(0H&;#67)XMb z=s1BfCnO{ia4RZLg(?xD-H1@cT530Y>q#F{u}{_Gv_^fHtp8NpVG}glWjTI8F+YjXlZG`m$E7#M^7$93fHGtW zMW|j{Ci!7(>`~kPcQrUhB5jf1RX2DM6TcQ0tDBp{skrovue~2jlbTC>tH(tnU3qQ# zyws~85~7Uh=*0Fs7voQEsqfA+(|u#SN7QX*1gC^jZX`gH`}*}WgQ|PZ(>+mWA(ygs z_-N_q7M2E|1J3RLTbQ^}RLy1w%ChzHgNN(FotA#KXLCD+g@wJfXuXH1rXVN3os(mC zXX3PW#Vv0#da*#SC`wwrm(dC0o)nanFI-uRnHU-GaA?1>|JlaYk*!;Wpq7)DzmVMW zZEQ?t;%iEVRuWOp-e`V*XdZvXyWI}oUT0RegT-zD+HFID5t5!zb+`aENVP=pZj`wqu-vxIz{#d37nTsBs6WTt*oL6#EH6b7uxnS z;drxHqr$@v?jR+50bEy9Tx?)x$Fnt#pG5t)PqE=d@{H=pTxSP9w8fHBj~>_y|WPU06K}ijkk6pZ($wHR2Oc z@QYD4ND2xHG&41W^ztoRiX4mxBfG&v#oT}Wdv5*L4xCY=URsMe zFF$|s#Q?JVbfVFZ1+6maUe%j;lqKN)b8Y)YPAbK||2;R{P9|S^9!2SU$!xjNcvC!U z@S~*_J6l_oid!2;`AzqyD8@w3J&+94e)RV+4M4%0n?6o(Igtgk0g za{5rVvD~{j-AnD}=5}mtF<8j{8_AtJcZ`jVpS76B@)_;&-E}}+lymNpv8m~!*jPDp zb5?${CgXw9o2YZ!QAdM(eRo8$YZ+Dt9&-Ni<-)W*ikv^8md<@rkeB~HKicqA)GZ8! zDc7KC*Q1DtZT7CNsQ|8;Ir{NrbRu6~8(eJs{JEV>x6~MIdJILh@lStEjX!GV_o1OA zS98go78VxP1Eq2KR-KN27A;;~EtWJiWFoP(wIy;D(XXDWbj-`!8)0_ZXrDbKn)+z;~ z{HBdJetoO73^=7}EI>n`08Y;PpP!sPOi5W?6GFXB!_5_iMIn;)0wVfvqfSV$3;>#G zRz{(ax|7Pf*TKO74LSh9Pkhsz9i+T8p{Ub+eSN={m&fuu^^@%e%YUz}WzoH+(~cWWld~00@-O~hx=S5l?RH$cQn{S+~@k56oa30e(9pvi#*sF4SfkwhpyTYz zaxX6{K9}_W0mzB+6Xnn;87Ov<_)!UF0yM=A!@JOTn9(mmpq=K1r11$|G!xCU*3Ub*!@|RkO4jCBZ3Ci@Ga( z&f#;1(V~&(hNxh;G4p{^VdPvB`zz-0vy6T;#4V5L0##;TuSkgFHzPRd(9n>aqT&uE zr_`m1)&TU)ZA0h66MW(#AVrKF{|eH$6^Ljxg@+qDwc ze|GIsV9}iWDmTR1Mt=Bk6^emQp)DPPY78NzYgB~%uox^C=eknx0&!2tad|&T4$;>s zZxBU7(`~YY>+(yz8c^&a$I-oq4jm#YU%Mrn_A6Su(z#vAPtMfz_8v!ZEVifSxrU1g z3<+VDkf0|eCC#roloJak#Kgo@gnI!rH$)@7TH<>{vMe$|n?hBd(s z$OHnt;X>QVWJ`z8l`AVN8{v)8iZ!}%kzsU%iLB8(u#_TkI&dBG(>Y{=$DC%HpIlJFEXhM1mq1KNbR}g&Yzt*s(5ME>*b|H4Vvd88V!$M66=eUltT;* z1Ql4FE*vbnxp0z1B%Tasf{NAn+Mw#kV8uBV6%|y?>I!s<5o!WyJ{Al?0Y+cC2h<3r#f<{w|4??C(3(bH4#zsy*Dn5c6Pv+!lY=+{7@!|(6xpcVIsMCBpD$18yn znYX1MLP#Y67yob;!DSDfi{iPSu#cMC9_?d7f@|LY?OOq&zJ9L?03JKIwlaH)o12V; znwr|OBU`@zor^`+Yes~A^al~iKp@p*awcuSieHmC6{meRy}o|^T95ze5m;-$XUiKY zcMmC#K5iMnQLT}2rH~u9L$E?%7DUNV27>Cr!-th$QxsP>*Jg#?W@v9@Qd!&DhLx3x zSKT{cgyso-D2whDIaB!G-l=3eSpFFeU)bw6FTwdnK1PrbP(OxS8N_J!{{1fyneLvR z#J4o3pdmm!xkMqW_V3jq`#bofTwnu&QX_%3wXT)`w!F1$4@Qa5NKrVF@rB*5o(XR? z6m)F=E{Hev*}8c`ERF zBKzej-Lao8`t|F`I3}YufA<HN!YwscnCJz?z_s41?;E6}ads=tBzH@}*G6s~p zZs+F<0?I~mXoumWzhr80#7W2pYGb+}xm#Uby~u5r{*=noZ{g=QZw%Ll>INkNBF)Uq z2w1iSGG4rQDc@2{p0b8x{KAls-GJDimDwCuA<0rrGy;fqr#+Xg$rvOW@k==s6&W?k zsi~3Y@40`hyIV zL~vT54Qy_1&X++SVd4stEM=mUW(2Q>XcNtIy$Se12=N@8gsREM&tC1?7St{WW1;vN^$M|)?g@~wQX5JyK_GQ8uk#qa`#ejJz zlm=E-Au4GRQtE+TN_w>Ztlx;FN2^7)nn460k{-VVDzSHRN=BT3@+G2-s{Xr zV>Q2%y?y=9rpFM3t*tphD@Foz{EtlB}tmlh;B~4EHqA#W1K&P63R+~ z^F4j~5ytDpjiQecMH|Eh#SE|pBWQdCVgBM_?KzCNd;Lg_XlMJ1lU-RQM-*v7cZrIMB0*Sn-<%NlTqb4< zoY%{r;%FR}ergeH)PEoKZ}cD>npeluN*2ZF>i+&~6!MIkgwnHm{_0g)0$YGiUoCZi zc>JvGgU65ep2w|Bv?P;q>AigqUJs!vxpktAOc$d&_iPl5g_)As)6PFG+4dD(fa-nx zjP(r&uEdGs%J^>18?Udgr(b%$Jzm5m3HN+j^#wWm!wDh3dS7}eEoppUjFE#qDR2nT>>aT4AlW=&5S zAxlo0W}tq0|5-Hn_WllWROy!(8yjEHNd?ASK(C*F03`-sC|c{&`k$pqqID3Q5XYYm zc~~n`v$C~S0~Olcgy_4KzND>Xo^H{cx=BPOI!$Pk=sn$qb_|40u{hC6g4hEERRlk= z=qus_xJ8~{!3VH@Ay6U2kwbVyj3R!24`2|&w5CHOUL^q80BmmBmag`Qb?@^eRL?K@ zR@%VPjleQ(WU_(UmvMfBUJD0&HdjxfJSVrr=D(5-p}J2a7;O6a@$+^|6QvjA#Y%W1 z{Ws{@C{@b#_Pl8OMu<}MA(C%De#pJl%TL!xBO_GM3%>&FC)k zJWButKpt9ASI#U^tA|X|Luuj z%ROY;PbU(IifCkKmxHoBas}U`Mf5NP-U7SV`YZjiPXu2B?*>IDiH(bcR`?fwcfO(n zj9ZmZdz+u1f&%xKwFQ$G+afdw<_p2V{@1q)02oZ2HR#Dmy3?mmw~>t&BeIAdf}1af zz<|=BTQiE9XwmbQ4OleA{`&{ZfIlDLxWlPDE$|F8g%>PQGL|V98L>FGK8;-tMj7>fl#8GGwSOSG{KL23xlCY5Dn7l?%|`K z(@bQt;}Zx|!T&dh8D-s}n|ca{G>6V672o8eb=t@8#c`x6Id-22KOIT%_CoG^PT#+@ z)2`|1Jl05&FV?=rG~71g+%!|>cRk8b$Wy|L=h3i+@Vlk`Y(W;n%WP_|cAHrKNoxN@ zON^V9_Q%OQ8hRA8zf9HAkS2;I>SKX~AY15bjzfO;`f5JaKB5>6`KJ5fK)mj}=P;g#mUi}Tl-7)mAe z97Rm5R)-E>qExgBv2K2tkTkv=RpO^#8sg1(950ggAi%fLhf9+ggOR*Pht>D|vE&** zs9#xI`FOwg$uTO^w?8xz-_z%l@EX%}l`ZbBD@<(2t+OvXP!&t zt#{#;(iby4u?CN{SO`S zV5mvwHEFKXolLGW)LH-RVf*x8-Ez*X^#Ss(WU9{t=}%m$&Ti^6IZ5a@ectyS211#v z=jv6bosakLB^|%Z*Z()IBjft^!4l0 zMzg_2ZPr?MxMvIAfB5-*WhQg5z`=dk;xzw$68C8P(WQgE-!;n9djeSX)gB22i&+g% ziTlx(H63TjPm>AR%NqQFAu-2rH0R2m^zra3YG#)x_s8wRY>?S!QjzgsUG|2HsovDn zy|po4^4|HJ4Xb*hVq|5f?7u4|?qmFsUwX$UTm zq$#CWJ8d{QIng4w|I5X7z_;?>1=_JBz%$6uWMpJKqf4NRXv|$*T{j?eC$U!7)uE$d zltFr4jndG_2*TO>rY4o?Lb+0@;FkK_>G9k*1@CJbg6hAl=}z9?#oS9xH}a>uchRfj zK)#+9lOS7saU!P~jwCW?QdP}Il`>iKi?&tq5yyb&4Vp_VuQ`vK&WM*Uzs;wHJUf+MGZA4(dPsxQRN1rq%<#cLvb;cVEE`8|x`t)46&gURH>hu9l zlC4Y@5}~|V3et|J?{ggaL@Ih8HPqR@wjEPB(=<@^nqlBP4V^!Y@qNUb%5<^ZXzghF zs-Cof-T}S%Xp!m68wMs#p-u+E1#b4a2u`Dps>&Mrmox1ffyYB-&NL1v8!DYHlduj+ zo=oPMx1M^LS7zrgM$2MBNuWyD5Wju@K9}=X(YF~)Q)SRAv{lBK;#KV-Xbc#-@*dr9 zS;4|{4WQ>J^c5)7IAo~m7f})k%``X(V#G!8wjXU78XafQ8j``8OIHRwp{`_ZPzA-v zWwp*#9NY1GvHAONEw%)kYaW>i^-orQagR#B>|}r5V*Wa}Fsb{vi+r#uByO){ z9p>s?*xNXy8*VMJO--uIhW8FnjaHXy)wN4hUu{jlqAa886S3`ZiQ%|;gw3@!o7Mxu zTkJKt9L6Cjp*!=hXfugRt4b=JzVVZy)b)?b-kU;S*M`a5W9DB>OuD3Zmb1r%4}NRP zm&-q>R+{vpMr}lQNklVQ$D-M~!EmNF;$eb?r441ci|H(j%9N05{@9Upot(vmbI;vV zq-10sf!wamR;Yq;Fcd38rO4a#{{71UEp)4k>XR9t!H0j&Sa-cI_g-VYTJ*Zdu0hcS z^FknskQQ^V%~PJ+L9$MsIN=8}w+%%3f`Yp&eFzAdQ`@w zD_1DCtNypOc)&cz6;dl}y6m7oSF)ydxQ2C@3y@RC%bDKW#_vQ|$TKKy_NwY@k8|tt zX1q>PmErDmZ4`-sv))$ammlu1Qgy`Z2mijA?j1XH1e~BgPw$|4?9wd%8n?sf2v^h8 zf#;vEg#Oy|JIkj+##bimf*NJHx78WF_+6s1$AhD|l**R1=Jv4uQ78~OS$!hc=KF=W zB3vD3sGfHF>`AbT;3Ii;{ks5j1jo<3{F1%qY_ +=Tl}pB?YpY?gj6 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 diff --git a/docs/b-tree/image/output255.png b/docs/b-tree/image/output255.png deleted file mode 100644 index 4ca6817dabde4317c58e1e5db34d02365489893f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60571 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%0D$hr5^8!Y*rZo}|rS zf#>JGc64^aj4<|Ma{;`;`(oU8==N8oXrHCOZFD;i2P-__w$OWmsecq)7p zH(>`oHMGLO&ASz09Fiv-fa8`oHZo$qpgytiI2YH+ zw(GRjqfa2Rs-s=~TgY&rZOT5(XI8>L!3bzS&XnOBkNaa|4pgv}%p1Tw9zZK*5?cA3tN{Bt`1lWj6 z6Vs$}#R3^VGvsjC&&Eh|vxab2umyV`!0ba^oZoU4#3>2CW#TftLwf-P?;9SzgDZmX zix!{-`=7|lxTjJS+aDDAE}6O4+4%B68cxOfVN;6c0#*w1G@xi>Wh+ae&=30h`#-{T zCNm^xHe!(OFyqwt&rADWEuRJOc^n-v&a1@0P{`&pq?7(iosu5 z8Tg@P(0g@Cm*+1LSsq+8r|U3yB%p3D zz6kCGlqRoUFL8`4kzZO~oKyq+$^ABh7$_a9*e%E|B3L}ztd3j+l|I66JO4@r-XhRz zV?^^RqW%Ll6K(`NNx~k4Y=ba~Oift!93V|ijxXgEIsD;+ve$=)TfuI`v5&?b)7}aSvOC3YUv4U_9 zLPsD4>Pxx*sx>qi^17VVa53tby8r;*_t&GPKcI$0Pd_NF1J5Y(ni0U?r+}|x_*hs@ z@be@gzXYp5BZj;(Ks#WVYW#zEIhZeDUOw;dCu(thLS`7^r2Yt=p)dwxx(P)GBRubk zV$hWeHy6WE{_j_0UrR zH2f|laZ8Dz5TJZO+_Vtl_3?J{tj*w5h?ex3*T!(8N-*moMM&Z&2PqWFFKsXkWr+VL zV0J1&1rbe+d1Qv27NCOM)5AXy@Z_kgA{Bv$iD*e=bTAR&iT427PzY|}4XxUjVOEk% z!CnL_5@E|ELhOX!D65@ea25z!sn7^5S{@8g9@ybVNJt1Cah1{uo>eVvxNB8f@{1`736i`Hj7B5)(Aj%HjV!iz#%)C0#|1&``l^ubE6Cv|Xf4 zm}F@hkn`#N`I8eRlP`dw5223L3}h^{1gF=S>Oyrmub|{ju;^P5bvB^zqM!>L(0+!w zBszI~zH)Sk0EX&VWtpuQ-Gpm;8%otiu*Umv4Da*l3JBu?2lpR6dfsWJtQ4(#G5=Ci2>?q+KC{Pd%=G@ zmkt^gYva)-O7f>p4MqB_EX}NDfL6{dOM_2%09(O@eBDQE4l(kn_mHoNu5l9C52C-` zz+2<^Fd@WOHzxY!%@t=;E31dSudsbv5XfTy;U)Y1zN^a!{yZ(LQAgNo903e)XBlxA z8CzRh_d;1tL{1d?mfX+!IAi3VZUN?7d4%R@CY{=(0cxWG@wK!CX;@#vS?vYOnS17){$k{6J z$Nbz}5cE`9@cS+w6AKG2NEqelc_M~!Xb42GGsROa$d@LR8Tt<=syZLE{h0n;XEJp7 za74MV&LabwDVjluE1fS4xqkgRbf?lA7c1{C#R~T_4<(UqY{C}Ups5tN9 zm-wq>KM*5hBv)K1Ycf?ez2!C{NI^Zm3o5Xz6rr>YXTFB4`0QL^CLW@Yh|*pL08mZ& zRk{t-feEd?q3-g-6A@sxCK3PLxdt1;NpJN8hLH)aDcH=9*72bL`{^PU;Vmpn0m|r zbMISP{-)4dpfVq%dI^WOD@S^HR*otWf#p8@`Q8Hu6a#MFyn~)c0}-nMB*k`S26~98 zwKebZ{IFnG4#IUbGIYC+sM92@Jq{s)S>=(~7K02O_fV)Ew?NizBRjZ-g@qR+N03Sb z--E6ykU&(DSXn4Lm9zzumy8D@6#35;C`0uf%=E$G{s{PSgJES|xJ|x+a?D{BcS-1b z2a#V3c=>W%i75c(Uyka+*F0-nc|$7f=S3~rC(DG8LXKA7;;z*99yaU%v& zSAnQyEdy$D9|p!5k*?S)AfO6p9E77l3oF@{edEXS@>^ilgKX_M6Y@|IhFgyvIfAv> zc~}`<#BH1@N4zRP3gS78p@ zD=e%5ICKk=Mi4Hi1=b zOK!|~>;;Js@rJf%K&mNodE4`|O3;AL;euGTTbY=|3n3ns z9lKI_7@WYRL=v_-aF59486W{#oIj&1Ej_&`j1@EVcu$7h3JR(k^F=`A3^{4gyKZ5L zNnzDM60)l(1$4P;?EA-#4t>(l+xSQ(Y#h?p!}C4N)ZvtpY6>F0C$ZR|M81J+l>>#4 zLm4wOGs#Cnx7TXBKJx1qH-70O;Z4|dpzAt^P(1zSXwx#%uiU^8CmkHJ?K&n`S>T?+ zie`XLT{VUA6L}+hJx>{Z;9aD?BTZjJ0wGrt&iUB;;j^R*yzv<4&!ybmAuJ2?+=8Wi zhSGEziJm)94mrxpR`oL*d*8S2M2(`ALE`r;O~P@8oV>iP#y)?~KE2F-++)wgK)oP{ zT;jQ3Xe5XU$5E`7ppl?q3}DUx?WLh!2xiQ$UAxn;+WXEAXWm<#}=vu=4#>`y2Z40v8etlh-v3@Fpl zktuB_-him7s;Ux02qK{G%91;xg3+d(xXOUUuoatH%<{6cE44*4;E%(#wus`Jmdd-- zc9)<%2(y|{)SgKBR0GaLOL`qf<}3+S9Cu9Rc|`^0Tw;`manD5#);zz9 z=QZs|c@mfYgIYo0ItKd@n7(J)84$1*+8Q_jCl}WZK;B85I;*3FFFyapB`5wPAiAh^ zBd1Yao%r9y5(`^fWk}Bwcuo?o6A?$7E+M=~LN1U+f1-MV%&)VuvLZMi|3)Hv`WVE) zYM^@U`*11u`FaCLm&Cn>jsx7FUoZ)B1gEqSUru>A=lPNq1`zJw*9f$LMTV?9bZ>)< z=^K9!swgYxD2E~EDU4tsnm|=vCNLv;+7-m6CPeeQCVp4-GQZJpMRLdnfNR#~mB1{3cV}-X)7{#7xT#1t!(f~Gugz;v znaLA!0BNidVGH~N@*_(F>^^m>Vr3UvIthdm5f&K$%ygJTJSFNmnY%`;W_k7pJ))H) zbV<_HpakrTJ&i9Ib1~8=ONN#2a&dDr?$}WYp<;Y`+7bk_m`VhN0&sIHU?vfQ@ruUj z3`J9xjalQ98&rT?!YS9qWYAEJdG|ek@}&D%P3@!IC?MovIFJSLL^paw1mG||fs#VB zEqq0U&=CwCe!NS1>BE?x#OM^gCuM_b;|#QbZhob1!cY;&?<&aB>PrM=BL*&vpd6@? zD^naJb8k=JaR#4Hnrl6gPtnxC(<^YD-y#I5_uB0s@mx?0$wMrFHghk0+-Oi}x1`AK z-&A--<66qpg3%kxs_+-ne$v?S>xR6WZJHX7R!!M_P(4r1z@!pfS)gh=rcB%vAAy2e|c#BFA z0bvF(@dHjh(Kb*Qe?o&TM>-E|`T}NTno{>D#L+?bm$(376t>WJX`i=qdL$zbdW?~= z7Yjm`=H>xuX}rLE;XE3v;kXfr5{wptzWobu9XJ>(N&F`@Fc1&$Od|1kHUp+72am_- ziycEO7#9)2O*cH!O65OY9*zGfSsWzn@Q|mh;Rv7m;u|*7ZaWZwI0<>m8rYM4inr2y zy*z*|6e{b2t7oxg7}htzHA7+BU(;P+b@rM1RpdspFE;E&LHdYjYCXPvx7R6ioD+0@ z5;uU$i8&&|O^EA8GWRYnQ|ElB?)m!F$4SS58zohjZ-~ubWa!xRtaRuMi)&?Vy zX5R7OF%#QykGIfJrRVvdlW6P5kJJ&0C(oQgUV8&@!6ZI(E;J83Rl?ELwJxV(MJp*Q zOASoTd1~PN{BbDM)mxwdd!*zo$32GYzWNEpgZsaX4!NI2QpU7YZ>#>U2| zB2{tHeg*8l5JhieXo^e=Vw8r8jH5y?1zL`R(M#*~8c7eh1tetwtOI^=65k%{t2*kPXOg zn}MO?p?Q;GAMoU`|3)VzFf4|*sduWJeVvCS57KJO3etlu7sYVY1|n*{dvBbE&Xo`x z&RIeWdEZGMg5%) zvH{i>KvYdub~W1PdpxHL6c1`RsC@lcZ+B%SPv_gu5Znt#K_u}!NHkPBoT*eWYW-4f z$uHiA^+=(@wO9m!u|ekDn2L=MD#hC9OU zJ9`zLhX!swDXSQGnZrO*)bT4KfMmoe0t>c0>ISJK>d>X_nE8_=S}>WcV`X((n7#}V zBWc0mk#Fsb?$D{3iH`UMC{p{710WULWBdZ(5_zB^t~1fukSxGsmJnCl4LOK}6Kub| z+QP@jhcAp{Q0dSOtY6%%g-36a5{AD+d@mXKmX6P<+G*OwUX%_C%8Z^)r&ZyIKEUWE z09_KhFD}9Zf1Z#*Cy)nRaM5qN9Y(LGTD0*kNE+`5>Fra_W$AOOyGLlyR~nK zl8{-(q6{GA}6D4iQkfD;;G7m+vlQNeEBuZ4YNo0l1YYhCMFSX=#02U4Kx7w|A+)~pKOJ)JvsD!W(nBm8Z(V@lTG z=kL9T03do>h2Lpq^lL1g#eUOIbrSyS!c2xovH>N!b4pKr1Bx7SEfftf2ZRpV+!+`D zR^w3gh6LlOtz@j3@s87+)q;znD5J*Pg4V#1E+<2$i0BE-v)3(ib}73bDO@Q{MCAyXh8e*D^F4k?!3FHhQhGT)2qH_ z6C=}=KN!`ej|Z^n9^kE&~qvk;Rf!hpikH^tC&_9Km*Bk1XF2R0yBqh9GL>) zSeg@YobMQFxVrnO)k<;GPgbnxJanN79$)>TM1}esWZ+K&SlW6j*=cEM0>~P`aCsE_ zxf>Z7F}P|01+nG>WAw_{1vC0RIPD^0h*Dk@BF`adzfSYuR(*bB=JD;lOl!Nky1p+; z3d08{H+EVduJM5np9r>eUZm>?zO=dIHizzQxW>!5jD8bK9%=pM{+J(!M%+GT{vx7= zGjdeX#vtIJs@Ui3UkbfJ1{A|$q&|D#aGekIz|wRanZWhwnMj>QNbg>e*u-iuzo{w# zn6bfs$gt(!zqyklIR05v6%kwdgS^Rgd>7(7WtsRLemp=s47!*Zt|>7;JW+B;b2ii? zjW*j1y2>GCHT{Ie|#MG?g3lMnwWJg?D zO?K}I%?-)o+{HHi)~zA`Nly2WWBHMy1A%K7)hQ*@gGG9HDDR+U<&;B(xi%5HQTsT=wpdm`;_ozMfx?!5)bw*3l`mCR zcrUODL)`rcZVXpQ6vc(WXdn{tO=UdZ2`CroGg|NQG!2f*xd9J}-66!Iv(jf6eG$dW z1%YKp__pajHpZ?@h*TS9YQ)pPtr|XOVq+JM~A%+%)4HFu>$XK6Latm-L_y(-r!V_caj%FN7!YmDGs3!PpQ zo@s}$dDVY2dF#f;P0u499CGv3^y~n5NayU_1BOUIzt%mEdyJbH{Y~vjd*UA~f}=@) z_)yQ}$Bq%S7$*{x;HE;eY&Q-dP>Lvp%f6xN>(^XZFY$t)F9TjN0>C7$F;;>;gT!b^ z9HYzMK~d4qa%p>GRmKrGLHJP|gB^=s?SJdmt-bIBm`-i@aX6Un9^z8|3d%$0zAwnJ z6Y1d+R|LmVTm&GFw5&D74U49V0g@}==~P?~Tdg(x2(grby_9cF^<*UtdZm46%3~>D zsb$0cl$*)@fil_2U)gKq_1m(_6*vZgT+9U!X)d2o<-$TEQg7B1qhXdqlfuEjD15>O_5h4J>brHxx z7gndf1`!=5{3C_#4qkmxe#I?6p$SSL9L2ZO86vTcD;ga3yX>l``zdx{YPkD9qybM+6q_ab2Cn^kGcpZg8P4Szk*{>JeQrBsD(QWI% zS?a@v9nYB(sQZ1r(LnQvYZ>=Dy=^&Xvh9ok?n_q&9XgO2Z8G9hN?XhQQwKIQ&5K&` zrP|XiJUOELD<|Z6#r}Kcc^Ok(59)mzF#7h^x+lwZ?E0F(Rjb~Z@S=--@)U*>mOe|b zyE%jAc;FVRRgV@ABk`a(a?(!zok$so)U$5UhCU5p%+~ZsU6l%lD<_EmL9f7I>zWEg zTVjbouVewoON`<{e8RXsV4Qcj+w*Pa(XYr@(8;O{iotBBbJKqSgMUD$V+wq|`G$0| zgK#v==v4ih?MH7A%tM$OjQoU-Kw%<4Z7|{=Uf~ujo4Mg4%Z1qQNPfrkv98O@u4=tt*i8LA3X}ej$LO`QCdecb8|YZzl}aXM063eYqW6uyrAMl1Rxxl+tiGI zJ{3efUpgA@g(9>mzIPy}CS#FTGrZP{40VL8_p3V33SmPl{*+S|n79AkUA0cvADy(0 z%1Fr$Z_#(mnBq5PCADEAZlpHCxv|l|Yd@%?2eZ3&xlOw*NhYY(V*LCpTqM>cxOlQfHrh^7;+x2VR)nQAH*hG8PzldqEx>AL@ zuv*RBrYVWca7LHk&$m1?y<6kuHF>YiTJ?FQN7LTVazFGg?s?yt&m1nr@$CJ!j>)te zT$7SrZQChqld;LJqRlTZG&mh`%|fH&EbYewLrR9vRXO4BlDATApW4ArM~C0fDSzwr zP&f!wJ7S{m)x9@USCbKw6j==Z9LwBVR~dvWEF3c}w*wj=D5IMcvhv^?is1mBi#_Pj zGj-Glsp8p9bsj#dQZ1cdTF`-u1~DeGKx#&KKb?ZtgHR{{2naSc5%EXOTyh2H3DyQq7?AVdBBy4R|4tW z^I@wIxvqMhMPCb8T10wfV;Og3b6*e~WQWdn6zE<1rYpl|vW&8fA%TjI}(zi~~9N?gm@~ct7 z#Y_kD@-3fNSOo?ex~{wTqu3^M@6qTFQ)6vURNJ;&*WWvG@4@5#sY918Ti~`UHhOzy z_RZ&=LW)X9d+AONx}Er9-QI&oBWs^NK5)RL+w3l#yEt8Ti`myZ;_tywH|7W|4$Kc_ zSV@Xv@ENL`4&1%MM0hcA8wd;<+N${;6hBbRYQ8teq->($gR7)o+UKY!P5$;DlYL=! zkZU?TtAv+Df6x2eP<|1f&IySy*k}u2o*v!DtS5aCf*IBS3X)n~m|;;6C4|rAwj?`29Dhunk{_!`aQO0PE6(!!`;?B!(;N6{XaM*~C0-K$k&{2;d zBc5g1W6P*Ls53uf#Z$J=e#VS>$m8gv(hP(wUcu0E0};iWM;l`-z^8^sPR*X) zkykj6!DZ$qN(P)wrZA}c$5*v_hqDNE{=}veQyDs{8gL1Z(Wujx-n)w;gO&x@TCo9r zT&jmDNPyuNCMwH=i zvygh=qQO)|)nDuD>dLCB{39bH-Arr2a*Py7gk802RRjK=@sLPNo~*x^GRRQ5^X}Zd zkxoj_lMk;ryuDdF9hE*)`lgNEy7~M18JAkFEb*@Pn;#x-J~+|+T&{(h>XGWlhxHp5 zUM;OwOCEF5&ZOWX2FJR#U+r7A%sTU;znyyTiRD+me*LS_$Lb2Fzg2oo(r);xy8Pq! zA@B2#ZJhgWaBdLTNL8@WsVVhK#y#rLzJb=KDStZ|*!dUTzJF8octXq2izypEwSHn% z^tvc|l8@qqlGR^U1yAq)an6Q=$6J}i7M@<|8(vV_i91`hYj0KQyI8mo7X^6)@z$Q1T_hD7<*1aYU=7BKE zan9f^)e}C(%5a{K2VP~b49%s5Z!-3Z3X``hQc{r#!?d4US`RTGv+5+wthHS*wZXf_ z8`&*tQsMJckV2DIVEF@=&Qr=-o=g?}sZ4ifrGGoiu*@eMGzj@HhYZ7jGR0wo)Gf@N$o6Hp>zlNK`Dk*dWGw;9dyWz|z( z_M->fHEP1kzs}~gy`$p}v1WPr=dxDE!ozj_&bU}zvY}%YRsa3Eb)%+HN{T*iw zTD~A%i=Q!g_^>Ezvst55mKf`ttlt+}Z6ZosvDH5_uOTt5GOjq-DNwvXGL^!$9ibx+4<{Mk%BW7vNOU~|?wM1& z!gv%j>m$z890w$Ff2clygy{Z}N8F%$gEm@-2zV12V4`^<(@mWBt%QoQZ|=D5ND~2> zT}Fga{gOhS%kcB`Jkk;<<7E_vI!W#pok!FUXg42N#;;qxe0{X~xBLy`ly1-fL)J1{ z>MVL*T#mtP7UFVEBs3>H_hV28yP6|3ab9 zeXbrqr2NZlj&sAl)R|?jbeke1Qt4(gpRu-6*TflyCO~93d{^Az?N$d9Qw}yok zG>@<6B?%QQcGak<#qR}m{`U((Didf*a#G3?8n#l?RiO9hqnbEXA?L-G@_MhSgMUx8 zu-Gy=EVyd-u6g;o&Ie8=C+h|et@~%^;lpjL4eQl)Jd=(c%k5v&ues9Ze;S84O}M(Q zzlq)9L-R_^qmOq8*57~R&e@H_JC3zf@$oY$&lzpxQ(e4wOmOZb4Z~6YMEN-B#k!97 zyA>ES)$l-Ui|S8{tIYBoF1S8TYTDxJU&n2ZC1h>P-s*RG`N!K{2A|U>DcyK*x3pQS zT|KLe#suwe^fc6I0K2?33(I*$cW-zYHUHAPhqeDIH&HHm{d4=(Q-|N0 ztbCOo5pDp&0XUyQxq;*gB)3Y&CP_zP!Xn}>AStw5Chb1TQk71F8*FCICV(ABOy>QG zsSF&urLew6+PKKR=PyJm{sB)hgiE{2yuwEoJbilq!V)_%?mKtxOP2^2zzxIxxAO9W zfDfHzIyln~gGEd22d3njU8^cfh$`(u7OawKzLcev$}2jPpK*Y>fW=uy6f zY(Rj^2pcho^IuE`kvF*Y!^6cFB#$A+S&6J(X8+c`@btrUfwGO@>&Fq{-|Z;WJv13z zw)row|MNU)Lq~d6Vp=5`0orZAIt!Jr&yJuie`Z7-1<+iIwnuStcA4>RB|#(0Ng?KByJ)dTkf1I=Y$p;P8Dhr}js++V(y& zxag`~w}W3#4L9lBrd#Liy}MmLg}>V}eDY40yw45Vt-TO^=471PEDiOj$s@g5%)EDF zSf5XeX1u-NUo&LG>Y)K`3v^ySxIAEY;-l*~pKr6SH=S-(bmM6K(wE0WJckS!ntCVK z=ipM^maZoY?=`N9HJm+WZP>gNYvrrSKYOgxxY;G?Qk4wKY}>Z&2ow`f)ow&hKL$#u z@8J5dov`wKg4Ji>p+jO|)IeO+D8!tFpDDQ1iar+1!6cf-_^EtdazVNpa>|$jdCeRk z(y$XVFK7#Y{K4UZ3;(^1X9;ID0Y+-*DGPJ+TrK}hbEfb(gixwRd8(5jNEz=*17?f$ zBX8gs3Qfu5zhD699PMRdNK{AM&b`i6g>*zS!x18Kk zS@|fxFn&$f|8yeYns3?W;LT!KPCG%JW5W!BXRo0xU43pMAqu_Wd zFvKrwPneBkI3&ojfUjYwfn%L=7V-lIdFzn?`Ljn9fryd3{3t_e!f`~QaMzFG5qxmJPe?5>#cddA(V zzH)c!RDDmiqNL$Vk4$P6J!xgCf^$pMV&?e)$)3f>BYxlA7FL+^Wr@M{EN#Wjnn_C& z{A@hp#gbEhWz^@0j=w%AfAyc27O}x}*R)Ns2M=^{oTg{AX4Luxp-*-l3(E;QcvNH5 zfPJwq2J{^8@`by;cKaC}v-~#H8sqxuuh%3SYM4(oW9n5aJI8Kl#1=* z83)VG%m{z3+-TmTn;+iK*)$++$>ck`T|cjxY!fu>`y8*YPC7?69-twkP1~n#UU+IB zCaB8GGqH*g2Q8hKj}~8GKpQJSY!uS=li=yCJ=9v%k0!qeIS7VgH$-G!ff2waMogZ( zJFHN$<;y>f6wA`6cObqWy>vP|rxw2l0_Ch~Evz%;3`{*5R?RasT(l|&GM%x@Y`_EG%t~~c= z$Sh`6UwAhv#jQGyuGpfY{%r{5@|vPWNHeT%bzH;=72*@YVhfCQGX`&bNc=^JvJ(DJ zWtBPFVnh*{!(YGK2@dN7P0+Me_gzezBe6IRU;JmsON54o0+lvOzioi11VocG`qPP_ zYm$-%5jn4ey>;IkCDr6Ve%yiia@umzy>+;>S_~F$-qb8ug+W48bTpH`=iU#|)73RT z`DkI^{J_K2KTeewEPV2%=KVMO!jy8xfyCE=Sfa&%1vpd?z2wA+$J|{vFeQk8(hA@3 zMW{I_gofU!Ie+28glHRQ)5<1Uzg)SD2nlL)9g~(BD*;r~y2jBqYaxlj zM-(0#_Z_n@XHVb3!)ek)uPyDbtgO5MFQNF=5f-^&^o6R6(C6lXsF<8?xOx4!@$LZg zDIc!+)EDlu%DuZPY=P5a)5SY{-}tm^;~2Dl<>+k|er^k&O)|I9_VD<(Uhmfj$KXyu zKL6}(*mRq-kJ5dy-d7yvv46Fg|a%u>@!GoX9*rwg~JA2oVDYX1Ce6aDw2=>rf^nZ50?G@eby|r<^&A8#W5!-2l(|Zf;Y=F#sck&6Rcdf;n-T?UVaN z*N2X9TC|8V&_v9xc*i0pp%t5arsbP#l%PR`PTAJT!5-RTtKRV8kMDLtU~6<_qv~A5 z9~`#$=O@3PB0Ygrq(vu%A}mfSj)*+Lv?h^M9JLvyUvmk@4B!j7M@}F%UBm>O+ z=;IsW8DkVelpo00LqiS}9v9}czEO8QXp+Nhn$*Iu4DWo$7+In7^gdsD?h!$JVOYqw zzY5|WEL#2Kw>>pQDs$4$a`v6g5aR}ZrBIhFH4KK0letCIz6VOucDv-~=Yz6C`h_h+ z^noxrv3ovKQ245k-1z;B&Qxp4XByivltlGc{=QQ{PwqAs5NP*s&Xy4#U1wZL$SwHx z%j9BkJ1q?>kL&A8_q0*JlBjLvmG|gW?BBI#`wa9@3wihAS#Xa3+HJdReQz`}Sbszz zc*+#Dc-ONF%zHm|On3OOzFzd~;wnxg(D!VDgJ|hjvsqa~V3%YHm&^SwJTPg|y`6E# zhV?Ux{XWMtaK5|kq5;i@m~{$MTd;WkE_b(SpJ&WUSXQ!KWz60o^UoeCT-AP7pC!92 z>u0sN?!PZD~C-GW+{G+tY)8uk*gLsyNbZbY%O#!;@NF z_{Z>GiE`586<@!86)RuNLNL`9^?*Vy;n z{n!~`id^H+e0%U}C`)6Zf=ghlX?0XzSYjNrfBp$9pLmfC61$JrxM@+kc}x|xYNGpL z{0u;zzTlaKonrd=%%hXNtIG(Tf;!2rr{|1@QWU;iw>p`!%byl=*>4)Bvf_pMEAdne zWnSX^jf47kJIb0c>N{bTILYwPpHR1m7dB?L!xlfB2dg)LWkzWg#QQz|{#L%uWQ~oa z5|Qshz(NVuWTkbC*dGvZB)jWqrXCow&|S)qBg)Sqq;q6rTR{bF-iN(i%Z!Q@A{r z$21K~LLuFW39^U?Xpg_9uK<^iqsW+tA*t?TnlNYL6H1Rc_kYDe$HAB1?PRoRqpyAp z8m^;=N!n@KmWB8op@TFO=U<(<$-5Z;BGfoiIS$&m8`}>QMXW8@RZ*|G+l*0k`8~i( z@=e1mPkUxv#WIC!#^A*(zT#V&6V>nYzwFMbpF?Qt#+XST#tv#ee%-xe>71)EDrp;& z_e5>o8hEz)Ubm8ZzgGRn{T0+ZYqoKNS+k;V-rn2G-1=+3yhSfFjUtx(YgfO{{r4|( z>%-xP%F3r{Evl}z%{m)ZTdWwJj%l==p%Z6}5vY<&FE$-xoLX&Dxtw zKYcLjU}j|IL!U!i{n{G8LT9d0P1ET7OYaoSnq@xKpA{5%s`$?7Y|TEs^S)OcEGw@- zbz>Z|u>I33A63sK&oPVr_m=78$ICyxY*AhPmtNV-y7sevl%IHbM&D z>-C=TYW~Zbtk_h)=HE*z^PD~69v^Kq!m7~mM#h@UPX64J%cTm|>uc6Oai#@`dS&{~50_ z0Iq-)zXV)Bp=j`&%eITNkr;&mebDm$j&3;b=g;a^u0(Z|ygPy6Q`z#x2^FI;SOxJ^ zefQ{Gid~+cYE0D^jt)}L`HqgqP7b9Iv=UN<$^x*}3y%X5(Q=eyKyX%M+FZOmBw@>)ws9$WacXLWjO*)y{;USE6PigCbl! zO3KMez>^gn6536{amn?+H_*{Kp1uAce*ukNeeRX8oF3szzJj^h`3cw4)BkKD4 zp}d8G1?tkFXPy9o)Ti7pmMP1^JzoH-tY|>kvj(oRE4HDj&_t_~TnHVafD`76vG*@& zt&CXGJc+u43FH^et2|*Rq0G_{%i#RgiK8dp)`$ZU0p0{4Q2(UeH)TRsKBD%&DAIr76rI0|b` z0RkS)3i~j4uyw4y{sM&qVQI0`0!ELhei!Z3yRNp%>r$7|9VYI!Nl0}_jJk8l($e&FxePt5*UehxW<2Bi~fuxILb(Ur( zXIA{XALjaGj`mwvTddhnBXrJA|K;~<+x=|%Qz=f}s-eZG`uHYON|ehTj+;GLzOkao z#hjW)&b^0S7##C@+rr?usg1_e<;3?ge6wO?|K5L>Jh(eH`jq*>eKS93=bc)&RAqN? zD>LK%>sR*K=Il74?dS17UPm2|pM>(m^-)Uq+Y2YgZ@d<2GX3Mn#p-kl9z5C_Hf+g0 zw?(f=ZQqLGMciaY|9fcgS#h03)c-JKASOVsIU=$J6tOyfm=^pS7&$D6`LVZryB)^m zSx`0(qk=~vh=6PtP6-ucL#^zEsB6$4%63-{CHk>$+&VU(Ot@&&99~C87l6za2@eUq zoiVhcixpR(1DDU8kufQru(4G1l=|E{57(+Wkm?BY#BT@Du>ymbax&2L&>Nvc(*rb$ z6a!H6o+Z!xzQ_lQWHe*xv-29H@%->DNJdD7$553d`V7Ehh>t5WRU(gK-!Beu_<;FY z+$bS-m|IkKaVb^l@v$KqTlv!V5XehBXUxU*os!%3)Qr~Fi-+n^re(irPf&_xTrF`P zOq7_f!mIk?c|~*Pc4lUIbWIvn7Ur=z)-5%)wRfO!SOwiH`{vocNO!v3ActRZDvzw< zuRJAgsEl()HU{VH0?1(W7B}F60c~H)7CzePLR&x)A?Lf-|8AEl64bE%+V`DkCy|W}B#q*njUjWz?aDHp!g zbwnd6o-U}=Wm&pUv$irE`Gbfff+4hbg9>eIei1xcUzM0mU0drFLhJ)HDJ&iONDRy#v*<9Q{da%U;PM5jua&;~kF|>PtE(@# zn*FiwX`Ril>q9PIZ9RZF(WJgG(PwowkHSc!pe{|;S<*O!pd&UlQdlGNr@z=z;T7ONM^0IXQ zvz4J8Go51d{xR6F@8anASl4$mY#d)d)JaP7?apaaj=nz;?Q?{s&`!2qV>3Cy{F5Q z)Z1O-Yr59#-=EojrNNG0H7=*EwKMD<4r@H?&Pawe)GYF ziT%c{pBv#YcWm*o9Vj5kShAvncIseMrMNx?_YYDkPV3uF8Al`8IE35HlgZ{@cuSl3 zeJc`U`IReI?&;iE@T8t}!U%Ir!3IUo>DEMJ(5RJfl#uAY0`)LC6%0<5S+GxqKW=6? z>B?SYf^!*3h^QzUc%Jum@t(!#$I6F*kuFLcvC_?n7WU&oPG*pZ8#Oh2I@Q_X~ zyMO6Til;xiLHHVw0<^g*26MT6JAk1BM(1!^4a@fHWR9ziwlq;)d7e8AXp&X& ztMiJGM;9l>gtq>yLsigw%AswkjAI%|MBBTK?nl1sERs|($m<_)BiXQM#GdkMtXt7+J)R=oTD`D&W~!ApF@vA zT+fIM~=!RrMJZs3X^ecR3%QP1)-!uGFr13J208+j;%q-d_Ry-_uze$h38+!f} zQMby{UP#Uu2xDbW z(s^y5i3G3uO^6_gyRG1pHGeIgHs~78mo0Zs42pa+bOfCOb$-SB15IZ|+YDLyOivsa zN!Zf$fQjB%@e|F66F98tZvAs?H82Z73@Cb=2AI^Cd(fLtERNz*xIt1Uc(@J@8j#ORvvvmE!puAUE?TC@EE zRY^8vTJ?^ObiPa84T+==svmPp?;PQB5-5{`Y}o3)4aD4$^e4X5gha@`@x6muV@}6` z*<#ZE5G3I#Ppq63K0p4>kUJTgM1^Ds_wEt zgQF)a@>mwf5qL}Jn;18}3wK$u?OzUCRhSc$${h>Wu4aK;*QShYx5sGIx8>xFTkvPM z>7h=hGkF>i{r8k z_&}C}i6b$5D8GG)(;;eVO)~)PUY`3rH@EQ0wFrG-tkCdsjg-JcuGT#JlV4gOc+p6%6Ev)TdAo%?vO9hUOiI#Cm*FoDQ9Fx^Hnr&<&MO~LoG@kAntc26a+WoH zC;5tu6xRz*^(0u}+<{HefUHhWrt`-8HmzB|DGU-@oIepsa`KK7h&;wP!|<*D_Fj#G zmzi5{0wR<%HXqIhmlE3As;O3??!H6ceU?EVPMnkwT_wX(5(^5v*=%9f6 z>3B94$F%BC--dIH7H~1)I`04bSAU-Rc>LuOetG&>`O#mp*f$`Od0sS?TSyfoH^B=VA+8(}F8pn#%J>JU z)4n6w#sEO*e$u$ac*HDp5pLbMQ5;vb0@I^8-uPpUqC>s|MGk3=JA*J>$W^>zH&tX_ z;@qHdOx4luy!amJ{UfY)N+JL*r6cyTCX`@h`r>tRB$(YyYatzZLaV6-#+s9Dm zVUh^6tv~G;I9yKGP?9lK_FX(%#H0aCh?jUh>>HUKHnAh>dJ ztIagur(y6a7>c{kVWrCZ^6FM|gi<1GEyql!a$*MfPS|gb`%C^${DO}BM<0u%lyD}* z5HI}In>S2bJeXW}o{5LTvor!64Qt;IW#%U!yM%btPPqw!Z&?k*$j#?`mx%ILBrjBo zn~G)A7I6sX*x}mxe;6|pu_FVR4Mgxw*hU19MjJ?8JPb0%2f|=c&E#pWjGq>3i`mRB z9+fP3#O;`9!6@NSW|v8(AgN{?`h_4){4I}J_qEmzk?nGPxTFtefj1#FMaKoW$S7G! zh(T5J_p|fOOp_up7wLuR3A5TaIRPXe1|cN#6YrCX4rLQ9MD2mw2NZbhk{@V;4Uvld z$m!Bc4SUQSR4~}{FpuR+Fk$0@w`ENy(nSZcJexJIQgKqBPBT?sHY7R?zB{DeP{1w1 zGmL{YN##yAyqlDVPx7$}TNK&ucOIy^6S`64(wdl2NeUoQcz#?vEztJwpG$l6jJQ*0 z9Pz7WNb@4Apq?XX`&AACt@|6ziHJdakeVs!)lf@ObJYrE~ za{U0|6>l4#oO$8j%9y*j28#C~1T7BQU4fDu?;o%IjlT2dksP?t*5E)ws7afR^O&BV zu1H9vFA_?&h0vK?V|;`h&65hCiMs&$5h%;5*W58O6ev4Lr78xnAp7r4q(WUf7%2t~ zi2ac|G2m4vlne;JyM>tFA}Y#f#Mh-5@45pA527KE&3dAUg#$Z|ih+A`FTyAXuRduG zrLY0Y_xGT93N#uK+h7jn!IQDdhGM{x4ks~U(*E~OKJZVxeHl07s=Z={5g8SfsPrm1 z$0F0_qNJk{*GJ0B9}wYaagG&p1o${?yo(79tiRoh*5g-cErr1rQ~)wZ54(fklc7K? zbj7k61=g*?vuXTH>p64g5GbBLdnRM*ylU{O?EJMoIh_qTcR4lEiz|PTV#Muyyd-wx zr&mp=V~zu7XhVI%_({Aep!t}iUTDAiHxJu8`gc;|5ZxY#>u~5 z#wq!Bh?r0ysu+4_d`3mU4r&XT*`@Z-t=3W2->#{&jP=gZ03HOXQvzq}>=y{Rb?a8= z%!_Om(Hv{=`F`5-=d+#OOGEEa+y;%U3hdpnlr@MUrN`Bt^X62Rh%vJQm zjLV#V?c6<1vu3De?`|+NcUSS<0~?fcc9(hj^VZC9+Oz==ece}@z29mvvJKx?r?Ay~ z^Zxw+?D8rGrg(h)SHYCOl{>H^H+rX&i%Xw5@IlMwU{4e>aMtwC-@ff*Dvv48C?2&1 z(La~t6HPelr?0Qi;xVRCxG4M4M8{p4&5RD;&W4+ucda)cFyYdr{df`8-&^XBvr(fc zS|Ty-ZXEkS%iclw2Wv1tT6lSd306kIgqz;6j}|ATlVr6>)Mm#XT>F~D3DZv6wAjMb zGypStjfT18%j(BTD@%4bVLIjs>9DNO0rx3ei~?c-!->ws`F-t_x1MJ(FzGuVJu1hr z)^g>lRYBBAd<`yKpQQB;)K*&+OgZzlIrVqZ;A@Uu40Cd@lzv-J`&qLrxZw{5){^`+ z$9nw!<$myMJ>HyVk=CYSy*cajgGEs!3=7>*%TcU3;Ky=4dc`6=v*G?kQ%xj&WhPW7 zvt*?!QzAnnZg*`;PqAH!Fvj7P|p0DXK5+a*V0VP z^;qockqvIQrLPr>2tLsnn%ky8u5#bJ)JX2AMQZ4-(}@r?gcY#=Z_S zo&8;Y&FV4DihSE3%1b*2#ZU;e?q^~w=^`h{qo@7E3%44JTqe;gy^g>r|2n+|9 zCILysvRQt_F!aE^$eu*-YX(uGTTyRvXQiCWF_#1`JRUzU<=CY}g0+htdF`AOb$` z1L;p=(L~LjPcZ0sb9u+7Oet7M=P=DB!ZW6#bM0Kf;{Jv9bk)SMfu9X$u)OqMH(b(4 ziYFX8PBZP+1M^giv17-^d@H%zq0fd58_k_YAiB>!L>)q2W*Tmn$tQ|_-BqvCMfy02^oAY=B? z*4EB8@>;j9MlVT=GDYz^|8UKx!}_b5@*%*;huwCuKi4!cIJUSupWj*9_Y~B)MGxNa z?Qfo7nAR<6xcC`IW(@suIQcGP!V>*}vajjy>aHHyBLp&z%HKX=AQ_xwEzy!Of5O_N zCl?I+CoXS(C2V9PpVb_To$Ll}Mg|AiWzu#}SX~S96$2*UqPzZXAUC)+86al)lWW=X zl`TMh$v@t9!D2>e9ykb@xP~eiRk-ub6L$}f|9N^{=bz?ZStZc07?Pq?Xi;rjB@|+z zq4tRrtih6dvrC$W9W8#ewfN+a&8$}E&$e$jOYE~0nozIv?$a3}vX{RP-odm$nK=Ik zEHOnu%CC2ru)0BE>BozeR}tZ;{XUi3#cJ__1>UoDCPmvcEYtqGX_F?=S9e2VMfWof zvNw+gI|S8)&k|$S?<2OaKfH5ia|RZ&a#P#K|E^kAaoTm^!hOZcyW$OBRQJ9zV)*ch za2B0AABVF4Vj?#&Kgg!nB_t2z=p6kYGL zq@;zG>NM)m>}aT4N*r$jj`)2ul7U3lJaNQTAFG`w`V1`N*A_GWGoQgFP}!zmpC%zp za4b9HV`WS6D`hqN$!;J>LQ%RB745p@-mE2q*b;Ll-nP`dpc&cD2Fhpzuw4-hFzLN)ShsDSXoxR|-*@l_}?3D<{oi&r>mTiv=4h zF$O(7HZRPdN0fA~!Tt2l9)Y4xp(Fvsn2xxOEyl0XZnbvJJSM)qL^&}4s)0J7-{kl` z6j!ToJ%daPh^&*9nSd3VfA0qF*W6C9bNTt59VoIjkNMRt-@l*goD}lAR%(7;)^S%e z$`cWJ0)k#wR))uZ=pT~R>foq!zB(WDWqJAb`1oZ99bc0)VWsPmE?s4V0KvhOLIC!) zgs5zP&{ElWV!se`U~C#QBrt&t1#D(wvfOR4azyXF*2<%JZBm6%&1QFynVf&&R zM>y)~yeoWM706F%>FIue_iJnFuTHdD20SCy#nUk-C-Cz~rvxyF7>=@Ahx5}yF> zf}kZJ%|a~O-#tNH&%=<5Xa7@;;JlR~FdXRmQ?oUUy0}g1OajNd$J0(eA_VT_x4uhU zffp!Mb@Y>i!QHnS|KsPU$fuCLabgL=qK&L)Mda;|frZ1m);-kJG9_pL5x{@fN577@ zKi69bbd04u%znWn8~{fWl#cNl$G+MblybGyiu-8b;^_ z+*!h)6S<606x<~ko$LB%bX8ztgy9&IIZfwIwi?QK`J9UPR~HB|LiCYA*2J$7V>V2L zO~e{e?C8~=MNlxYghZTst`o3VXTxpXhLXq|xG13;{lhvcZSxaMMZ?_*j zi%{g^MG3py;-T|_zyhAhJL<|um710?;J{~)Iti*66r@Yt12NkvFj8@avhQ&KE7hDi z1a(M*OgxUC(dXHx^11$@{-{yr=>Kv#$12^-Pj_t7rso9~l(Mxvkjay1T1n;Yf3BD5 z=K!4kG~qyFX?fTX+_ezT$FdnFmt>}8W(~AC_8^ z5v0t=kEc^e@3Y0;FcxCVhJdC8Ru+g0vdZOcAW=*-M{bu`H-e5h&ht^IZjx4|!0?>v zf4~{f!1V%mVsZIxNKUqRTpqczus5MQ#PC25mDeHO^i4B)Pz(7zvCDg!J{yo9D zRAj+#YgaI6980tc#I!`bM`JmIfp~GUF8h2SC7I92#Dd!QX9~beB)S{P#e^3S`6vLve`G6e#x46 zoGz}?w8{J1?&KqL?w9~%&HdTY0H2gqDRgc$Q4a_Z)W)va7CA;{QIW&S<;w#&%g5}F zEF?6QS5}>@IgEAD8(dIXac4%MvQKIlLCdItgCN|Z5Ch73X_mt5BRFVFL*njQ{Jhoe z?d{Ddvo=b~{u$rrKki?Sw&eLyrmP zC`<bV9wG4UiH z5u6wVS{+(Fv-ksAkJ`sQ?NV#arcBw##9e=uJy>jhNK3RFI4Awg2Dhx@7r$v9af-N} zhrJO_MUqt5?-mUKX|J16Kdpx24iKiO_VQKEQd;KX>MFV#d?RFeAUM_bNnJK{;Uxzy zi!gB*h>30ss7tXDYT%yWHnYi<*;9DpG9bsrX&~U4r9h$!<3twe-_A@;ZFFJgWS(2~ zjx;<9?qe{DM+(QG5%X3L!on)oAbAv)9=am>$7%i1qh%dYlB+t0Y#d|CXIRQb=`QX; zpmKb#*=;opLIqbIA$}g=grGpO^%9K$g~jYVvUhLmKuvM?qzcO`47cnpL&3KH z+BUPZvm3R#Y%E;2WMGx@5YKUrf@XX{$iPf{-DP zo*v>*Y8R7Z5AFkASyZ$7wFOMd;kRGhhlQU*layE$fKr$G>A{7{S@!l*MK+Hg1-1F= z`Vs$aIOK=^mD{zJicvOLLKP={J;wsZ7@CYoZ&aALhq9Fgd3>QLulnB}Uj}QpQ-*U# z@jc1+wk>tqA?7b$a+>%kvfBw1%14y7+9c`Rjecl$V{u|Hs*mS)VVckx=nKpg-yE{2 z43AG<5myaA`i0qLS*^illsinAlUe^Q8xq_^tTliS>=`T#RO-Sa{;R|H2eAQ&u>?xjZcqs(O|2%Y_bYSNJP$uZ_9x>Fm*lu^VZmY)WCib zn-yiS4#X%MLSb9-2F~b-%Amkt!?#@;CcbCDKZwj^@|4gwV)YF7+w>qrY)`Lm5QVe&trXTSuXHr9r|s zVI;59r~%_teOmGD+QV?<(DB6`NR+#;U%&1(bG^^(H2z-#ve?T>e}p=S5H#Yc-fZJiWTJSGC;4~-z z`{a#RI_=kZV@@$Jp8&+{^(xw5xJ%rFH`JXIYlDX2DtrvsViJ)=He&G$7E&X7ygt`N zHM8RRI&xAaA2umfa5Pxa>g$Y#bd|Ftxw z&lk&r61=b?@r0s7`kX)YR(HzaZwl*3D-kZy*X#EWKPrRHJn#%XpoC~FB-r6i5egwL zo#?85t9+iDXa+}Y6LTq+SF^KsGBH3p+oU`C^4*XdWu&>cU-znGB8a@Y0+(;x>GD|9BXWUrH_o1 z0t0wuS#krhDeYx*-*BaA-`6u%d!7lsOjcpR|FCmncN7gr6Th!!Y&Q!A}}~w@#6`qjcjIN zy)>pp(n;g)qCv--DHU2%vXX=%s@;r|1qy)ymqO@=g5Psb+6`h&!ese?w10>+9n-zK ztGCHA=*v~ZwN)2u8>&O-DM#2az=3MQZkyOB4j43Xs?rz!SzFcN2Y;o3ju`s1!Y)6A-ZdR%Z-V=`%bCbmao#Q70ZjJ#x z&%{WRwmyGr1ZB!R9?ikmJW$adVN%hCHsgzA&mlAkS8q#IRBh(m{mc9Op$Nfl)5o>$ z+fMv`pcuvKDeOj;NB4FCmHgu;y@+S5--zmgaE7U)Kv_5n`PtKKkV{(7C`4;Eo5_OP}V zjhv?$GaYhB~kXuOGmgf(Y&c}pK>R(a2N86ZjZ0vysmzQ@ibOjkx zD>uR0ht;py%=c4M7W2f=@I1R;+$>am)WFh)fto9@6p~t<7FS=JC?%f1oFBP1D-{@3 z;1HT{8}?>8VW$?rOhAj>6CIHpwOY=a2Y8rc8>BM?zz$)|$tAyPE{$*ysHp5jbt8!g zKnva8L*_T>vJ+>DAtlf@g%O-{LBXKime=|9qUROlD*p!HPUH^|-@5dySwEsuH$=II z8T%c@IsoqEIvp=jJfY>^YpI-SLDy&=j5))B36RV}&Jrz%bpg$eZq;pd8POs75iPXJ zm;p+E5lU4e;hVlZCg~4G+hihD&jjy?tQSihp_qMJT4gBEN+CqA_8P6P&k}~){C(QN z3yBUrp8vE%NrYg?kMYE!&p@RhYE0G-#8xEEWT~HER-Q%vSw}_eT^zZ!BS()ux8n80 z!X?c+3@|0qAk1{(UiEl>Q2UJmHh4k?v-iD$r~uIXj9+qI{o3uPPY+0w3VksJP$s{H zdsB?S?&vlronCFSW)A=b!6S*M5vFvKMa1-wFp&411d%l z64*r!?$@uG?1V)nFSeIp56rWsE`$7M)6QMQGUJUy(-|L=&^6`INFieA8Au5(v2Eok zs5y2NuBC>>H}H5ryVHMM^r*#cH{aFb@9wPQR9J=^gfde`a!IfMU1LP*`Sb1;t-Nw* zewwey%yHqPcpC=Cg^PX4aoy!qkttDL_vgk zH1MRl)Af_DTmYiZ)XO3-{@)yeh`Ac`9h%cI6IlRFP7%wX({V3~G>;w-bvFtqk$o&AJUWPW2=@LI>rvYzg90##Qw}a|$I+Gtyv1OQ1jSf)KVhSSK z5!3_hQ045eSA4MNP&S}P*3!e-iN`(y$_4O&d>XY;dgC(I;GdC02To`{(ZciVsl*zy zI~+-;88O-kE{{@DY>O$r z_fR)!xv2Elo{vo)^P)lzgHt0C2W@ovcvY7>$80OVv@5{Gj5J z#icX=@ti+^Mo(>&fkwBUk$1FMS#q5XF*k^n;)X0$3ZGVP=4S=YmKY`D%mC)s2Mr4y zN@QpX2mmu(le-S?{K6g4%Rxl6O(w`FlvS2V321p>@IS=&cl)4ugn{JU=e8?xcjoGp?t<>*JZ$9)anzay_;x=?vYP2fgjz8p#Vs^Xt*00W+4T39%WG6Lf5SNL)HUL zvjyB%E?-N!HCTM|FSfsBva%V-0|^~2L5Dh71X+kj3dO)No7hf_7E8HLy9g-Z9k4}; z5>5t+CKjHymwSP$4392jvy`Mz9Y{{I`0y>d?FncIhbrtQfa3M5S7JdPJ3a1TWLg`C zUT()q=5drsYvLKXH!#o`E*L>W0AHrKS7(GjR06cmeIe+idqp5y3>F!ep&=|0be~9M zA*7^_IVkyis^FaPzmhk)x9o0UDm@ys#LxwQKfgTn;pmKU2cv#C`>+vD_ z{3EOykts|9#B%b9Y+1p*3ihE*NdBq@dk?=Ei~4FFT0(A_ge^2*88CJebo(jgp8&Vf z?$}O?Z53Apc$LAgQz0=cH9hiZaem^O{*=yd$P8RZKkB}nPBy9ud%=!~TwRbsA({~_ zo+y}D(iLe^`)0d}mLH?B;z2H&6i$OI9ic#}{tfOn zAv|yOE|Q~clqOTq!P4ax`6$K410HH>9}z!u7S5qEL#7r=O8|63h5Yz_q-QQ+-o!NU zCKpL`iKI6z6jNfS&bxMWa&jvBs8AgA7bO=K=u+h{fMzL7+=yD)QU*?om^-!r5z z)pKpbH691q18kyv*cucRB)HsaA77f^_f`-bL!g2?ISl{dZJkdNc2jdr_##<{eon02?cRM6sht z=i*QGk6O$MRuppZp2xUQ4F44Jy#vP^yUs%iC}EPVU=oRWZ1Sr?JZ&AhkBW#( zozai%>NKR$W;w&$8PGBLL0!rIJ$(kqqJuC5)C4zVtcKbOAT(t4B5(C;P|t8p;irpk z03^ge6-{G@q-_bI88cK&@n_;q2s_8SlJGdPEnrLu@ zT8t&R7SP65R=jQs1^J2>vf!xmxQwmmXATrIH5oX^0t_5}h7K$-n$ZFNraA%x4%#j8 z%mU(p99+oE^vcynoj0)349*__5T*oYe~~#*L^v6~ecQG%&5d=0@)v(8w0ZJdNlngV zGC6WSHQe9O5zD$mm-R#($K2Bylr<2B^X0d$w?befa$(VT@Gqix6MU|(pMO8H#Ff)L zk=-#-xLycCAXUnOaI)sD%PQkCZm~T^#s%b}0fqlySBx+a&ye1gQoWeBUw~9-R}Z7^ zn}yh8jRA!6pBEHL^FnlZbj)sYCHSr&xGs#gsC1hd9<8^!LBtMXyv#O+8+q-)TBOVH zzmNQ3MfgSoUKSVMpd!Ib&xqmHE-2%!zjzVB&)eqi)I`G%$)^~L$vhR+1U1f&S33ud z*RmUz(HJ&}!w^F!Nf7?a>kVZ@1bPvgI4UwNd)4^nC6nmAa~h8E7#L`M0QHWA!GJ)s zaT$)}a9Icd{b?L&J=o=5SCP+ITL%yq6pCB4>TYm^^djm}Qnnc1f@{YUUER0A2gz{* zKJm6$sAkH`%fGrVKGK9=Y5b#gtgW`tBFU^4<4TI$8yYN{Pbv4_$NxH&2mOArX@c(- zR7z-SZ5FNmMqTn5QGgD4TZ%+5**MVD&5v!zWgJ6ZkqOcjl9wv^?&nE)L#POE$hF)vZ8#aU^geU{kgRHH|cADLB)Jh zj5Xj~WDXG>F#PkAw#}S7G*?lHlE(xjrs21?s^~74a>A{VWYhnInAhb=@mrafl%X^} z9PznDw{Z21y5typv@riEj&_l+5*FU=3|q6{&#hgE3PD=o1jeJ*eNi7ZVLl|pRNKh< zqMjJQ?m=)_`lHeT9Wc7yfyEF57&XD4Vc>CP~h z2K(7#4(4barY)Bv_cfj{VZvD|URw3@%d8C(k<|-5qiH6afd&m4#DLhmvNMLta2Lot zK7RYQsp<*7VhNOW21d<(5%3xa=Sj#NCSoAt$d?GxkI^6v^{C@pKE(?!{MshElh_LQ zGM^%275pwxb&G)PFKcIo!JU!cA%gUlj2Pg&g>P@MdHtKSesqniX#!YwYfEj_)PJr) z!Z#K%X)k?|JSH!tEqJTx3&l?v&see^_l89t-HxjjkKsXD!h|+8ns~EUMGwMh&ch)? z5HguT!WnGh-<|{mF|=+p3r9Sg=qr)NQi)lqnPEI~j*I_1vqWT~V^Ol}@FmR%H{GqURNunwj0mxOph|>rXgc zp8?B1eEi(%=WbO)9Txi1N6RhhR+Y6>1&G967 zcIJ-S!@KNq{GFTsbzkbF)$%KgeD|JJyKvRgxOa9zVROSKgTkMy>s6**y{8s7)8=Z0 zlSvhyz^(h-rDduAGch3T{&k?*S79sH`Qadv#n}Kk;MTs?EQnKCg@(GHmp3Hr);> zOvret_}uVE$KssI1+JyOcDJU#8B{p7YKHFln@Fr(k5qm?@X~Wwf8D zIo@w&Y4t?oUphzibTzzUo3@L6wPo-2Ta$JU(ij!oWs=>;_eHL6l(i}+EV2IAVbFlT zXRodRs(zWY|FV}`mm%{T9w-<&?bETkeD%52(|MVUxlmpI!V--h*sB^vMd=8UblLwTyI?Gxis z-^TwfZx|@LkXJ3L!2%#+oYxhW_I7f4hXebiW4(VHPjwXz;zfhp({0aG6B9@>_F(5k zWx4}d1VMOs*B?s7=glpgkC1L;L|{SI4{9HjbcOqID^6~Q)oR_BMp~pqK53BK4{-}U zH~IFi_S8G2GG&Z`}X+oNK&X!R42({um+D(JW(@rx^QS0nDE$%qJ;DTGw**%h2CN+s5tB zsD;_n^mp`6Q#>g}!MQ#gbj&;1KdJZAd+@qUajCl$Pqg7Du>$n|!tg2_?30s0g4e32 zOPeaOG^!sGrM~fMk1f& z^loKG?C1C!5s{dr=)8K?bbntO$xzX#Qeu00jE!^^bTvRfR~_UC;z1L9OEqWu=n4{fZU6G@0AFBl%&`%+^V zTS4A7H=6O+e(WB2-c-iA*b(0i;W=>(pP69m5O2s4Noj!~oq|$H1DvbQmErh+$a7#@ z1|mfWmMb>9@EE`MYTaMxmknR(%ENot6}w%ifA@t^-uDXkWL@`8hs>7iy=(}WBV6Cr z+OzG>9&;SVRorBMCib$hvIveZp%2u%UEAAKaZi8$1Z!rDTm?g8X!@ju66{zR-;1lO zg+HEK^zG_DRR=TPm_jwGeYR}dWgfSPPWB>v#PHlv6vcJQ9aFPkd7g?-Dls8*PF6R* z4u99W6_Z7CrYP!*L+43;v+_nxFK%fuY!}#wZ{zlrl^!YrdCHMdD`Q1D;n+U%2V_~` zDZ+F8cGBmKkWH?rADrT}{9EN`*qgUPW~z?o@hhS4YV3))7u7s4R-+i}rdrNf!Ep!2 z7(Z+z4Lr-y#^HR;wdYgH4tum*9q81RpPAH61+_xS`Y!sq*B3%6$?3;83t|cU9*Ssk zy0PuZ5e`DxBK_$`g7-Ji>TV5`w(}fZISpy&Cg~a5EB#E>Xg(sf3KWgtZV*TBmqx{P z4AdOTURmy_SzWRq?i`xr0L1pu$oE8{U%rHK<$E1dW0;n_N|YwI86u36qbJ4rz)BYS zsQ6oP$xTN8>F?!Mks@_Rv0Xh6lvEsPxrj&AKB%Gi`PeA+&$JKIN;F3W1cpyue4SJ} z^FYbZ3w~$IrWz}$7}h3gsH(Gqv2IGHuE|YB;XS}hV!!bH6@~57J-sWjtX)YF5ZElA zlTN%Lej#Wx5lf*j{49or^uq%Bx{vRb;2vW9{CX04oE7kN@(&Tr)%{Vhml~O`0K(`P zE9mt0_7QWBYt!^r3JLk(Exnn!^Q!!3q!;(wMa$k-dumgO8KQz`n=fc9RycKXsDqmS z`eB=1Vy8-#cx~2@y|VQ$jwd9RJoz<$baMFCFt8f)OTFhiQsxNmPl!h^ltjFI2Lw}X zg0@aFBaHJ3OyknKS23?SP%-nXV%~aoeW`B9zX81%KVBTU-E>pYF}?{(n#z`FQ2rg$ zrtNt9G%ILUZT$ef+pJU^OfW4yw{9Jxuw@;Om{b{_Ey4R<|o(2QOEKW$tdTb^G%;(=~ zaEriuoer4yp%nc`ZM@vo3}y$0Ne+kOee@+QaC;9-PiGmXnSHDu6k;Ad&k9VrOeC(+ z!BXYmk(1V}FcW12DQSmO*#_8daCAdN!s59HAN6T9w61eXqz9dC4=2M#>njtNY8yw^ zQ~SUg#H5&2yva&vm)P#w6z^)Zt$T*&pOfI>$NhfMQaI*{9E)6U&@o-gaY_rgmxdn{ zqRhJav=@<+O9O5P+xV7$1mQkBz-5)7jwW?M^^37s{X>|PLPmVX-C&XpvFUlvDZ#41 z-5OyLBkkDhQbbHM8%p;~ejXRe>75-e^*qH)amp+r+CA+#X%7`EG@Kd6HoQ*Km7X-W zvKU+>YLi#xx)w4l=lau{|8SM;q-$hQ1$h;K+R+7e-%iNtRZNTi>k#plVfzi?u~Ir` zR5ebS?4#d>@FO3*_aQ%Hnyr5S>2g0eCzdUGJ}cUgkW?^r7Rh+NC_`yBcju#zzq+PS zYN?Gty6yS4tjZ~kBMp<2)?Ov(wuPCr;FBKiuYL?VlZ1}Hw?@(6FVlV>u@?+U70Vy5 zbI@Q?sjso6jHoh463s8OUir9NbJE*;tR9(_?_Y50*1c{u5;$K<2Xu1=B)h zU)sGI+d0oixG5ZH>=+%>gE7^R!XkpB(7uoOKE!Lqtq<~aIHkgxzKz}N)@yps-eRCK zfFl8VI~JcAFJvXsb;vE5)IJ3`=&hB#WG#Pwl`G3{IIq#&@jGg)A*cKP&o`9g;@26I zYA{bs_)}cE%P@(1_a|}V6G)V@%C#zgp8Xyf%=-DXYp+^WINr)65LT6@a&4kEOOUd4yWghn-lxRk_dh0C$|YNVU93XjY?wzI)$Y}#D)G;y*g}Fz5fRV@X)Go z(`xx>pH|>r#1$#xsRO|goNa=l<#O@lsl#mOIzMgWcO7=+5IJ^C2(tE zsVz{yuz4sZsHVTL>v+)*EP3ajP8no*X$0&k-~!(!=m-vWDDMsJWibd*e?3$|f4jaE z2CF3?%D|O`Y8)J&x|&p=Q@cQCEFb4QHI&VR3>>F4`swA5e|a^wC5lJD>i}P;`ACUR z_CD)pOiRJ*&BshJ%FHvBRQ!Ws-e74Xsun*X%GfmWZ}biQ;U5!fM}N^FgsX6{jBHCU zqep6ceF!VUq?_>{&PzZY0JJ+|f`s9{`iJ@e{27>yMUz@~1&m?v01g`_%F^ZPBZnEF z=im+NFAh@|6Sb^_-@vg(MEQTJ)w<;y`uqsNz_!m%^z|uSP>Ju|Kt>nb0M1f%{aXAvRO z+!r)!GCX3uH{Vf2(nuQ9WW!+dAqb|L9*6dt#Ta98m^}4H?RB2T! zLZ+D~B9k=jpTuNNe$pd7;>vfH*Q#^~%m0e*q8P;^7tn3F`K!N4jY={Rb`rA9qljs%Xzn0Q-3VM#0A@RJ;1N*Cr5y$Q<{f_a{v zWMc)sPYIpk!qj`G+KlhP&BI*`fi6x76EC%fy`Z`YLKRWOtM{&8DziC`I!)lrp1l8i=4Ild=J~v3J0QDvM*MVz zp)}RRUi?)L#xQ{6bnQrdb2XPjSYpbvqmN+NvrR1KHg>ollo^Vx=CZ#h5IhMOqB`86 zQ!oTJ?75DnXh*5n8wR~E;L~Z9jQS$J7UpLzYUo}5^i`D}N^sI6JOKHkjLTmx{G-OV zFnvaR5Di$5<+8TAfT<9G?SS?H7pdkI-D?Fg#?q5wNIjrg@I4Lily90w+h5x)tYj33 z?^_{c8kMi>pKD|RtdHj7UjDd^T2$#Sh`3O9g!n zg5_>L!qTX~4Jvmj~?7qz6&ZD_OIA zMH-&-ygV;FnDN0xKoa$+Nn-Qf$;5U2_qPcaw3Rh(UH=y6xBo4@5}{4(^MM?7`*m2_ ztcJVgVcI!+GbMpcZUz<0Ua+~R>Q-1ql_m-u+XC%=6)Q&4GF&qQTT`^gT(HIlY-Fxt zEF;Z%t6zuhvi7sHZ{zA@EfXhZDVGM+d1pR=Pa2C=k|-p6pY`?rD*PBch7w^yg+3 z?GqRC&BMS30V*G^l!rOhP!t%kM3Y^}{Nb(ncBC=`BeOVu3`@t~#suoPiWdv*mj{Gp z6S4TUqlneS8Zvx~wlDF%QodPPP~wCFdKN+3>@*3M^vw0Rib@|tw_nOGgA+MM)!RX0 z#|^Bd2}|nq9hRuh1*cT0)%ySqw@~%&B#|6_L?`xqYj3TVcUV%!$c!=k?v;J?fD;!F z_hcDVoy^jF`*1jcU!?Avw*3LSmui{qdS>~~c^R+y(4Klx>pDq>A=)!yyijG1uFDv5 z$>+byyH{nWC*WmoVGML{#MTkhL4IDq!|fkWa3?7eP#hAWYhslHYp@yP<2zo5UkVIlN=OvvgdRc}w z`Gik^1yYD9ZNVqjtkIsMQqZh~O#ZeV8Be!-!LM!9D3Y9aPaN7%4+55gE5L`AKr;@H zd|m4Mcn@9YYK-m<3g7#TFOFkZk|EXY?3h8->Fb+*hsm1w)-$l4IFubHrm6o1jIR)L z?9~}=d55Aw{zQOVdGvjx%%t7vVc(gH%H!jaOeTqvO^!~^YD7#KfbsV`8G9eBtogxh zdxYogc>O~VKXb2aF@ijai?6Lu2JHZ*%A6GhZi&^thAMS$fHy`s9WV|GvE!EFQ%)@L z&QQ1+j%H&Y9l)}MdY@mmBWZwrif>VtRyK85g*PF+K2l}Nap*w+ZYh6Z{B3*gr2_uJ z@Q`FerRP{h>)Z9Ur>~FQP;9qx%|@|Iy+`~BbcLr?De*;5+My!8Js7|&@*4H5V9tFA z{E$>2c-oIt(KLSOB?{p9a+Uw|PpAf?Ws0iny}~NMPZwcJXVP5QF~W}s zltio`H*fxQw^LwjCcc~F2fMzpgov25KiK*Kcb#W}>SWJ{=&Aj&`AC5wqux|FnKrC| zczE05Pj;oHr!Cliz^NtG>4wJQVEyi^c08Sq}zx=Ctrrn6YHXnzU)7 ztgc(&6`K^5S>Aw`QRNxa?N6R&afJlH|9@niB=YB{3PjDH>FbbXYzA;HEFMF)Cahz42NX3*%G7 z`|e?kLS+U&he=Ew&8M$@=0SDX`QVZr2-DF$=kQ(nU``Md*g?SQCF4!{OKbTE%Q2 zy)^ra6zrOO2-G~Odd6BOOUA%+Gg%LvFYB{H+^QVhO(7)KrI^v#; zFe~wif#Dx(X%!C#9&@aoMtA__NyU4?NxSDD$?2FLs1o-}WQ44FE{rNB#aCw20NoBQ z3;~>>U{wI>E=F$lw6MX)|EW$ubDw(ctbm{HyRni-VTkFQD~UIs#ck%7Zkdu8_--J1 z967`GDIa+Rm>&CV2R641Bh<-voktIO4MBpu_|%rk}0) z1no3HAt41zB(N2ADXBQI8xbEt55%nqAE(zI%2Qf^Z-KO?Xl3><9}4Q3;JZ!#f|MH7 z9R7XrD;B6;`@97Pe(RN|EV~%Vu1=Ev?Bp7cS>d2T#K$%Ma#_a|&QYvdcepUi4{(si zPiHmwgbuA1mK7!tBo2HT-)@Q|7R}HXYnmQ!z45YQ&za+Oz-H(9p<4jJ=cWujCJ|*0c)k34aj+QBT{VTUd@8}8e(TwD?~F8JwMt*1qWu9k z_oY6|_Nmz|_`HB$&wFO=;K%Tw)#_lS;qM8RZtPNUN?vyX|Kv`a?qu0^xec#_6uOA^ zseL|P39BU8tUsFriQc~Jg5xs*YRw5A9z$V|5Nm(Rr}agMa^H76Z?JqN&OrDfG);Xe zUpk(S+2cn|gwSx_rHPS;Q20rZfM?UdCcD;?lNMRP@V8#wd#BADD%u<^SM`;!Vi*Ik z)BYb>fH~8x@pC*xh=nOLOvVhW`twReVx#>%5$xp@Fd7Hb+UT@w+JJ5 zHAK1YqrPeJ_;(Oa0)kOck^gA0_6cda%?r69%}{j2#I_|Bo;%QZJ4Oa+<yf_-eN#>8qP2U)sV1yQD0|7Ci&Y)+=VH=bfq$@7gd=OiQn_{asi}3H0aues1+C# z0HHfOOWwvdQ`3{AfGGtJcsq%^l~PF83HTV3hht$GG*7z!`JI^t_6X&GZufUx05i!s z&E^Flcn=Xmd6P~YE5n6j2NTnR0=u6_?8oi^?+2}nz!4E!bcC3KaXas?n~~TTEgq8j zs;&9n?0ltG*>L_a1Bethciw%bm;v`TlEa?`Q|}2mKZ`ceB=(s8+ED~M7ASD$_M0D2 zwbB)EO&XxqfRG-XhF>UMm_DA@sF)^^wPeaa9O1S$p$cFnJ~7b`Jp=KTMIUViS6=~h z9>o!RSVItAVCt!Q{@fIwj^_gxlr(@Z0J0efG^gz8&oy$@G7Yt^npN9D2xvm~HUq0c zG-2W@TO95|0sA8_V0sYnJz-g>c@G^8nOV@2iUmZ!=D_QO=QE6Cg z3qZ=jurd4~iIYe9Kqoi1H~$>t)*5$&8xTd2qh6#c#d2`|FHpOu#6%=WR7 z6y5pqLgbEv9c71u$NgOJ7oWFK-XU}k^KRW9v!TyPD230<9H!c(!CpeDz)8+kRajXY zPWJ7)si1mE&-|Rc7!6F9#pV}W;B9H7uffT}d~IPYIElm7`VVY{rd*%f4SW!`TQX<} z{7MBWjAssGt$8UtmXmvhN||k`yb=IAD9PzuCZ+4nE5c$30Hi#@43+sL`jVv`7Z7Bz>Ac*pnd_J`^S{GAROGMjE?nEoEV#h*K2Tan<1!e>-KY>3KiadTK|!BG>Lj^VIBp-s}`mYK|GZ7L+a=kr}mM-6L=!O z!U$w{9|G*TB)}l1y22BTdQ9LEUoK2&!1El2Ij_OA#lijTB|+LtZ}$o&5YHwC6fUoa z>A~)%3);M#&Zb&DhoYg!EhUvsf_TA1m6y2$h?*^cI3Y>KjQSG0#E6fg^` zncjrZo-D0Pw{4=5F?=_2+u11HE^0FcXNrqNKvGs9^j>N%?FcxN3`;Hlv2#X(ZBeBUc>XG~bx(@!XSvYW0t6C>aJl zAW(9h-Xh}ip|Y9{l4jZpRmQVo#8Ih7ensU>`H-kQipwJ-el-Wl_}(&%CclKV{o=7* zes&{2Yo<=d@|Lh5w(iDfzCFYxgy!CnDiYEo(v0Xc(G-qG9Yw+XOcAX;y}zp$uSeNSO0SWAPN=1&Z*@-rYmQqqMZ?1s$Oi zGQ{9O#>mOl`=braQ;tjgbu{a{^Z}p{fMf~!8Puc@OI}hB5pYT%?CJZ6Z_7PB+L&Q^ zLc#%~-j#&cL2k=42UwWWPdGv|k7fm>l&1(@)}l@_Kme1;c#-$V3sJjS7mmAd?8Lz< zAO>pGJdU{+So>v{GP%wD00d>~PzHT~Fab1D;2f88f;H+dwdJ1m zF)Rj450`^_17Y{2=RK=tGEg-ZGg0%6UxBz)95`fH(4c-SsM3><@~;+7PASF$~}#uoB#ITr%Ffj;B3fbhoyn(5SZy`_piD0{HyTZje#4Y&elpkT& z02C9<-tzfBZev8t{%VIq>X<_|g=tdPRKKF0K9JDaUjPW7%XM3)*a#$4NS`^7jv&ZY zZVU5esSrf9>q)8OhRGFEPO@?NScdJ$?7s+x8{)&E2BgsSdR_MlU`!Ap+@wJRoR|Jx{K z-)h1cxx4q@O105!p0`m_9Hj=XH$=GN$&-0Bcr^maL|!%g&qRlkfcbf`Yyw}X1U%mh zEeM#yg)bGMh&eF@D7EkymBPr|?WN?RO^ND2Br>)zj1=_KY#%+kX)Ff7Q<>fI0)l{_ zHISz#5PlY>=N@?YyP{p@VLSy@SlM>5Uv!gdGKHG^cL`aB=lUY6LEE-jna`yAv4Yqf zO?Y%R>}P&>hKdUhfzl{DP)Jr}k=$dYKP5QoGFVnuPC#`-LEx5w`my(8{CkA&-sh2S zzL|zS`&ae=UFWNlz>mbV5-cJxp8g(brR^d{{I!48-t^=(RJChUIA;x71FR97| z$+8QptI3O#7}Lw3n1~O&VKelq`Ca(V|Z@XuZ2B|&N)+zbC4#4z6gMZD;_XF5k`zN!M<)&;Fe?aCx+hJpF6 z_CnTVrYoK#NCzm+U;<)q1WrI`dhKXmMh6llrc+FZN9r#zw;nz4V`P?151J5;;}dFZ z7ah|#vrXJC_ZVb}M3gDzc?HH%np|Xv9bMhMga9<8PA?fccYup3#2KV zk!2!l(iH6Z#n4H#N*Q8X#8DmsqtSDR;)`?K>G|_IiSCB%z$AIz=CXvt!a!;kyd_!I z26^IF%E#ZnC@vAt?kL%(uTyCel{;9+CK%$aXGT9~(Q%QyJ=L z+gV+b1pFifXNj?)P#rn_mJ*u$( zAx95%cK`oLf6sVi=#u{PTmL%=ff_cGzgjUtLMznC&W|gsI;`Sm#MbRqajjxfN5k`&)AUo>V>k=B&OS33P_#To8AO=g^J|W@b3(VG5e=bRTbn?vsO{919yx zF7=!R)Pdg>RpUs@%YnLryBu^-L-q+rrdtX#?BiYO$yV)M);{Qh0ID;kk)OWEfZ{n& zJ27~?EeA@lK&ADteeEX%5p@*k=?1!cq^!;)D=bBt{#Rb-LyaW4|GN5L$@2U^-a-F8 frSyNe*)>%&Bhy=W1kK((@S`B3`lej!?Z^KIJ+Tg7 diff --git a/docs/b-tree/image/output256.png b/docs/b-tree/image/output256.png deleted file mode 100644 index 8281a2550bb07bf62e8bf5b8573ae79e0bbf422d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67408 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%0Af8?t6o3?puxcFuw%8 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 BAaMWy diff --git a/docs/backtracking algorithms/N-QueensProblem.md b/docs/backtracking algorithms/N-QueensProblem.md deleted file mode 100644 index 33535c0aa..000000000 --- a/docs/backtracking algorithms/N-QueensProblem.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -id: n-queens-problem -title: N-Queens Problem in C -sidebar_label: Backtracking algorithms -sidebar_position: 1 -description: "The N-Queens Problem is a classic problem where the objective is to place `N` queens on an `N x N` chessboard such that no two queens can attack each other. A queen can attack any other piece in the same row, column, or diagonal, making it challenging to place all `N` queens without conflict." -tags: [backtracking, algorithms] ---- - -## Problem Definition - -Given: -- An integer `N`, representing the size of the chessboard (`N x N`) and the number of queens. - -Objective: -- Place `N` queens on the chessboard such that no two queens threaten each other. - -## Constraints -- Queens can move horizontally, vertically, or diagonally, which means no two queens can share the same row, column, or diagonal. - -## Algorithm Overview - -The **backtracking** approach is used to solve the N-Queens problem. The idea is to place queens one by one in different columns, starting from the first row. Whenever a queen is placed, the solution checks whether the position is safe. If so, it moves on to the next row. If no safe column is found, it backtracks and tries a different column. - -### Steps: -1. Start by placing a queen in the first row. -2. For each row, try placing a queen in each column (one by one). -3. Check if placing a queen is safe (no other queens can attack it). -4. If safe, place the queen and move to the next row. -5. If a position is not safe or leads to no solution, backtrack by removing the queen and trying a different column. -6. Repeat until all queens are placed or no solution is found. - -### Functions: -1. **isSafe(row, col)**: Checks if placing a queen at `(row, col)` is safe. -2. **solveNQueens(row)**: Recursively places queens row by row and uses backtracking when necessary. -3. **printSolution()**: Displays a valid chessboard configuration. - -## Time Complexity - -The time complexity for solving the N-Queens problem using backtracking is `O(N!)`, since we try placing a queen in every column of each row and backtrack if needed. - -## Program: -```c -#include -#include - -#define N 8 // Change this value for different N - -// Function to print the solution -void printSolution(int board[N][N]) -{ - for (int i = 0; i < N; i++) - { - for (int j = 0; j < N; j++) - { - printf("%d ", board[i][j]); - } - printf("\n"); - } -} - -// Function to check if placing a queen is safe -bool isSafe(int board[N][N], int row, int col) -{ - int i, j; - - // Check this row on the left side - for (i = 0; i < col; i++) - { - if (board[row][i] == 1) - { - return false; - } - } - - // Check the upper diagonal on the left side - for (i = row, j = col; i >= 0 && j >= 0; i--, j--) - { - if (board[i][j] == 1) - { - return false; - } - } - - // Check the lower diagonal on the left side - for (i = row, j = col; i < N && j >= 0; i++, j--) - { - if (board[i][j] == 1) - { - return false; - } - } - - return true; -} - -// Function to solve the N-Queens problem using backtracking -bool solveNQueensUtil(int board[N][N], int col) -{ - // Base case: If all queens are placed, return true - if (col >= N) - { - return true; - } - - // Try placing this queen in all rows of the current column - for (int i = 0; i < N; i++) - { - if (isSafe(board, i, col)) - { - // Place the queen - board[i][col] = 1; - - // Recur to place the rest of the queens - if (solveNQueensUtil(board, col + 1)) - { - return true; - } - - // If placing queen doesn't lead to a solution, backtrack - board[i][col] = 0; - } - } - - return false; // If no placement is possible, return false -} - -// Function to solve the N-Queens problem -bool solveNQueens() -{ - int board[N][N] = {0}; - - if (!solveNQueensUtil(board, 0)) - { - printf("Solution does not exist\n"); - return false; - } - - printSolution(board); - return true; -} - -int main() -{ - solveNQueens(); - return 0; -} - -``` diff --git a/docs/backtracking-algorithms/n-queens_algorithm.md b/docs/backtracking-algorithms/n-queens_algorithm.md deleted file mode 100644 index eefaa3ee6..000000000 --- a/docs/backtracking-algorithms/n-queens_algorithm.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -id: n-queens -title: N-Queens Algorithm using Backtracking -sidebar_label: N-Queens -sidebar_position: 1 -description: Overview and implementation of the N-Queens problem using a backtracking algorithm. -tags: [backtracking, algorithms] ---- - -# N-Queens Algorithm - -## Introduction -The N-Queens problem is a classic example of constraint satisfaction problems and explores ways to place `n` queens on an `n×n` chessboard such that no two queens can attack each other. This challenge is often solved using backtracking techniques and has various applications in algorithm design and artificial intelligence. - -### Problem Statement - -The goal is to place `n` queens on an `n×n` chessboard so that: -- No two queens are in the same row, column, or diagonal. - -### Approach -Backtracking builds the solution step-by-step, eliminating configurations that violate constraints. - -### Algorithm -1. **Place Queen in Row**: Place queens one by one in different rows, beginning with the leftmost column. -2. **Check Safety**: For each cell in the current row, check if placing the queen will not conflict with previously placed queens. -3. **Recursive Backtracking**: If a placement is safe, proceed to place the next queen in the following row. -4. **Backtrack**: If placing a queen in a column leads to no solution, remove the queen and try the next cell in the row. - -### Python Code Implementation - -```python -# Function to check if a queen can be placed on the board at [row][col] -def is_safe(board, row, col, n): - # Checking the left side of the row - for i in range(col): - if board[row][i] == 1: - return False - - # Checking upper diagonal on the left side - for i, j in zip(range(row, -1, -1), range(col, -1, -1)): - if board[i][j] == 1: - return False - - # Checking lower diagonal on the left side - for i, j in zip(range(row, n), range(col, -1, -1)): - if board[i][j] == 1: - return False - - return True - -# Function to solve N-Queens using backtracking -def solve_n_queens(board, col, n): - # If all queens are placed, return True - if col >= n: - return True - - # Try placing a queen in each row for this column - for i in range(n): - # Check if it's safe to place the queen - if is_safe(board, i, col, n): - # Place the queen - board[i][col] = 1 - - # Recur to place the rest of the queens - if solve_n_queens(board, col + 1, n): - return True - - # If placing queen at board[i][col] doesn't lead to a solution, remove queen (backtrack) - board[i][col] = 0 - - return False - -# Function to initialize the board and call solve_n_queens -def n_queens(n): - # Initialize an n x n chessboard with all positions set to 0 - board = [[0 for _ in range(n)] for _ in range(n)] - # Attempt to solve the N-Queens problem - if solve_n_queens(board, 0, n): - # If solution exists, print the board - for row in board: - print(row) - else: - # If no solution exists, print message - print("No solution exists") - -# Driver code to test the above functions -n = int(input("Enter the number of queens (and board size): ")) -n_queens(n) - -``` - -## Explanation of Functions -- `is_safe(board, row, col, n)`: Checks if it is safe to place a queen at position `[row][col]` by ensuring no other queens threaten the position from the left side, upper-left diagonal, or lower-left diagonal. -- `solve_n_queens(board, col, n)`: Solves the problem by placing queens one column at a time. If placing a queen in a specific cell doesn’t lead to a solution, it backtracks. -- `n_queens(n)`: Initializes the board and starts the recursive process by calling solve_n_queens. If a solution is found, it prints the board configuration; otherwise, it outputs that no solution exists. - -### Complexity -- **Time Complexity:** The time complexity is O(N!) due to the combinatorial nature of queen placements. -- **Space Complexity:** The space complexity is 𝑂(N2) because an n×n board is used to store the board configuration. - -### Example Walkthrough -For a 4x4 board, the algorithm would place the queens row by row, backtracking as necessary until it finds a valid solution: - -1. **Initial Placement:** The algorithm places the first queen in the top-left cell. -2. **Row-by-Row Backtracking:** As it tries to place each subsequent queen, it checks for safety, backtracks when conflicts arise, and adjusts placements until a valid configuration is found. - -### Visual Representation with Mermaid Diagram -Here's a conceptual flow of the backtracking process in the N-Queens algorithm: - -```mermaid -graph TD; - A[Start] --> B[Place Queen in Row] - B --> C{Is Placement Safe?} - C -- Yes --> D[Place Queen in Next Row] - C -- No --> E[Backtrack] - D --> C - E --> B -``` -**Note: This algorithm is adapted from GeeksforGeeks.** \ No newline at end of file diff --git a/docs/balancedBinTree/balancedBinTree.md b/docs/balancedBinTree/balancedBinTree.md deleted file mode 100644 index 05b276d56..000000000 --- a/docs/balancedBinTree/balancedBinTree.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -id: balanced-binary-tree-checker-python -title: Balanced Binary Tree Checker in Python -sidebar_label: Balanced Binary Tree (Python) -sidebar_position: 4 -description: Implement a solution to check if a binary tree is balanced using Python -tags: [python, binary-tree, tree-traversal, recursion, depth-first-search] ---- - -# Balanced Binary Tree Checker - -This document provides a Python implementation of a binary tree and a method to check if the tree is balanced. - -## Implementation - -```python - class Node: - def __init__(self, val): - self.data = val - self.left = None - self.right = None - - class Solution: - def isBalanced(self, root): - return self.dfsHeight(root) != -1 - - def dfsHeight(self, root): - if not root: - return 0 - - left_height = self.dfsHeight(root.left) - if left_height == -1: - return -1 - - right_height = self.dfsHeight(root.right) - if right_height == -1: - return -1 - - if abs(left_height - right_height) > 1: - return -1 - - return max(left_height, right_height) + 1 -``` -# Creating a sample binary tree - ``` - root = Node(1) - root.left = Node(2) - root.right = Node(3) - root.left.left = Node(4) - root.left.right = Node(5) - root.left.right.right = Node(6) - root.left.right.right.right = Node(7) - -# Creating an instance of the Solution class - solution = Solution() - -# Checking if the tree is balanced - if solution.isBalanced(root): - print("The tree is balanced.") - else: - print("The tree is not balanced.") -``` \ No newline at end of file diff --git a/docs/balancedBinTree/balancedBinTreejava.md b/docs/balancedBinTree/balancedBinTreejava.md deleted file mode 100644 index 0615a3e98..000000000 --- a/docs/balancedBinTree/balancedBinTreejava.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -id: balanced-binary-tree-checker -title: Balanced Binary Tree Checker -sidebar_label: Balanced Binary Tree -sidebar_position: 110 -description: Learn how to implement a balanced binary tree checker in Java, with explanations of the algorithm and time complexity analysis. -tags: [tree, binary-tree, depth-first-search, java, leetcode] ---- - -# Balanced Binary Tree Checker - -## Problem Statement - -Given a binary tree, determine if it is height-balanced. A height-balanced binary tree is defined as: -:::note - A binary tree in which the left and right subtrees of every node differ in height by no more than one. -::: -## Solution - -We'll implement a depth-first search (DFS) approach to check if the binary tree is balanced. The idea is to recursively calculate the height of each subtree and check if the difference between the heights of left and right subtrees is not more than 1 for every node. - -### Java Implementation - -```java - class Solution { - public boolean isBalanced(TreeNode root) { - return dfsHeight(root) != -1; - } - - private int dfsHeight(TreeNode node) { - if (node == null) return 0; - - int leftHeight = dfsHeight(node.left); - if (leftHeight == -1) return -1; - - int rightHeight = dfsHeight(node.right); - if (rightHeight == -1) return -1; - - if (Math.abs(leftHeight - rightHeight) > 1) return -1; - - return Math.max(leftHeight, rightHeight) + 1; - } -} -``` - -### Explanation - -1. We define a helper method `dfsHeight` that performs a depth-first search on the tree. -2. If the current node is null, we return 0 as the height. -3. We recursively calculate the height of the left and right subtrees. -4. If at any point we get -1 from a subtree, it means the subtree is unbalanced, so we propagate the -1 upwards. -5. We check if the absolute difference between left and right subtree heights is greater than 1. If so, we return -1 to indicate an unbalanced tree. -6. If the subtree is balanced, we return the maximum of left and right heights plus 1 (accounting for the current node). -7. In the main `isBalanced` method, we call `dfsHeight` and check if the result is not -1. - -## Time Complexity - -The time complexity of this solution is O(n), where n is the number of nodes in the binary tree. We visit each node once during the depth-first search. - -## Space Complexity - -The space complexity is O(h), where h is the height of the tree. This space is used by the recursion stack. In the worst case of a skewed tree, this could be O(n), but for a balanced tree, it would be O(log n). - -## Example Usage - -Here's an example of how to use the `Solution` class: - -```java - class TreeNode { -+ int val; - TreeNode left; - TreeNode right; - TreeNode(int val) { this.val = val; } -} - - public class Main { - public static void main(String[] args) { - // Creating a sample binary tree - TreeNode root = new TreeNode(1); - root.left = new TreeNode(2); - root.right = new TreeNode(3); - root.left.left = new TreeNode(4); - root.left.right = new TreeNode(5); - root.left.right.right = new TreeNode(6); - root.left.right.right.right = new TreeNode(7); - - // Creating an instance of the Solution class - Solution solution = new Solution(); - - // Checking if the tree is balanced - if (solution.isBalanced(root)) { - System.out.println("The tree is balanced."); - } else { - System.out.println("The tree is not balanced."); - } - } -} -``` -:::note -This example creates a binary tree and uses the `Solution` class to check if it's balanced. The output will be "The tree is not balanced." because the left subtree has a depth of 4 while the right subtree has a depth of 1, violating the balance condition. -::: \ No newline at end of file diff --git a/docs/balancedBinTree/balancedBinTreejavaScript.md b/docs/balancedBinTree/balancedBinTreejavaScript.md deleted file mode 100644 index eb5f78277..000000000 --- a/docs/balancedBinTree/balancedBinTreejavaScript.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: balanced-binary-tree-checker-js -title: Balanced Binary Tree Javascript -description: Learn how to implement a balanced binary tree checker in JavaScript, with explanations of the algorithm and time complexity analysis. -tags: [tree, binary-tree, depth-first-search, javascript, leetcode] ---- - -# Balanced Binary Tree Checker -## Problem Statement - -Given a binary tree, determine if it is height-balanced. A height-balanced binary tree is defined as: - -:::note -A binary tree in which the left and right subtrees of every node differ in height by no more than one. -::: - -## Solution -We'll implement a depth-first search (DFS) approach to check if the binary tree is balanced. The idea is to recursively calculate the height of each subtree and check if the difference between the heights of the left and right subtrees is not more than 1 for every node. - -```js -/** - * @description Check if a binary tree is height-balanced - * @param {TreeNode} root - * @returns {boolean} - */ -function isBalanced(root) { - return dfsHeight(root) !== -1; -} - -/** - * @description Helper function to calculate height and check balance - * @param {TreeNode} node - * @returns {number} - */ -function dfsHeight(node) { - if (node === null) return 0; - - const leftHeight = dfsHeight(node.left); - if (leftHeight === -1) return -1; - - const rightHeight = dfsHeight(node.right); - if (rightHeight === -1) return -1; - - if (Math.abs(leftHeight - rightHeight) > 1) return -1; - - return Math.max(leftHeight, rightHeight) + 1; -} -``` - -## JavaScript Implementation - -This is the JavaScript version of the balanced binary tree checker. -- We define a helper function `dfsHeight` that performs depth-first search (DFS) on the tree. -- If the current node is null, we return 0 as the height. -- We recursively calculate the height of the left and right subtrees. -- If we encounter an unbalanced subtree (i.e., it returns -1), we propagate this value up. -- We check if the absolute difference between the heights of the left and right subtrees is greater than 1. If so, we return -1, indicating the tree is unbalanced. -- If the tree is balanced, we return the maximum of the left and right subtree heights plus 1. -- Finally, in the `isBalanced` function, we call `dfsHeight` and return whether the result is not -1. - - -## Time Complexity -The time complexity of this solution is O(n), where n is the number of nodes in the binary tree. We visit each node once during the depth-first search. - -## Space Complexity -The space complexity is O(h), where h is the height of the tree. This space is used by the recursion stack. In the worst case of a skewed tree, this could be O(n), but for a balanced tree, it would be O(log n). - -## Example Usage - -Here's an example of how to use the `isBalanced` function in JavaScript: - - -```js -// TreeNode class definition -class TreeNode { - constructor(val) { - this.val = val; - this.left = null; - this.right = null; - } -} - -// Example Usage -const root = new TreeNode(1); -root.left = new TreeNode(2); -root.right = new TreeNode(3); -root.left.left = new TreeNode(4); -root.left.right = new TreeNode(5); -root.left.right.right = new TreeNode(6); -root.left.right.right.right = new TreeNode(7); - -// Check if the tree is balanced -if (isBalanced(root)) { - console.log("The tree is balanced."); -} else { - console.log("The tree is not balanced."); -} -``` - - -:::note -This example creates a binary tree and uses the `isBalanced` function to check if it's balanced. The output will be "The tree is not balanced." because the left subtree has a depth of 4 while the right subtree has a depth of 1, violating the balance condition. -::: \ No newline at end of file diff --git a/docs/basic-dsa/Method Overriding.md b/docs/basic-dsa/Method Overriding.md deleted file mode 100644 index e4f0e4c44..000000000 --- a/docs/basic-dsa/Method Overriding.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: method-overriding -title: Method Overriding -sidebar_label: Introduction to Method Overriding -sidebar_position: 2 -description: 'Method overriding allows a derived class to provide a specific implementation of a method that is already defined in its base class. This feature enables runtime polymorphism in object-oriented programming.' -tags: [dsa, data-structures, Method Overriding] ---- - -## Method Overriding - -### Introduction - -Method overriding allows a derived class to provide a specific implementation of a method that is already defined in its base class. This feature enables runtime polymorphism in object-oriented programming, allowing methods to be called on objects of derived classes even when they are referenced by base class pointers or references. - -### Syntax - -To override a method, you must define a method in the derived class with the same name, return type, and parameter list as the method in the base class. - -```cpp -class Base { -public: - virtual ReturnType methodName(ParameterList) { - // Base class implementation - } -}; - -class Derived : public Base { -public: - ReturnType methodName(ParameterList) override { - // Derived class implementation - } -}; -``` - -### Example - -```cpp -#include - -class Base { -public: - virtual void display() { - std::cout << "Display Base Class" << std::endl; - } -}; - -class Derived : public Base { -public: - void display() override { - std::cout << "Display Derived Class" << std::endl; - } -}; - -int main() { - Base* b; - Derived d; - b = &d; - b->display(); // Calls Derived's display - return 0; -} -``` -### Key Points About Method Overriding -1. Virtual Functions: The base class method must be declared as virtual to allow overriding. The override keyword in the derived class method is optional but helps clarify intent and catch errors. - -2. Polymorphism: Method overriding enables polymorphic behavior, allowing a base class pointer to reference derived class objects and invoke the appropriate overridden method. - -3. Access Specifiers: The access level of the overriding method in the derived class must be the same or less restrictive than that of the base class method. - -### Rules for Method Overriding - -1. Same Signature: The overridden method must have the same name, return type, and parameter list as the base class method. - -2. Use of virtual: The base class method must be declared with the virtual keyword to be overridden in the derived class. - -3. Return Type Compatibility: The return type of the overriding method can be the same as the base class method or a derived type (covariant return type). - -4. Static vs. Dynamic Binding: Overridden methods are resolved at runtime (dynamic binding), while non-overridden methods are resolved at compile time (static binding). - -5. Destructors: If a base class has a virtual method, it should also have a virtual destructor to ensure proper cleanup of derived class objects when deleted through a base class pointer. \ No newline at end of file diff --git a/docs/basic-dsa/Operator Overloading.md b/docs/basic-dsa/Operator Overloading.md deleted file mode 100644 index 923063273..000000000 --- a/docs/basic-dsa/Operator Overloading.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: basic dsa -title: Operator overloading -sidebar_label: Introduction to Operator Overloading -sidebar_position: 2 -description: 'Operator overloading allows you to redefine the way operators work for user-defined types (classes and structs). It enables you to specify more intuitive ways to perform operations on objects of your classes.' -tags: [dsa, data-structures, Operator Overloading] ---- - -## 2 Operator Overloading - -### Introduction - -Operator overloading allows you to redefine the way operators work for user-defined types (classes and structs). It enables you to specify more intuitive ways to perform operations on objects of your classes. - -Overloading an operator does not change: -- the operator precedence, -- the associativity of the operator, -- the arity of the operator, or -- the meaning of how the operator works on objects of -built-in types. - -### Syntax -An overloaded operator is implemented as a special member function with the keyword `operator` followed by the symbol of the operator being overloaded. - -```cpp -class ClassName { -public: - ReturnType operatorOpSymbol (ParameterList) { - // Function body - } -}; -``` -### Example -```cpp -class Complex { -public: - double real, imag; - Complex(double r = 0, double i = 0) : real(r), imag(i) {} - // Overload the + operator - Complex operator+ (Complex& obj) { - return Complex(real + obj.real, imag + obj.imag); - } -}; -``` - -### Types of Operators that Can Be Overloaded - -- Arithmetic operators: `+`, `-`, `*`, `/`, `%` -- Relational operators: `==`, `!=`, `<`, `>`, `<=`, `>=` -- Logical operators: `&&`, `||`, `!` -- Bitwise operators: `&`, `|`, `^`, `~`, `<<`, `>>` -- Increment and decrement operators: `++`, `--` -- Assignment operators: `=`, `+=`, `-=`, `*=`, `/=`, `%=` -- Subscript operator: `[]` -- Function call operator: `()` -- Member access operators: `->`, `.` (only for pointers to members) -- Input and output operators: `>>`, `<<` - -Operators that **cannot** be overloaded include: `::`, `.*`, `.`, `? :`, `sizeof` - -### Example: -```cpp -#include - -class Complex { -public: - double real, imag; - - Complex(double r = 0, double i = 0) : real(r), imag(i) {} - - // Overload the == operator - bool operator== (const Complex& obj) const { - return (real == obj.real && imag == obj.imag); - } -}; - -int main() { - Complex c1(3.0, 4.0), c2(3.0, 4.0); - if (c1 == c2) { - std::cout << "c1 and c2 are equal" << std::endl; - } else { - std::cout << "c1 and c2 are not equal" << std::endl; - } - return 0; -} -``` - -### Operator Overloading Rules - -When overloading operators, there are several rules to keep in mind: - -1. **Preserve the Operator's Original Meaning**: The overloaded operator should make sense in the context of the operation it performs. -2. **Return Types**: The return type should be appropriate for the operation. For example, `operator+` should return a new object, while `operator+=` should return a reference to `*this`. -3. **Symmetry**: Ensure symmetric behavior where applicable. For example, `a == b` should return the same result as `b == a`. -4. **Do Not Overload Operators Irrelevantly**: Only overload operators that make sense for your class. For example, overloading the arithmetic operators for a class that represents a complex number makes sense, but overloading them for a class that represents a database connection does not. diff --git a/docs/basic-dsa/Strings/Advanced-techniques.md b/docs/basic-dsa/Strings/Advanced-techniques.md deleted file mode 100644 index 26ce6c408..000000000 --- a/docs/basic-dsa/Strings/Advanced-techniques.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: advanced-string -title: "Advanced Strings" -sidebar_label: "Adv Strings" -sidebar_position: 4 -description: "StringBuilder is a mutable character sequence in Java that enables efficient modifications of strings without creating new objects, improving performance for dynamic string manipulation." -tags: [String Manipulation, StringBuilder, Java, Mutable Strings, Performance Optimization, Dynamic Text, Programming Concepts] ---- - -In addition to the basic string methods, several advanced topics and techniques can enhance your string manipulation skills in Java. - -## 1. StringBuilder and StringBuffer - -### StringBuilder -`StringBuilder` is a mutable sequence of characters. Unlike immutable strings, `StringBuilder` allows you to modify the character sequence without creating new objects. - -#### Example: -```java -StringBuilder sb = new StringBuilder("Hello"); -sb.append(" World"); -System.out.println(sb.toString()); // Output: Hello World -StringBuffer -StringBuffer is similar to StringBuilder, but it is synchronized, making it thread-safe. However, this comes at the cost of performance. - -Example: -```java - -StringBuffer sbf = new StringBuffer("Hello"); -sbf.append(" World"); -System.out.println(sbf.toString()); // Output: Hello World -``` -### 2. Regular Expressions -Java provides a powerful regular expression API through the java.util.regex package. Regular expressions allow you to perform complex string matching and manipulation tasks. - -Example: -```java - -import java.util.regex.*; - -String input = "Hello 123 World"; -Pattern pattern = Pattern.compile("\\d+"); -Matcher matcher = pattern.matcher(input); - -while (matcher.find()) { - System.out.println("Found: " + matcher.group()); // Output: Found: 123 -} -``` -### 3. String Interpolation (Java 15+) -With Java 15, you can use Text Blocks for multi-line string literals. While not exactly string interpolation, it simplifies the creation of multi-line strings. - -Example: -```java - -String text = """ - This is a text block - that spans multiple lines. - """; -System.out.println(text); -``` -## 4. Character Encoding -Understanding character encoding (e.g., UTF-8, UTF-16) is crucial for string manipulation, especially when dealing with internationalization or text files. - -Example: -```java - -byte[] bytes = "Hello".getBytes(StandardCharsets.UTF_8); -String s = new String(bytes, StandardCharsets.UTF_8); -System.out.println(s); // Output: Hello -``` -### 5. String Comparison -Understanding string comparison can help you avoid common pitfalls. Use equals() for content comparison and == for reference comparison. - -Example: -```java - -String s1 = new String("Hello"); -String s2 = new String("Hello"); - -System.out.println(s1 == s2); // Output: false (different objects) -System.out.println(s1.equals(s2)); // Output: true (same content) -``` -### 6. Advanced Searching and Sorting -You can implement advanced algorithms for searching (e.g., KMP, Rabin-Karp) and sorting strings based on specific criteria (e.g., alphabetical, length). - -Example of Sorting Strings: -```java - -String[] arr = {"Banana", "Apple", "Cherry"}; -Arrays.sort(arr); -System.out.println(Arrays.toString(arr)); // Output: [Apple, Banana, Cherry] -``` -### 7. String Manipulation with Streams (Java 8+) -You can use Java Streams to perform complex string manipulations in a functional style. - -## Example: -```java - -List strings = Arrays.asList("apple", "banana", "cherry"); -List uppercased = strings.stream() - .map(String::toUpperCase) - .collect(Collectors.toList()); -System.out.println(uppercased); // Output: [APPLE, BANANA, CHERRY] -``` -## Conclusion -Mastering these advanced string concepts will help you become more proficient in string manipulation in Java. Experiment with these techniques to see how they can enhance your applications. diff --git a/docs/basic-dsa/Strings/Highest freqyuency letter.md b/docs/basic-dsa/Strings/Highest freqyuency letter.md deleted file mode 100644 index 211da3b11..000000000 --- a/docs/basic-dsa/Strings/Highest freqyuency letter.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: highest-frequency-letter -title: "Finding letter with highest frequency in a string." -sidebar_label: "Highest frequency letter" -sidebar_position: 5 -description: "The frequency of a letter in a string refers to the number of times that particular letter appears within the string.In this blog we will learn how to find letter that appears largest number of times" -tags: [String, frequecy, Hashmap] ---- - - -# Find the Letter with the Highest Frequency in a String (Java) - -## Explanation - -- Imports: - -##### import java.util.HashMap: This imports the HashMap class, which is used to store letter frequencies. - -#### Finding the Highest Frequency Letter: - -- char highestLetter = ' '; : This initializes highestLetter to an empty character. -- int highestCount = 0; : This initializes highestCount to zero. -- for `(char letter : frequency.keySet()) { ... }`: This loop iterates over the keys (letters) in the frequency map. -- if `(frequency.get(letter) > highestCount) { ... }`: Inside the loop, this condition checks if the current letter’s frequency is greater than highestCount. If so, it updates highestCount and sets highestLetter to the current letter. - -#### Return Statement: - -return highestLetter;: Finally, the method returns the letter that has the highest frequency. - -The following Java code finds the letter with the highest frequency in a given string: - -```java -import java.util.HashMap; - -public class Main { - public static void main(String[] args) { - String input = "Hello, World!"; - char highestLetter = highestFrequencyLetter(input); - System.out.println("The letter with the highest frequency: " + highestLetter); - } - - public static char highestFrequencyLetter(String s) { - s = s.toLowerCase().replaceAll("[^a-z]", ""); // Convert to lowercase and filter non-alphabetic characters - HashMap frequency = new HashMap<>(); - - // Count frequency of each letter - for (char letter : s.toCharArray()) { - frequency.put(letter, frequency.getOrDefault(letter, 0) + 1); - } - - char highestLetter = ' '; - int highestCount = 0; - - // Find the letter with the highest frequency - for (char letter : frequency.keySet()) { - if (frequency.get(letter) > highestCount) { - highestCount = frequency.get(letter); - highestLetter = letter; - } - } - - return highestLetter; - } -} -``` - -# Find the Letter with the Highest Frequency in a String (C++) - -The following C++ code finds the letter with the highest frequency in a given string: - -```cpp -#include -#include -#include - -char highestFrequencyLetter(const std::string& s) { - std::unordered_map frequency; - - // Count frequency of each letter - for (char letter : s) { - if (std::isalpha(letter)) { // Check if the character is a letter - letter = std::tolower(letter); // Convert to lowercase - frequency[letter]++; - } - } - - char highestLetter = ' '; - int highestCount = 0; - - // Find the letter with the highest frequency - for (const auto& pair : frequency) { - if (pair.second > highestCount) { - highestCount = pair.second; - highestLetter = pair.first; - } - } - - return highestLetter; -} - -int main() { - std::string input = "Hello, World!"; - char letter = highestFrequencyLetter(input); - std::cout << "The letter with the highest frequency: " << letter << std::endl; - return 0; -} -``` - -# Find the Letter with the Highest Frequency in a String - -The following Python code finds the letter with the highest frequency in a given string: - -```python -def highest_frequency_letter(s): - # Convert the string to lowercase and filter out non-alphabetic characters - s = ''.join(filter(str.isalpha, s.lower())) - - # Create a frequency dictionary - frequency = {} - - for letter in s: - frequency[letter] = frequency.get(letter, 0) + 1 - - # Find the letter with the highest frequency - highest_letter = max(frequency, key=frequency.get) - highest_count = frequency[highest_letter] - - return highest_letter, highest_count - -# Example usage -input_string = "Hello, World!" -letter, count = highest_frequency_letter(input_string) -print(f"The letter '{letter}' has the highest frequency: {count}") - -``` - -# Find the Letter with the Highest Frequency in a String (JavaScript) - -```javascript -function highestFrequencyLetter(s) { - const frequency = {}; - - // Count frequency of each letter - for (const letter of s) { - if (/[a-zA-Z]/.test(letter)) { // Check if the character is a letter - const lowerLetter = letter.toLowerCase(); // Convert to lowercase - frequency[lowerLetter] = (frequency[lowerLetter] || 0) + 1; // Increment count - } - } - - let highestLetter = ' '; - let highestCount = 0; - - // Find the letter with the highest frequency - for (const [letter, count] of Object.entries(frequency)) { - if (count > highestCount) { - highestCount = count; - highestLetter = letter; - } - } - - return highestLetter; -} - -// Example usage -const input = "Hello, World!"; -const letter = highestFrequencyLetter(input); -console.log("The letter with the highest frequency:", letter); // Output the result -``` diff --git a/docs/basic-dsa/Strings/Isomorphic strings.md b/docs/basic-dsa/Strings/Isomorphic strings.md deleted file mode 100644 index 4668b2195..000000000 --- a/docs/basic-dsa/Strings/Isomorphic strings.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: isomorphic-strings -title: "What are isomorphic strings." -sidebar_label: "Isomorphic strings" -sidebar_position: 6 -description: "Isomorphic strings are two strings that can be transformed into each other by a consistent mapping of characters. " -tags: [String,isomorphic strings] ---- - -# Isomorphic Strings - -## Definition -Isomorphic strings are two strings that can be transformed into each other by a consistent mapping of characters. Each character in one string can be replaced with a character from the other string in a way that preserves the order of characters. - -### Example -- **Isomorphic**: "egg" and "add" -- **Not Isomorphic**: "foo" and "add" - -## Characteristics -- Each character must map to a unique character in the other string. -- The mapping must be consistent across the entire string. - -## Code Examples - -### Java - -```java -import java.util.HashMap; -import java.util.HashSet; - -public class IsomorphicStrings { - public static boolean areIsomorphic(String str1, String str2) { - if (str1.length() != str2.length()) { - return false; - } - - HashMap mapping = new HashMap<>(); - HashSet mappedChars = new HashSet<>(); - - for (int i = 0; i < str1.length(); i++) { - char char1 = str1.charAt(i); - char char2 = str2.charAt(i); - - if (mapping.containsKey(char1)) { - if (mapping.get(char1) != char2) { - return false; - } - } else { - if (mappedChars.contains(char2)) { - return false; - } - mapping.put(char1, char2); - mappedChars.add(char2); - } - } - - return true; - } - - public static void main(String[] args) { - String str1 = "egg"; - String str2 = "add"; - - if (areIsomorphic(str1, str2)) { - System.out.println("The strings are isomorphic."); - } else { - System.out.println("The strings are not isomorphic."); - } - } -} -``` - - -### C++ -```C++ -#include -#include -#include -#include - -bool areIsomorphic(const std::string& str1, const std::string& str2) { - if (str1.length() != str2.length()) { - return false; - } - - std::unordered_map mapping; - std::unordered_set mappedChars; - - for (size_t i = 0; i < str1.length(); ++i) { - char char1 = str1[i]; - char char2 = str2[i]; - - if (mapping.find(char1) != mapping.end()) { - if (mapping[char1] != char2) { - return false; - } - } else { - if (mappedChars.find(char2) != mappedChars.end()) { - return false; - } - - mapping[char1] = char2; - mappedChars.insert(char2); - } - } - - return true; -} - -int main() { - std::string str1 = "egg"; - std::string str2 = "add"; - - if (areIsomorphic(str1, str2)) { - std::cout << "The strings are isomorphic." << std::endl; - } else { - std::cout << "The strings are not isomorphic." << std::endl; - } - - return 0; -} -``` - -### Python -```Python - -def are_isomorphic(str1, str2): - if len(str1) != len(str2): - return False - - char_map = {} - mapped_chars = set() - - for char1, char2 in zip(str1, str2): - if char1 in char_map: - if char_map[char1] != char2: - return False - else: - if char2 in mapped_chars: - return False - - char_map[char1] = char2 - mapped_chars.add(char2) - - return True - -if __name__ == "__main__": - str1 = "egg" - str2 = "add" - - if are_isomorphic(str1, str2): - print("The strings are isomorphic.") - else: - print("The strings are not isomorphic.") -``` - -### JavaScript - -```javascript -function areIsomorphic(str1, str2) { - if (str1.length !== str2.length) { - return false; - } - - const mapping = new Map(); - const mappedChars = new Set(); - - for (let i = 0; i < str1.length; i++) { - const char1 = str1[i]; - const char2 = str2[i]; - - if (mapping.has(char1)) { - if (mapping.get(char1) !== char2) { - return false; - } - } else { - if (mappedChars.has(char2)) { - return false; - } - - mapping.set(char1, char2); - mappedChars.add(char2); - } - } - - return true; -} - -// Usage -const str1 = "egg"; -const str2 = "add"; - -if (areIsomorphic(str1, str2)) { - console.log("The strings are isomorphic."); -} else { - console.log("The strings are not isomorphic."); -} -``` diff --git a/docs/basic-dsa/Strings/Reversing a string.md b/docs/basic-dsa/Strings/Reversing a string.md deleted file mode 100644 index e6550a8dc..000000000 --- a/docs/basic-dsa/Strings/Reversing a string.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -id: reversing-a-string -title: "How to reverse the string?" -sidebar_label: "Reversing a string" -sidebar_position: 4 -description: "Reversing a string is the process of rearranging the characters in a string so that they appear in the opposite order." -tags: [String, reverse, inbuilt function, StringBuilder, Java, C++, Python, JavaScript] ---- - -## Description: -Reversing a string is the process of rearranging the characters in a string so that they appear in the opposite order. For example, if the original string is "Hello", the reversed string would be "olleH". This operation is commonly used in programming for tasks such as checking for palindromes, manipulating text, or preparing data for display. - -## Key Points -- Input: A string (e.g., "Hello, World!") -- Output: A new string with the characters in reverse order (e.g., "!dlroW ,olleH"). -- Methods: Reversing can be accomplished using various techniques, such as using built-in functions (like reverse() in many programming languages) or manually iterating through the string. - -Reversing a string is a fundamental operation in computer science and is often one of the first exercises for beginners in programming. - -# Reversing a String in Java - -In Java, you can reverse a string using various methods, including the `StringBuilder` class. Below is an example that demonstrates how to do this. - -## Example Code - -```java -public class StringReversal { - public static String reverseString(String str) { - // Create a StringBuilder with the original string - StringBuilder reversed = new StringBuilder(str); - - // Reverse the StringBuilder - reversed.reverse(); - - // Convert it back to a String and return - return reversed.toString(); - } - - public static void main(String[] args) { - String originalString = "Hello, World!"; - String reversed = reverseString(originalString); - System.out.println(reversed); // Output: "!dlroW ,olleH" - } -} -``` - -# Reversing a String in C++ - -Reversing a string in C++ involves rearranging its characters in the opposite order. This operation can be useful for various applications, including palindrome checks and string manipulations. - -## How to Reverse a String - -In C++, you can reverse a string using the `std::reverse` function from the `` header, or by manually swapping characters. - -### Using `std::reverse` - -The easiest way to reverse a string is to use the `std::reverse` function: - -1. **Include the Required Headers**: Include `` for input/output and `` for the `std::reverse` function. -2. **Call `std::reverse`**: Pass the beginning and end iterators of the string to `std::reverse`. - -### Example Code - -```cpp -#include -#include // For std::reverse -#include - -int main() { - std::string str = "Hello, World!"; - std::reverse(str.begin(), str.end()); - std::cout << str << std::endl; // Output: "!dlroW ,olleH" - return 0; -} -``` - -# Reversing a String in Python - -Reversing a string in Python involves rearranging its characters in the opposite order. This operation is useful for various applications, such as palindrome checks and string manipulations. - -## How to Reverse a String - -In Python, you can reverse a string using slicing, the `reversed()` function, or by using a loop. - -### Using Slicing - -The simplest way to reverse a string is by using Python's slicing feature. - -#### Example Code - -```python -# Reversing a string using slicing -original_string = "Hello, World!" -reversed_string = original_string[::-1] -print(reversed_string) # Output: "!dlroW ,olleH" -``` ---- - -## Reversing a String in JavaScript - -#### Method 1 -You can reverse a string in JavaScript by converting it into an array, using the `reverse` method, and then joining it back into a string. - -### Example Code - -```javascript -function reverseString(str) { - return str.split('') // Convert string to an array of characters - .reverse() // Reverse the array - .join(''); // Join the array back into a string -} - -const str = "Hello, World!"; -const reversedStr = reverseString(str); -console.log(reversedStr); // Output: "!dlroW ,olleH" -``` - -### Explanation - -1. **`split('')`**: This method splits the string into an array of characters. -2. **`reverse()`**: This method reverses the order of elements in the array. -3. **`join('')`**: This method joins the elements of the array back into a single string. - -You can use this `reverseString` function to reverse any string in JavaScript! - -#### Method 2 -To reverse a string in JavaScript without using any libraries, you can manually swap characters. For this go through the following code example: - -### Example Code - -```javascript -function reverseString(str) { - let reversed = ''; // Initialize an empty string to store the reversed result - for (let i = str.length - 1; i >= 0; i--) { // Start from the end of the string - reversed += str[i]; // Append each character to the reversed string - } - return reversed; // Return the reversed string -} - -const str = "Hello, World!"; -const reversedStr = reverseString(str); -console.log(reversedStr); // Output: "!dlroW ,olleH" -``` - -### Explanation - -1. **Initialization**: We initialize an empty string `reversed` to hold the reversed result. -2. **Loop**: We use a `for` loop that starts from the last character of the input string (`str.length - 1`) and decrements to `0`. -3. **Appending Characters**: In each iteration, we append the current character to the `reversed` string. -4. **Return**: Finally, we return the `reversed` string. - - diff --git a/docs/basic-dsa/Strings/What_is String.md b/docs/basic-dsa/Strings/What_is String.md deleted file mode 100644 index b8083e6b0..000000000 --- a/docs/basic-dsa/Strings/What_is String.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -id: What-is-String -title: "Strings" -sidebar_label: "What is Strings" -sidebar_position: 4 -description: "The KMP algorithm is an efficient method for substring searching in a string." -tags: [String Matching, kmp-algorithm, Substring Search, Algorithm, Pattern Matching] ---- -# Strings in Programming - -## What is a String? -A **string** is a sequence of characters, typically used to represent text. It can include letters, numbers, symbols, and whitespace. Strings are one of the most commonly used data types in programming, especially for tasks involving text manipulation, user input, and output. - -In most programming languages, strings are enclosed within quotes, either single (`'`) or double (`"`). The characters within the quotes form the actual content of the string. - -### Example: -```java -String greeting = "Hello, World!"; -``` -## String in Memory -In many programming languages, strings are stored as an array of characters (or a list of characters). Each character in the string corresponds to a specific position or index. - -For example, the string "Hello" is stored as: -Index: 0 1 2 3 4 Char : H e l l o -- **Indexing** starts from `0` in most languages. -- Each character is stored in contiguous memory locations. - -## String Operations - -### 1. Concatenation -Concatenation is the operation of joining two or more strings together to form a single string. - -```java -String part1 = "Hello"; -String part2 = "World"; -String fullGreeting = part1 + " " + part2; // Output: "Hello World" -``` -## 2. Accessing Characters -You can access individual characters in a string by using their index. - -```java -String text = "OpenAI"; -char firstLetter = text.charAt(0); // Output: 'O' -``` -## 3. Substring -Extracting a portion of a string is called substring. You can specify the starting and ending index to get part of a string. - -```java - -String text = "OpenAI"; -String subText = text.substring(0, 4); // Output: "Open" -``` -## 4. String Length -You can determine the length of a string (i.e., the number of characters it contains). - -```java - -String text = "OpenAI"; -int length = text.length(); // Output: 6 -``` -## 5. String Comparison -Strings can be compared to check whether they are equal or to compare them lexicographically (i.e., dictionary order). - -```java - -String str1 = "apple"; -String str2 = "banana"; -boolean isEqual = str1.equals(str2); // Output: false -int comparison = str1.compareTo(str2); // Output: -1 (because "apple" is lexicographically less than "banana") -``` -## 6. Changing Case -Strings can be converted to uppercase or lowercase. - -```java - -String text = "Hello"; -String upper = text.toUpperCase(); // Output: "HELLO" -String lower = text.toLowerCase(); // Output: "hello" -``` -## 7. Trimming -Whitespace can be removed from the beginning and end of a string using the trim method. - -```java -String text = " Hello "; -String trimmedText = text.trim(); // Output: "Hello" -``` - -## Immutable Nature of Strings -In many programming languages, strings are immutable, meaning once a string is created, it cannot be changed. Any operation that appears to modify a string actually creates a new string. - -Example: -```java - -String original = "OpenAI"; -original.concat(" Rocks!"); // This does not modify 'original' -System.out.println(original); // Output: "OpenAI" -``` -To actually change the content of the string, we need to assign the result to a new or the same variable: - -```java - -original = original.concat(" Rocks!"); -System.out.println(original); // Output: "OpenAI Rocks!" -``` - -## StringBuilder (Mutable Strings) -In some cases, you may need to modify strings frequently, which can be inefficient if strings are immutable. For such cases, many languages provide a mutable alternative to strings. For example, in Java, the StringBuilder class is used for this purpose. - -Example: -```java - -StringBuilder sb = new StringBuilder("Hello"); -sb.append(" World"); // Efficiently modifies the original string -System.out.println(sb.toString()); // Output: "Hello World" -``` -## String Methods - -Here are some commonly used string methods in various programming languages: - -| **Method** | **Description** | -|--------------------------|------------------------------------------------------| -| `length()` | Returns the length of the string | -| `charAt(index)` | Returns the character at the specified index | -| `substring(start, end)` | Returns a substring from the string | -| `equals(str)` | Compares two strings for equality | -| `toUpperCase()` | Converts the string to uppercase | -| `toLowerCase()` | Converts the string to lowercase | -| `trim()` | Removes leading and trailing spaces | -| `replace(oldChar, newChar)` | Replaces characters in the string | -| `split(delimiter)` | Splits the string based on a delimiter -## String Encoding -Strings are encoded using character encoding standards such as ASCII or UTF-8. This ensures that characters are stored as bytes that can be interpreted consistently across different systems. - -ASCII uses 7 bits to represent characters (128 unique characters). -UTF-8 is a more modern encoding that can represent a large variety of characters, including international ones. -### Conclusion - -Strings are fundamental to programming, providing a way to handle textual data. Understanding how to manipulate strings efficiently, especially when working with large datasets or performance-critical applications, is essential for developers. \ No newline at end of file diff --git a/docs/basic-dsa/Strings/kmp-algo.md b/docs/basic-dsa/Strings/kmp-algo.md deleted file mode 100644 index 7511b5946..000000000 --- a/docs/basic-dsa/Strings/kmp-algo.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: kmp-algorithm -title: "Knuth-Morris-Pratt (KMP) Algorithm" -sidebar_label: "KMP Algorithm" -sidebar_position: 4 -description: "The KMP algorithm is an efficient method for substring searching in a string." -tags: [String Matching, kmp-algorithm, Substring Search, Algorithm, Pattern Matching] ---- - -The Knuth-Morris-Pratt (KMP) algorithm is an efficient string-matching algorithm that searches for occurrences of a "pattern" string within a "text" string. It improves the search process by avoiding unnecessary comparisons, thus reducing the time complexity. - -## Introduction - -In traditional substring search algorithms, such as the naive approach, the time complexity can be as high as **O(n * m)**, where **n** is the length of the text and **m** is the length of the pattern. The KMP algorithm optimizes this by preprocessing the pattern to determine the longest prefix which is also a suffix, allowing it to skip unnecessary comparisons. - -## Characteristics of KMP Algorithm - -1. **Efficiency**: The KMP algorithm runs in **O(n + m)** time, making it much more efficient for longer texts and patterns. -2. **Preprocessing**: It preprocesses the pattern to create a longest prefix suffix (LPS) array, which guides the search process. -3. **No Backtracking**: Unlike naive algorithms, KMP does not backtrack the text pointer, ensuring a linear scan. - -## How KMP Algorithm Works - -1. **Preprocessing**: - - Create an LPS (Longest Prefix Suffix) array that holds the length of the longest proper prefix which is also a suffix for each prefix of the pattern. - - This array helps determine how many characters to skip when a mismatch occurs. - -2. **Searching**: - - Compare the characters of the text and pattern. - - If there is a match, move to the next character in both the text and pattern. - - If a mismatch occurs after some matches, use the LPS array to skip the necessary characters in the pattern without moving the text pointer backward. - -## Step-by-Step Execution - -Let's illustrate the KMP algorithm with a simple example: - -- **Text**: `ABABDABACDABABCABAB` -- **Pattern**: `ABABCABAB` - -### LPS Array Construction - -1. Initialize an LPS array for the pattern. -2. Fill the LPS array by tracking the longest prefix which is also a suffix. - -For the pattern `ABABCABAB`, the LPS array is constructed as follows: - -- `A`: 0 -- `AB`: 0 -- `ABA`: 1 -- `ABAB`: 2 -- `ABABC`: 0 -- `ABABCA`: 1 -- `ABABCAB`: 2 -- `ABABCABA`: 3 -- `ABABCABAB`: 4 - -The final LPS array is: `[0, 0, 1, 2, 0, 1, 2, 3, 4]`. - -### Searching Process - -1. Start with the text pointer and pattern pointer at the beginning. -2. Compare characters. If they match, move both pointers forward. -3. On a mismatch, use the LPS array to skip characters in the pattern. - -- Start: Text: `ABABDABACDABABCABAB`, Pattern: `ABABCABAB` -- Matches: `A`, `B`, `A` (text[0] to text[2]) -- Mismatch at text[3]: `D` (next pattern index from LPS is 2) -- Shift pattern by 2 positions based on LPS. - -Repeat the comparison until the end of the text. - -## Time Complexity - -- The KMP algorithm runs in **O(n + m)** time, where **n** is the length of the text and **m** is the length of the pattern. This efficiency is achieved due to the preprocessing step and the avoidance of backtracking. - -## Applications - -- **Text Searching**: Efficiently searching for a substring in a large text. -- **Data Mining**: Useful in pattern matching in databases and search engines. -- **Bioinformatics**: Searching DNA sequences for patterns. -- **Text Editors**: Used in find functionalities in text processing applications. - -## Pseudocode - -```python -def KMPSearch(text, pattern): - # Create LPS array - lps = computeLPSArray(pattern) - i = 0 # index for text - j = 0 # index for pattern - - while i < len(text): - if pattern[j] == text[i]: - i += 1 - j += 1 - - if j == len(pattern): - print("Pattern found at index " + str(i - j)) - j = lps[j - 1] - elif i < len(text) and pattern[j] != text[i]: - if j != 0: - j = lps[j - 1] - else: - i += 1 - -def computeLPSArray(pattern): - length = 0 # length of previous longest prefix suffix - lps = [0] * len(pattern) - i = 1 - - while i < len(pattern): - if pattern[i] == pattern[length]: - length += 1 - lps[i] = length - i += 1 - else: - if length != 0: - length = lps[length - 1] - else: - lps[i] = 0 - i += 1 - - return lps -``` -### Advantages of KMP Algorithm - -Optimal Time Complexity: The KMP algorithm efficiently handles pattern searching in linear time. -No Redundant Comparisons: Avoids unnecessary re-evaluation of characters in the text. -Flexible: Can be applied to various string processing applications. - -### Limitations -Space Complexity: Requires additional space for the LPS array, which may not be suitable for memory-constrained environments. -Preprocessing Overhead: The preprocessing step adds a minor overhead, which may not be beneficial for very short patterns or texts. - -### Conclusion -The Knuth-Morris-Pratt (KMP) algorithm is a powerful string-searching technique that optimizes the process of substring searching. Its linear time complexity and efficient handling of mismatches make it an essential algorithm in computer science and various practical applications. Understanding KMP allows developers to implement efficient pattern matching in string processing tasks. \ No newline at end of file diff --git a/docs/basic-dsa/_category_.json b/docs/basic-dsa/_category_.json deleted file mode 100644 index a02cc1bf2..000000000 --- a/docs/basic-dsa/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Basic Data Structures and Algorithms", - "position": 6, - "link": { - "type": "generated-index", - "description": "Learn the most important RoadMap for Basic Concepts of Data Structures and Algorithms." - } - } \ No newline at end of file diff --git a/docs/basic-dsa/array/2d-arrays.md b/docs/basic-dsa/array/2d-arrays.md deleted file mode 100644 index 1d8574acc..000000000 --- a/docs/basic-dsa/array/2d-arrays.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -id: two-dimensional-arrays-DSA -title: Two-Dimensional Arrays -sidebar_label: Two-Dimensional Arrays -sidebar_position: 5 -description: "In this blog post, we'll delve into the world of two-dimensional arrays, a vital data structure in programming. You'll learn what 2D arrays are, how to initialize and traverse them, and their common uses in real-world applications like matrix operations, image processing, and game boards. We'll also tackle classic algorithmic challenges involving 2D arrays, such as rotating a matrix and finding the largest sum subgrid. By the end, you'll have a solid understanding of how to effectively use 2D arrays to solve complex problems in your programming projects." -tags: [dsa, arrays, 2d arrays] ---- - -A two-dimensional (2D) array is an array of arrays, where each element of the main array is another array. It's often visualized as a table or matrix with rows and columns. Two-dimensional arrays are essential in various algorithmic problems, particularly when handling matrices, grids, and dynamic programming solutions. - -In this guide, we will cover the fundamentals of two-dimensional arrays, their applications, and common operations used in data structures and algorithms (DSA). - -## 1. What is a Two-Dimensional Array? - -A two-dimensional array is an array that consists of a collection of elements arranged in rows and columns. Each element can be accessed using two indices – one representing the row and the other representing the column. - -### Representation: - -- A two-dimensional array can be visualized as: - ```plaintext - [a11, a12, a13] - [a21, a22, a23] - [a31, a32, a33] - ``` - -Here, each row is an individual array, and all rows combined form the 2D array. - -## 2. Declaration and Initialization of 2D Arrays - -### Declaration: - -In most programming languages, a 2D array is declared by specifying the number of rows and columns. For example, in C++: - -```cpp title="C++" -int arr[3][4]; // Declares a 2D array with 3 rows and 4 columns -``` - -In Python, a 2D array can be initialized using nested lists: - -```python title="Python" -arr = [[0] * 4 for _ in range(3)] # Creates a 3x4 matrix filled with zeros -``` - -### Initialization: - -2D arrays can be initialized at the time of declaration: - -```cpp title="C++" -int arr[2][3] = { - {1, 2, 3}, - {4, 5, 6} -}; -``` - -## 3. Accessing and Modifying Elements in a 2D Array - -Each element in a 2D array is accessed using two indices – the first for the row and the second for the column. - -### Example: - -```cpp -int element = arr[1][2]; // Accesses the element at row 1, column 2 -arr[0][1] = 10; // Modifies the element at row 0, column 1 -``` - -In Python: - -```python -element = arr[1][2] -arr[0][1] = 10 -``` - -## 4. Traversing a 2D Array - -Traversing a 2D array involves visiting each element of the array. Typically, this is done using nested loops, where the outer loop iterates over the rows, and the inner loop iterates over the columns. - -### Example in C++: - -```cpp -for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - cout << arr[i][j] << " "; - } - cout << endl; -} -``` - -### Example in Python: - -```python -for row in arr: - for element in row: - print(element, end=" ") - print() -``` - ---- - -## 5. Common Operations on 2D Arrays - -### a. Matrix Addition - -Two matrices of the same dimensions can be added element-wise. - -```cpp -for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - result[i][j] = matrix1[i][j] + matrix2[i][j]; - } -} -``` - -### b. Matrix Multiplication - -Matrix multiplication is performed by multiplying the rows of the first matrix by the columns of the second matrix. - -```cpp -for (int i = 0; i < rowsA; i++) { - for (int j = 0; j < colsB; j++) { - result[i][j] = 0; - for (int k = 0; k < colsA; k++) { - result[i][j] += matrixA[i][k] * matrixB[k][j]; - } - } -} -``` - -### c. Transposing a Matrix - -Transposing a matrix involves flipping its rows and columns. - -```cpp -for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - transpose[j][i] = matrix[i][j]; - } -} -``` - ---- - -## 6. Applications of 2D Arrays in DSA - -- **Dynamic Programming**: Many DP problems such as "Knapsack", "Longest Common Subsequence", and "Edit Distance" utilize 2D arrays to store solutions to subproblems. -- **Graph Representation**: Adjacency matrices use 2D arrays to represent graphs. -- **Image Processing**: A grayscale image can be represented as a 2D array of pixel intensities. -- **Game Boards**: Games like chess and tic-tac-toe use 2D arrays to represent the game board. -- **Mathematical Operations**: Matrix operations like addition, multiplication, and transposition are fundamental in linear algebra and often implemented using 2D arrays. - ---- - -## 7. Example Problems - -### Problem 1: Rotating a Matrix by 90 Degrees - -Given a `n x n` matrix, rotate the matrix by 90 degrees clockwise. - -### Problem 2: Spiral Matrix Traversal - -Given a matrix, print the elements in a spiral order starting from the top-left corner. - -### Problem 3: Find the Largest Island - -Given a binary matrix where `1` represents land and `0` represents water, find the largest connected land mass (island). - -### Problem 4: Matrix Multiplication - -Write a program to multiply two matrices of dimensions `m x n` and `n x p`. - ---- - -## Conclusion - -Two-dimensional arrays are a foundational data structure in computer science, used in a variety of real-world applications, including graph theory, dynamic programming, and game development. By understanding how to declare, traverse, and manipulate 2D arrays, you can effectively solve complex problems in DSA. diff --git a/docs/basic-dsa/array/Kadane-Algorithm.md b/docs/basic-dsa/array/Kadane-Algorithm.md deleted file mode 100644 index 75f41b4a7..000000000 --- a/docs/basic-dsa/array/Kadane-Algorithm.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: introduction-to-Arrays -title: Kadane's Algorithm -sidebar_label: Introduction to Kadane's Algorithm -sidebar_position: 1 -description: Kadane's Algorithm is an efficient technique used to find the maximum sum of a contiguous subarray within a one-dimensional array of integers. It is particularly useful in scenarios where the input array may contain both positive and negative numbers. By leveraging a dynamic programming approach, Kadane's Algorithm can identify the maximum sum in linear time, making it optimal for large datasets. - -tags: [basic-dsa, data-structures,Kadane's Algorithm] ---- - - -### Defination: - -Kadane's Algorithm is an efficient technique used to find the maximum sum of a contiguous subarray within a one-dimensional array of integers. It is particularly useful in scenarios where the input array may contain both positive and negative numbers. By leveraging a dynamic programming approach, Kadane's Algorithm can identify the maximum sum in linear time, making it optimal for large datasets. - -### Characteristics: - -- **Dynamic Programming Approach**: -- Kadane's algorithm builds up the solution by maintaining the maximum subarray sum that ends at each position in the array, allowing for efficient computation of the overall maximum. - -- **Iterative Process**: -- The algorithm iterates through the array, updating the maximum sum and tracking the current subarray sum as it progresses. - -- **Handles Negative Numbers**: -- Kadane's algorithm can handle arrays with negative numbers effectively, ensuring that the maximum subarray can still be found even if all elements are negative. - --**Optimal Substructure**: -The solution to the problem can be constructed efficiently from solutions to subproblems, making it suitable for dynamic programming. - -### Time Complexity: - -- **Best, Average, and Worst Case: O(N)** - - Kadane's algorithm processes each element of the array once, resulting in a linear time complexity, where n is the number of elements in the array. - -- **Space Complexity: O(1)** -- The algorithm uses a constant amount of space to store a few variables, making it highly space-efficient. - - -### C++ Implementation: - -```cpp -#include -#include -using namespace std; - -int kadane(const vector& nums) { - int max_so_far = nums[0]; - int current_max = nums[0]; - - for (size_t i = 1; i < nums.size(); i++) { - current_max = max(nums[i], current_max + nums[i]); - max_so_far = max(max_so_far, current_max); - } - - return max_so_far; -} - -int main() { - vector nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; - - int max_sum = kadane(nums); - cout << "Maximum sum of the contiguous subarray: " << max_sum << endl; - - return 0; -} - -``` - -### JAVA Implementation: - -```java -public class KadaneAlgorithm { - - public static int kadane(int[] nums) { - int maxSoFar = nums[0]; - int currentMax = nums[0]; - - for (int i = 1; i < nums.length; i++) { - currentMax = Math.max(nums[i], currentMax + nums[i]); - maxSoFar = Math.max(maxSoFar, currentMax); - } - - return maxSoFar; - } - - public static void main(String[] args) { - int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; - - int maxSum = kadane(nums); - System.out.println("Maximum sum of the contiguous subarray: " + maxSum); - } -} - -``` - -### Python Implementation: -```py -def kadane(nums): - max_so_far = nums[0] - current_max = nums[0] - - for i in range(1, len(nums)): - current_max = max(nums[i], current_max + nums[i]) - max_so_far = max(max_so_far, current_max) - - return max_so_far - -if __name__ == "__main__": - nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] - - max_sum = kadane(nums) - print("Maximum sum of the contiguous subarray:", max_sum) - -``` - -### JavaScript Code Implementation - -```javascript -function kadane(nums) { - let maxSoFar = nums[0]; - let currentMax = nums[0]; - - for (let i = 1; i < nums.length; i++) { - currentMax = Math.max(nums[i], currentMax + nums[i]); - maxSoFar = Math.max(maxSoFar, currentMax); - } - - return maxSoFar; -} - -// Example usage -const nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]; -const maxSum = kadane(nums); -console.log("Maximum sum of the contiguous subarray:", maxSum); -``` - -### Explanation of the Code - -1. **`kadane` Function**: - - Takes an array of numbers (`nums`) as input. - - Initializes two variables, `maxSoFar` and `currentMax`, with the first element of the array. - - Loops through the array starting from the second element: - - Updates `currentMax` to be the maximum of the current element or the sum of `currentMax` and the current element. - - Updates `maxSoFar` to keep track of the maximum sum found so far. - - Returns `maxSoFar` after completing the loop. - -2. **Example Usage**: - - An example array of integers is provided. - - The function is called, and the maximum sum of the contiguous subarray is printed to the console. - - -### Summary: - -Kadane's algorithm provides an efficient way to determine the maximum sum of a contiguous subarray within an array of numbers. By using a dynamic programming approach, it ensures optimal performance with a linear time complexity and constant space requirements. This algorithm is widely applicable in various fields, particularly in financial analysis and signal processing. diff --git a/docs/basic-dsa/array/ProudctOfArrayExceptSelf.md b/docs/basic-dsa/array/ProudctOfArrayExceptSelf.md deleted file mode 100644 index 9b3a6ec06..000000000 --- a/docs/basic-dsa/array/ProudctOfArrayExceptSelf.md +++ /dev/null @@ -1,287 +0,0 @@ ---- -id: arrays-product-of-array-except-self -title: Arrays - Product of Array Except Self -sidebar_label: Product of Array Except Self -sidebar_position: 3 -description: "The Product of Array Except Self problem requires calculating the product of all elements in an array except for the element at the current index. The challenge is to perform this without using division and in O(n) time complexity." -tags: [dsa, arrays, product-of-array, pseudocode, Implementation, explanation, conclusion] ---- - - - -## Product of Array Except Self - -The **Product of Array Except Self** problem involves computing an output array such that `output[i]` is equal to the product of all the elements of the input array except for `input[i]`. - -### Problem Statement - -Given an array `nums` of length `n`, return an array `output` of the same length where `output[i]` is equal to the product of all the numbers in the input array except `nums[i]`. - -### Constraints -- You must solve it in O(n) time complexity. -- You cannot use the division operation. - - - -## Algorithm - -1. Create an output array of the same length as `nums`. -2. Initialize a variable `left` to 1. -3. Populate the output array with the product of all elements to the left of each index. -4. Initialize another variable `right` to 1. -5. Populate the output array with the product of all elements to the right of each index. -6. Return the output array. - -## Pseudocode - -```plaintext title="Product of Array Except Self" -procedure productExceptSelf( nums : list of integers ) - n = length(nums) - output = array of size n - - left = 1 - for i = 0 to n - 1 do - output[i] = left - left *= nums[i] - - right = 1 - for i = n - 1 down to 0 do - output[i] *= right - right *= nums[i] - - return output -end procedure - - -``` - -### C++ Implementation: - -```cpp - -// Product of Array Except Self -#include -#include -using namespace std; - -vector sum(vector &arr) -{ - int n = arr.size(); - vector ans(n, 1); // Initialize ans array with 1's. - - // Calculate prefix products - for (int i = 1; i < n; i++) - { - ans[i] = ans[i - 1] * arr[i - 1]; // ans[i] is the product of all elements before arr[i]. - } - - int suffix = 1; // Initialize suffix product. - // Calculate suffix products and multiply with prefix products - for (int i = n - 2; i >= 0; i--) - { - suffix *= arr[i + 1]; // Update suffix to be the product of elements after arr[i]. - ans[i] *= suffix; // Multiply the current ans[i] (prefix product) by the suffix product. - } - return ans; -} - -// Main Function -int main() -{ - vector arr = {1, 2, 3, 4}; - vector res = sum(arr); // calling function - for (int val : res) - { - cout << val << " "; - } - return 0; -} - -``` - -### JAVA Implementation: - -```java - -public class ProductExceptSelf { - public static int[] productExceptSelf(int[] nums) { - int n = nums.length; - int[] output = new int[n]; - - // Step 1: Calculate prefix products - output[0] = 1; // The first prefix product is always 1 - for (int i = 1; i < n; i++) { - output[i] = output[i - 1] * nums[i - 1]; - } - // Step 2: Calculate suffix products and multiply with prefix - int suffix = 1; - for (int i = n - 1; i >= 0; i--) { - output[i] *= suffix; - suffix *= nums[i]; - } - return output; - } - - public static void main(String[] args) { - int[] nums = {1, 2, 3, 4}; - int[] result = productExceptSelf(nums); - for (int value : result) { - System.out.print(value + " "); // Output: 24 12 8 6 - } - } -} - -``` - -### Python Implementation: -```py - -def product_except_self(nums): - n = len(nums) - output = [1] * n - - # Step 1: Calculate prefix products - for i in range(1, n): - output[i] = output[i - 1] * nums[i - 1] - - # Step 2: Calculate suffix products and multiply with prefix - suffix = 1 - for i in range(n - 1, -1, -1): - output[i] *= suffix - suffix *= nums[i] - - return output - -# Example usage -nums = [1, 2, 3, 4] -result = product_except_self(nums) -print(result) # Output: [24, 12, 8, 6] - -``` - - -### JavaScript Code Implementation - -```javascript -function productExceptSelf(arr) { - const n = arr.length; - const ans = new Array(n).fill(1); // Initialize ans array with 1's. - - // Calculate prefix products - for (let i = 1; i < n; i++) { - ans[i] = ans[i - 1] * arr[i - 1]; // ans[i] is the product of all elements before arr[i]. - } - - let suffix = 1; // Initialize suffix product. - // Calculate suffix products and multiply with prefix products - for (let i = n - 2; i >= 0; i--) { - suffix *= arr[i + 1]; // Update suffix to be the product of elements after arr[i]. - ans[i] *= suffix; // Multiply the current ans[i] (prefix product) by the suffix product. - } - - return ans; -} - -// Example usage -const arr = [1, 2, 3, 4]; -const res = productExceptSelf(arr); // calling function -console.log(res.join(" ")); // Output the result -``` - -## Complexity - -- **Time Complexity**: O(n) -- **Space Complexity**: O(1) if we use the output array directly for left and right products (optimized version). - -> **Note**: The above implementation uses O(n) space for the output array. - -## Explanation - -To find the output array where each element at index `i` is the product of all the numbers in the input array except the one at `i`, we can utilize prefix and suffix products. - -### Step-by-step Breakdown - -1. **Initial Array**: - We start with the input array: - `[1, 2, 3, 4]` - -2. **Calculate Prefix Products**: - - We create an output array initialized with 1's: - `output = [1, 1, 1, 1]` - - The prefix product at each index is calculated as follows: - - For index 0: - `output[0] = 1` (no elements to the left) - - For index 1: - `output[1] = output[0] * 1 = 1 * 1 = 1` - - For index 2: - `output[2] = output[1] * 2 = 1 * 2 = 2` - - For index 3: - `output[3] = output[2] * 3 = 2 * 3 = 6` - - After calculating the prefix products, we get: - `output = [1, 1, 2, 6]` - -3. **Calculate Suffix Products**: - - We now iterate from the end of the array to the beginning to calculate the suffix products: - - Initialize a variable for the suffix product: - - `suffix = 1` - - Update the output array while multiplying by the suffix product: - - For index 3: - `output[3] = output[3] * suffix = 6 * 1 = 6` - Update suffix: `suffix = suffix * 4 = 4` - - For index 2: - `output[2] = output[2] * suffix = 2 * 4 = 8` - Update suffix: `suffix = suffix * 3 = 12` - - For index 1: - `output[1] = output[1] * suffix = 1 * 12 = 12` - Update suffix: `suffix = suffix * 2 = 24` - - For index 0: - `output[0] = output[0] * suffix = 1 * 24 = 24` - Update suffix: `suffix = suffix * 1 = 24` - - After calculating the suffix products, we get: - `output = [24, 12, 8, 6]` - -### Final Output - -Thus, the output for the input array `[1, 2, 3, 4]` is: -`[24, 12, 8, 6]` - -- `output[0] = 2 * 3 * 4 = 24` -- `output[1] = 1 * 3 * 4 = 12` -- `output[2] = 1 * 2 * 4 = 8` -- `output[3] = 1 * 2 * 3 = 6` - - -### Note - -This problem is commonly asked in coding interviews and is a great way to understand how to manipulate arrays without using division. - -:::info -**Try it yourself:** Change the array values and see how the output array changes based on the product of the other elements. -::: - - - -## Conclusion - -The **Product of Array Except Self** problem showcases a fundamental approach in algorithm design where efficient solutions can be derived through thoughtful manipulation of arrays. By utilizing the concept of prefix and suffix products, we can compute the desired output without resorting to division, which can often complicate matters when dealing with zeroes or other special cases in arrays. - -### Key Takeaways: - -1. **Efficiency**: The algorithm operates in O(n) time complexity, making it highly efficient even for larger datasets. The use of a single pass to compute both prefix and suffix products illustrates how to leverage iterative techniques to minimize computational overhead. - -2. **Space Optimization**: While the naive approach might suggest using additional arrays for prefix and suffix products, this solution elegantly maintains a single output array, thereby achieving O(1) space complexity in terms of auxiliary space. This is crucial in scenarios where memory usage is a concern. - -3. **Versatility**: This problem serves as a great illustration of how array manipulation can be utilized in various applications, from statistical calculations to financial analyses. Understanding this algorithm equips developers with the ability to tackle a range of similar challenges effectively. - -4. **Practical Applications**: The principles demonstrated in this algorithm can be extended to various real-world applications, such as calculating cumulative products in datasets, performance analysis, and even in fields like signal processing where such operations are commonplace. - -In summary, mastering the **Product of Array Except Self** problem not only enhances one’s problem-solving skills but also lays the groundwork for tackling more complex algorithmic challenges involving arrays and other data structures. - -## References - -- [LeetCode](https://leetcode.com/problems/product-of-array-except-self/) -- [GeeksforGeeks](https://www.geeksforgeeks.org/problems/product-array-puzzle4525/1) - - diff --git a/docs/basic-dsa/array/_category_.json b/docs/basic-dsa/array/_category_.json deleted file mode 100644 index bf5d0b724..000000000 --- a/docs/basic-dsa/array/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Arrays", - "position": 1, - "link": { - "type": "generated-index", - "description": "Learn the most important concepts of Arrays." - } - } \ No newline at end of file diff --git a/docs/basic-dsa/array/arrays-bubblesort-dsa.md b/docs/basic-dsa/array/arrays-bubblesort-dsa.md deleted file mode 100644 index fb55fc361..000000000 --- a/docs/basic-dsa/array/arrays-bubblesort-dsa.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -id: arrays-bubblesort-in-dsa -title: Arrays - Bubble Sort in DSA -sidebar_label: Bubble Sort -sidebar_position: 2 -description: "Bubble Sort is a simple sorting algorithm that repeatedly steps through the list, compares adjacent elements and swaps them if they are in the wrong order. The pass through the list is repeated until the list is sorted. The algorithm, which is a comparison sort, is named for the way smaller elements 'bubble' to the top of the list. Although the algorithm is simple, it is too slow and impractical for most problems even when compared to insertion sort. It can be practical if the input is usually in sort order but may occasionally have some out-of-order elements nearly in position." -tags: [dsa, arrays, sorting, bubble-sort, algorithm of bubble-sort, pseudocode of bubble-sort, complexity of bubble-sort, example of bubble-sort, live example of bubble-sort, explanation of bubble-sort, quiz of bubble-sort, conclusion of bubble-sort] ---- - - - -**Bubble Sort** is a simple sorting algorithm that repeatedly steps through the list, compares adjacent elements and swaps them if they are in the wrong order. The pass through the list is repeated until the list is sorted. The algorithm, which is a comparison sort, is named for the way smaller elements bubble to the top of the list. Although the algorithm is simple, it is too slow and impractical for most problems even when compared to insertion sort. It can be practical if the input is usually in sorted order but may occasionally have some out-of-order elements nearly in position. - - - - -## Algorithm - -1. Start from the first element, compare the current element with the next element of the array. -2. If the current element is greater than the next element of the array, swap them. -3. If the current element is less than the next element, move to the next element. -4. Repeat steps 1-3 until the array is sorted. -5. The array is sorted. -6. Exit. -7. The time complexity of the bubble sort is O(n2). -8. The space complexity of the bubble sort is O(1). - -## Pseudocode - -```plaintext title="Bubble Sort" -procedure bubbleSort( A : list of sortable items ) - n = length(A) - repeat - swapped = false - for i = 1 to n-1 inclusive do - if A[i-1] > A[i] then - swap(A[i-1], A[i]) - swapped = true - end if - end for - until not swapped -end procedure -``` - - - -## Diagram - -```mermaid -graph TD - A([Start]) --> B("i = 0") - B --> C{"i < n-1"} - C -->|True| D("j = 0") - D --> E{"j < n - i - 1"} - E -->|True| F{arr j > arr j+1} - F -->|True| G{Swap arr j, arr j+1 } - G --> H{Increment j} - H --> |j++| D - F -->|False| I{Increment j} - I --> |j++| D - E --> |false i++| C - D --> |False| J{Increment i} - J --> |i++| C - C -->|False| K(Sorted Array) - K --> L([Stop]) - -``` - -## Example - -```js title="Bubble Sort" -function bubbleSort(arr) { - let n = arr.length; - let swapped; - do { - swapped = false; - for (let i = 0; i < n - 1; i++) { - if (arr[i] > arr[i + 1]) { - let temp = arr[i]; - arr[i] = arr[i + 1]; - arr[i + 1] = temp; - swapped = true; - } - } - } while (swapped); - return arr; -} - -let arr = [64, 34, 25, 12, 22, 11, 90]; -console.log(bubbleSort(arr)); // [ 11, 12, 22, 25, 34, 64, 90 ] -``` - -## Complexity - -- **Time Complexity**: O(n2) - - Best Case: O(n) - - Average Case: O(n2) - - Worst Case: O(n2) -- **Space Complexity**: O(1) -- **Stable**: Yes - -## Live Example - -```js live -function bubbleSort() { - let arr = [64, 34, 25, 12, 22, 11, 90]; - let n = arr.length; - - for (let i = 0; i < n; i++) { - for (let j = 0; j < n - i - 1; j++) { - if (arr[j] > arr[j + 1]) { - let temp = arr[j]; - arr[j] = arr[j + 1]; - arr[j + 1] = temp; - } - } - } - - return ( -

    - ) -} -``` - -## Explanation - -In the above example, we have an array of numbers `[64, 34, 25, 12, 22, 11, 90]`. We are using the bubble sort algorithm to sort the array in ascending order. The bubble sort algorithm compares each pair of adjacent items and swaps them if they are in the wrong order. The algorithm repeats this process until the array is sorted. The sorted array is `[11, 12, 22, 25, 34, 64, 90]`. The time complexity of the bubble sort is O(n2) and the space complexity is O(1). - -:::info Try it yourself -Change the array values and see how the bubble sort algorithm sorts the array. -::: - - - -:::tip 📝 Note -Bubble sort is not a practical sorting algorithm when the input is large. It is not suitable for large datasets due to its O(n2) time complexity. - -The main advantage of bubble sort is that it is easy to understand and implement. It is often used to teach the concept of sorting algorithms. - -Bubble sort is stable, meaning that it preserves the relative order of equal elements. - -Bubble sort is not an efficient algorithm for large datasets and is generally not used in practice. - -::: - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Bubble_sort) -- [GeeksforGeeks](https://www.geeksforgeeks.org/bubble-sort/) -- [Programiz](https://www.programiz.com/dsa/bubble-sort) -- [TutorialsPoint](https://www.tutorialspoint.com/data_structures_algorithms/bubble_sort_algorithm.htm) -- [StudyTonight](https://www.studytonight.com/data-structures/bubble-sort) -- [w3schools](https://www.w3schools.com/dsa/dsa_algo_bubblesort.php) - -## Related - -Insertion Sort, Selection Sort, Merge Sort, Quick Sort, etc. - - - -## Quiz - -1. What is the time complexity of the bubble sort algorithm? - - [ ] O(n) - - [x] O(n2) ✔ - - [ ] O(log n) - - [ ] O(n!) - -2. Is bubble sort a stable sorting algorithm? - - [x] Yes ✔ - - [ ] No - - [ ] Maybe - - [ ] Not sure - -3. What is the space complexity of the bubble sort algorithm? - - [ ] O(n) - - [x] O(1) ✔ - - [ ] O(log n) - - [ ] O(n!) - -4. What is the main advantage of bubble sort? - - [ ] It is the fastest sorting algorithm - - [x] It is easy to understand and implement ✔ - - [ ] It is suitable for large datasets - - [ ] It is used in practice - -5. What is the main disadvantage of bubble sort? - - [ ] It is the fastest sorting algorithm - - [ ] It is easy to understand and implement - - [x] It is not suitable for large datasets ✔ - - [ ] It is used in practice - -## Conclusion - -In this tutorial, we learned about the bubble sort algorithm. We discussed the algorithm, pseudocode, diagram, example, complexity, and related concepts. We also implemented the bubble sort algorithm in JavaScript and saw a live example. We also discussed the advantages and disadvantages of the bubble sort algorithm. We hope you enjoyed this tutorial and found it helpful. Feel free to share your thoughts in the comments below. \ No newline at end of file diff --git a/docs/basic-dsa/array/arrays-dsa.md b/docs/basic-dsa/array/arrays-dsa.md deleted file mode 100644 index 931a72bf8..000000000 --- a/docs/basic-dsa/array/arrays-dsa.md +++ /dev/null @@ -1,543 +0,0 @@ ---- -id: arrays-in-dsa -title: Arrays in Data Structures and Algorithms -sidebar_label: Arrays -sidebar_position: 1 -description: "An array is a collection of items stored at contiguous memory locations. It is a data structure that stores a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type." -tags: [dsa, data-structures, arrays, array, array-data-structure, array-in-dsa, array-in-data-structure, array-in-algorithm, array-in-dsa-example, array-in-dsa-explanation, array-in-dsa-conclusion, array-in-dsa-importance, array-in-dsa-syntax, array-in-dsa-declaration, array-in-dsa-access, array-in-dsa-update, array-in-dsa-length, array-in-dsa-iterate, array-in-dsa-max-min, array-in-dsa-program, array-in-dsa-code, array-in-dsa-js, array-in-dsa-java, array-in-dsa-python, array-in-dsa-c, array-in-dsa-cpp, array-in-dsa-ts] ---- - -An array is a collection of items stored at contiguous memory locations. It is a data structure that stores a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type. - -## Visualizations of Arrays in Data Structures and Algorithms (DSA) - - - -## Why are Arrays important? - -Arrays are important because they allow us to store multiple items of the same type in a single variable. They are used to store data in a structured way, and they are used in many algorithms and data structures. - -## How to declare an Array? - -An array can be declared in various programming languages using the following syntax: - - - - - ```js - // Declare an array in JavaScript - let arr = [1, 2, 3, 4, 5]; - ``` - - - - ```java - // Declare an array in Java - int[] arr = {1, 2, 3, 4, 5}; - ``` - - - - ```python - # Declare an array in Python - arr = [1, 2, 3, 4, 5] - ``` - - - - ```c - // Declare an array in C - int arr[] = {1, 2, 3, 4, 5}; - ``` - - - - ```cpp - // Declare an array in C++ - int arr[] = {1, 2, 3, 4, 5}; - ``` - - - - ```ts - // Declare an array in TypeScript - let arr: number[] = [1, 2, 3, 4, 5]; - ``` - - - -## How to access an Array? - -An array can be accessed using the index of the element. The index of the first element is 0, the index of the second element is 1, and so on. - - - - - ```js - // Access an array in JavaScript - let arr = [1, 2, 3, 4, 5]; - console.log(arr[0]); // 1 - console.log(arr[1]); // 2 - console.log(arr[2]); // 3 - console.log(arr[3]); // 4 - console.log(arr[4]); // 5 - ``` - - - - ```java - // Access an array in Java - int[] arr = {1, 2, 3, 4, 5}; - System.out.println(arr[0]); // 1 - System.out.println(arr[1]); // 2 - System.out.println(arr[2]); // 3 - System.out.println(arr[3]); // 4 - System.out.println(arr[4]); // 5 - ``` - - - - ```python - # Access an array in Python - arr = [1, 2, 3, 4, 5] - print(arr[0]) # 1 - print(arr[1]) # 2 - print(arr[2]) # 3 - print(arr[3]) # 4 - print(arr[4]) # 5 - ``` - - - - ```c - // Access an array in C - int arr[] = {1, 2, 3, 4, 5}; - printf("%d\n", arr[0]); // 1 - printf("%d\n", arr[1]); // 2 - printf("%d\n", arr[2]); // 3 - printf("%d\n", arr[3]); // 4 - printf("%d\n", arr[4]); // 5 - ``` - - - - ```cpp - // Access an array in C++ - int arr[] = {1, 2, 3, 4, 5}; - cout << arr[0] << endl; // 1 - cout << arr[1] << endl; // 2 - cout << arr[2] << endl; // 3 - cout << arr[3] << endl; // 4 - cout << arr[4] << endl; // 5 - ``` - - - - ```ts - // Access an array in TypeScript - let arr: number[] = [1, 2, 3, 4, 5]; - console.log(arr[0]); // 1 - console.log(arr[1]); // 2 - console.log(arr[2]); // 3 - console.log(arr[3]); // 4 - console.log(arr[4]); // 5 - ``` - - - -## How to update an Array? - -An array can be updated by assigning a new value to the index of the element. - - - - - ```js - // Update an array in JavaScript - let arr = [1, 2, 3, 4, 5]; - arr[0] = 10; - console.log(arr); // [10, 2, 3, 4, 5] - ``` - - - - ```java - // Update an array in Java - int[] arr = {1, 2, 3, 4, 5}; - arr[0] = 10; - System.out.println(Arrays.toString(arr)); // [10, 2, 3, 4, 5] - ``` - - - - ```python - # Update an array in Python - arr = [1, 2, 3, 4, 5] - arr[0] = 10 - print(arr) # [10, 2, 3, 4, 5] - ``` - - - - ```c - // Update an array in C - int arr[] = {1, 2, 3, 4, 5}; - arr[0] = 10; - for (int i = 0; i < 5; i++) { - printf("%d ", arr[i]); - } - // 10 2 3 4 5 - ``` - - - - ```cpp - // Update an array in C++ - int arr[] = {1, 2, 3, 4, 5}; - arr[0] = 10; - for (int i = 0; i < 5; i++) { - cout << arr[i] << " "; - } - // 10 2 3 4 5 - ``` - - - - ```ts - // Update an array in TypeScript - let arr: number[] = [1, 2, 3, 4, 5]; - arr[0] = 10; - console.log(arr); // [10, 2, 3, 4, 5] - ``` - - - -## How to find the length of an Array? - -The length of an array can be found using the `length` property. - - - - - ```js - // Find the length of an array in JavaScript - let arr = [1, 2, 3, 4, 5]; - console.log(arr.length); // 5 - ``` - - - - ```java - // Find the length of an array in Java - int[] arr = {1, 2, 3, 4, 5}; - System.out.println(arr.length); // 5 - ``` - - - - ```python - # Find the length of an array in Python - arr = [1, 2, 3, 4, 5] - print(len(arr)) # 5 - ``` - - - - ```c - // Find the length of an array in C - int arr[] = {1, 2, 3, 4, 5}; - int length = sizeof(arr) // sizeof(arr[0]); - printf("%d\n", length); // 5 - ``` - - - - ```cpp - // Find the length of an array in C++ - int arr[] = {1, 2, 3, 4, 5}; - int length = sizeof(arr) // sizeof(arr[0]); - cout << length << endl; // 5 - ``` - - - - ```ts - // Find the length of an array in TypeScript - let arr: number[] = [1, 2, 3, 4, 5]; - console.log(arr.length); // 5 - ``` - - - -## How to iterate through an Array? - -An array can be iterated using a loop such as `for` loop, `while` loop, or `for...of` loop. - - - - - ```jsx - // Iterate through an array in JavaScript - let arr = [1, 2, 3, 4, 5]; - for (let i = 0; i < arr.length; i++) { - console.log(arr[i]); - } - // 1 - // 2 - // 3 - // 4 - // 5 - ``` - - - - - ```java - // Iterate through an array in Java - int[] arr = {1, 2, 3, 4, 5}; - for (int i = 0; i < arr.length; i++) { - System.out.println(arr[i]); - } - // 1 - // 2 - // 3 - // 4 - // 5 - ``` - - - - ```python - # Iterate through an array in Python - arr = [1, 2, 3, 4, 5] - for i in arr: - print(i) - # 1 - # 2 - # 3 - # 4 - # 5 - ``` - - - - ```c - // Iterate through an array in C - int arr[] = {1, 2, 3, 4, 5}; - for (int i = 0; i < 5; i++) { - printf("%d\n", arr[i]); - } - // 1 - // 2 - // 3 - // 4 - // 5 - ``` - - - - ```cpp - // Iterate through an array in C++ - int arr[] = {1, 2, 3, 4, 5}; - for (int i = 0; i < 5; i++) { - cout << arr[i] << endl; - } - // 1 - // 2 - // 3 - // 4 - // 5 - ``` - - - - ```ts - // Iterate through an array in TypeScript - let arr: number[] = [1, 2, 3, 4, 5]; - for (let i = 0; i < arr.length; i++) { - console.log(arr[i]); - } - // 1 - // 2 - // 3 - // 4 - // 5 - ``` - - - -## How to find the maximum and minimum elements in an Array? - -The maximum and minimum elements in an array can be found by iterating through the array and comparing each element with the current maximum and minimum elements. - - - - - ```js - // Find the maximum and minimum elements in an array in JavaScript - function findMaxMin(arr) { - let max = arr[0]; - let min = arr[0]; - for (let i = 1; i < arr.length; i++) { - if (arr[i] > max) { - max = arr[i]; - } - if (arr[i] < min) { - min = arr[i]; - } - } - return { max, min }; - } - - let arr = [2, 5, 1, 20, 10]; - console.log(findMaxMin(arr)); // { max: 20, min: 1 } - ``` - - - - ```java - public class Main { - // Find the maximum and minimum elements in an array in Java - static class MaxMin { - int max; - int min; - } - - static MaxMin findMaxMin(int arr[]) { - MaxMin result = new MaxMin(); - result.max = arr[0]; - result.min = arr[0]; - for (int i = 1; i < arr.length; i++) { - if (arr[i] > result.max) { - result.max = arr[i]; - } - if (arr[i] < result.min) { - result.min = arr[i]; - } - } - return result; - } - - public static void main(String[] args) { - int arr[] = {2, 5, 1, 20, 10}; - MaxMin result = findMaxMin(arr); - System.out.println("{ max: " + result.max + ", min: " + result.min + " }"); // { max: 20, min: 1 } - } - } - - ``` - - - - ```python - # Find the maximum and minimum elements in an array in Python - def find_max_min(arr): - max = arr[0] - min = arr[0] - for i in range(1, len(arr)): - if arr[i] > max: - max = arr[i] - if arr[i] < min: - min = arr[i] - return {"max": max, "min": min} - - arr = [2, 5, 1, 20, 10] - print(find_max_min(arr)) # { max: 20, min: 1 } - ``` - - - - ```c - // Find the maximum and minimum elements in an array in C - struct MaxMin { - int max; - int min; - }; - - struct MaxMin findMaxMin(int arr[], int n) { - struct MaxMin result; - result.max = arr[0]; - result.min = arr[0]; - for (int i = 1; i < n; i++) { - if (arr[i] > result.max) { - result.max = arr[i]; - } - if (arr[i] < result.min) { - result.min = arr[i]; - } - } - return result; - } - - int arr[] = {2, 5, 1, 20, 10}; - struct MaxMin result = findMaxMin(arr, 5); - printf("{ max: %d, min: %d }\n", result.max, result.min); // { max: 20, min: 1 } - ``` - - - - ```cpp - // Find the maximum and minimum elements in an array in C++ - struct MaxMin { - int max; - int min; - }; - - MaxMin findMaxMin(int arr[], int n) { - MaxMin result; - result.max = arr[0]; - result.min = arr[0]; - for (int i = 1; i < n; i++) { - if (arr[i] > result.max) { - result.max = arr[i]; - } - if (arr[i] < result.min) { - result.min = arr[i]; - } - } - return result; - } - - int arr[] = {2, 5, 1, 20, 10}; - MaxMin result = findMaxMin(arr, 5); - cout << "{ max: " << result.max << ", min: " << result.min << " }" << endl; // { max: 20, min: 1 } - ``` - - - - ```ts - // Find the maximum and minimum elements in an array in TypeScript - interface MaxMin { - max: number; - min: number; - } - - function findMaxMin(arr: number[]): MaxMin { - let max = arr[0]; - let min = arr[0]; - for (let i = 1; i < arr.length; i++) { - if (arr[i] > max) { - max = arr[i]; - } - if (arr[i] < min) { - min = arr[i]; - } - } - return { max, min }; - } - - let arr: number[] = [2, 5, 1, 20, 10]; - console.log(findMaxMin(arr)); // { max: 20, min: 1 } - ``` - - - -:::info 📝 Info -- The time complexity of finding the maximum and minimum elements in an array is O(n). -- The space complexity of finding the maximum and minimum elements in an array is O(1). -::: - - -## Conclusion - -In this tutorial, we learned about arrays in data structures and algorithms. We learned how to declare an array, access an array, update an array, find the length of an array, iterate through an array, and find the maximum and minimum elements in an array. Arrays are an important data structure that is used in many algorithms and data structures. \ No newline at end of file diff --git a/docs/basic-dsa/array/arrays-insertionsort.md b/docs/basic-dsa/array/arrays-insertionsort.md deleted file mode 100644 index 2e1104fb0..000000000 --- a/docs/basic-dsa/array/arrays-insertionsort.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: arrays-insertionsort -title: Arrays - Insertion Sort -sidebar_label: Insertion Sort -sidebar_position: 4 -description: "Insertion Sort is a simple sorting algorithm that builds the final sorted array one item at a time. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort." -tags: [dsa, arrays, sorting, insertion-sort, sorting-algorithms] ---- - -**Insertion Sort** is a simple sorting algorithm that builds the final sorted array one item at a time. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. - -However, insertion sort provides several advantages: - -- **Simple implementation:** The code implementation of insertion sort is simple and easy to understand. -- **Efficient for small data sets:** Insertion sort is efficient for small data sets. -- **Adaptive:** It is adaptive, meaning it is efficient for data sets that are already substantially sorted. -- **Stable:** It is a stable sorting algorithm, meaning it preserves the relative order of equal elements. -- **In-place:** It requires only a constant amount of additional memory space. -- **Online:** It can sort a list as it receives it. -- **More efficient in practice:** It is more efficient in practice than other quadratic-time sorting algorithms like bubble sort and selection sort. -- **Simple to code:** It is simple to code and implement. - - - -
    - -The insertion sort algorithm takes value at a time from the unsorted part and places it in its correct position in the sorted part. The sorted part is built from left to right, and the unsorted part is on the right side of the array. The algorithm works by shifting the elements in the sorted part that are greater than the current element to the right, creating space for the current element to be inserted. - -:::info Key Points -- **Type:** Sorting Algorithm -- **Time Complexity:** - - **Best Case:** $O(n)$ - - **Average Case:** $O(n^2)$ - - **Worst Case:** $O(n^2)$ -- **Space Complexity:** $O(1)$ -- **Stable:** Yes -- **In-Place:** Yes -- **Online:** Yes -- **Adaptive:** Yes -- **Comparison Sort:** Yes -- **Suitable for:** Small data sets, partially sorted data sets -- **Efficient for:** Small data sets -- **Not efficient for:** Large data sets -- **Simple to code:** Yes -- **Efficient in practice:** Yes - -::: - -:::tip Real-World Analogy -Insertion sort can be compared to sorting a deck of cards. You start with an empty hand and pick one card at a time from the deck. You then insert the card into its correct position in your hand, shifting the other cards if necessary. This process is repeated until all the cards are sorted in your hand. - -## How Insertion Sort Works? - -Let's understand how the Insertion Sort algorithm works with an example: - -Consider an array `arr = [12, 11, 13, 5, 6]` that we want to sort in ascending order using the Insertion Sort algorithm. - -1. **Initial Array:** `[12, 11, 13, 5, 6]` -2. **Step 1:** Start from the second element (index 1) and compare it with the previous element. - - Compare `11` with `12`. Since `11` is smaller, swap them. - - **Array after Step 1:** `[11, 12, 13, 5, 6]` - - The array is partially sorted from index 0 to 1. - - The current array looks like this: `[11, 12, 13, 5, 6]` - - The sorted part is `[11, 12]`, and the unsorted part is `[13, 5, 6]`. - - The key element is `13`. - - The key element is compared with the elements in the sorted part. - - Since `13` is greater than `12`, no swap is needed. - - The array remains the same: `[11, 12, 13, 5, 6]` - - The array is partially sorted from index 0 to 2. - - The current array looks like this: `[11, 12, 13, 5, 6]` - - The sorted part is `[11, 12, 13]`, and the unsorted part is `[5, 6]`. - - The key element is `5`. - - The key element is compared with the elements in the sorted part. - - Since `5` is smaller than `13`, `12`, and `11`, it is moved to the left. - - **Array after Step 1:** `[5, 11, 12, 13, 6]` - - The array is partially sorted from index 0 to 3. - - The current array looks like this: `[5, 11, 12, 13, 6]` - - The sorted part is `[5, 11, 12, 13]`, and the unsorted part is `[6]`. - - The key element is `6`. - - The key element is compared with the elements in the sorted part. - - Since `6` is smaller than `13`, it is moved to the left. - - Since `6` is smaller than `12`, it is moved to the left. - - Since `6` is smaller than `11`, it is moved to the left. - - **Array after Step 1:** `[5, 6, 11, 12, 13]` - - The array is now sorted. - - The sorted array is `[5, 6, 11, 12, 13]`. - -3. **Final Sorted Array:** `[5, 6, 11, 12, 13]` -4. The array is now sorted in ascending order using the Insertion Sort algorithm. -5. The time complexity of the Insertion Sort algorithm is ***O(n2)*** in the worst-case scenario. -6. The space complexity of the Insertion Sort algorithm is ***O(1)***. -7. The Insertion Sort algorithm is efficient for small data sets and partially sorted data sets. - -## Visualization - -You can visualize the Insertion Sort algorithm using the following animation: - - - -You can select the Insertion Sort algorithm from the drop-down menu and visualize how it works on different arrays. - -::: - -## Algorithm - -The insertion sort algorithm works as follows: - -1. Start from the second element (index 1) and compare it with the previous elements. -2. If the current element is smaller than the previous element, swap them. -3. Repeat this process until the current element is greater than the previous element or until the first element is reached. -4. Move to the next element and repeat the process. -5. Continue this process until the entire array is sorted. -6. The array is now sorted. -7. The time complexity of the insertion sort algorithm is ***O(n2)*** in the worst-case scenario. -8. The space complexity of the insertion sort algorithm is ***O(1)***. - -## Pseudocode - -```plaintext -1. for i = 1 to n-1 -2. key = arr[i] -3. j = i - 1 -4. while j >= 0 and arr[j] > key -5. arr[j + 1] = arr[j] -6. j = j - 1 -7. arr[j + 1] = key -``` - -## Implementation - -Here's the implementation of the Insertion Sort algorithm in JavaScript: - -```javascript title="Insertion Sort" -function insertionSort(arr) { - const n = arr.length; - for (let i = 1; i < n; i++) { - let key = arr[i]; - let j = i - 1; - while (j >= 0 && arr[j] > key) { - arr[j + 1] = arr[j]; - j = j - 1; - } - arr[j + 1] = key; - } - return arr; -} - -const arr = [12, 11, 13, 5, 6]; -console.log(insertionSort(arr)); // Output: [5, 6, 11, 12, 13] -``` - -## Complexity Analysis - -The time complexity of the Insertion Sort algorithm is ***O(n2)*** in the worst-case scenario when the array is sorted in reverse order. The best-case time complexity is ***O(n)*** when the array is already sorted. - -The space complexity of the Insertion Sort algorithm is ***O(1)*** since it requires only a constant amount of additional memory space. - -## References - -- [Wikipedia - Insertion Sort](https://en.wikipedia.org/wiki/Insertion_sort) -- [GeeksforGeeks - Insertion Sort](https://www.geeksforgeeks.org/insertion-sort/) -- [Programiz - Insertion Sort](https://www.programiz.com/dsa/insertion-sort) -- [Khan Academy - Insertion Sort](https://www.khanacademy.org/computing/computer-science/algorithms/insertion-sort/a/insertion-sort) -- [TutorialsPoint - Insertion Sort](https://www.tutorialspoint.com/data_structures_algorithms/insertion_sort_algorithm.htm) -- [StudyTonight - Insertion Sort](https://www.studytonight.com/data-structures/insertion-sorting) -- [Insertion Sort Visualization](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html) diff --git a/docs/basic-dsa/array/arrays-kadanesalgorithm-dsa.md b/docs/basic-dsa/array/arrays-kadanesalgorithm-dsa.md deleted file mode 100644 index b6c406972..000000000 --- a/docs/basic-dsa/array/arrays-kadanesalgorithm-dsa.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: kadane -title: Kadane's Algorithm -sidebar_label: Kadane's Algorithm -description: "In this blog post, we'll explore Kadane's Algorithm, a dynamic programming algorithm used to find the Maximum Sum Subarray in an array." -tags: [dsa, algorithms, dynamic programming, subarray] ---- - -### Definition: - -Kadane's algorithm is a **dynamic programming algorithm** used to find the maximum sum of a contiguous subarray within a one-dimensional array of numbers. It efficiently calculates the largest sum that can be obtained by adding consecutive elements in the array. - -### Characteristics: - -- **Dynamic Programming Approach**: - - Kadane's algorithm operates by maintaining a running sum of the maximum subarray ending at each position. It decides at every step whether to include the current element in the existing subarray or start a new subarray from the current element. - -- **Linear Time Algorithm**: - - The algorithm works in $O(n)$ time complexity, where $n$ is the number of elements in the array, as it only requires a single traversal of the array. - -- **Handles Negative Numbers**: - - Kadane’s algorithm can handle arrays with both positive and negative numbers, and it efficiently skips over negative subarrays that reduce the overall sum. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(n)$** - Kadane's algorithm processes each element exactly once, making its time complexity linear. - -### Space Complexity: - -- **Space Complexity: $O(1)$** - The algorithm only requires constant space, using variables to store the current maximum and the global maximum sums. - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -int kadane(vector& arr) { - int max_current = arr[0]; - int max_global = arr[0]; - - for (int i = 1; i < arr.size(); i++) { - max_current = max(arr[i], max_current + arr[i]); - if (max_current > max_global) { - max_global = max_current; - } - } - - return max_global; -} - -int main() { - vector arr = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; - int max_sum = kadane(arr); - cout << "Maximum Sum Subarray: " << max_sum << endl; - return 0; -} -``` - -### Summary: - -Kadane's algorithm provides an efficient solution to the maximum sum subarray problem using dynamic programming. By keeping track of the current subarray sum and adjusting it dynamically, it guarantees finding the maximum sum with a time complexity of O(n). This algorithm is widely used in problems related to subarray sums and optimization in financial and data analysis tasks. diff --git a/docs/basic-dsa/array/arrays-selectionsort.md b/docs/basic-dsa/array/arrays-selectionsort.md deleted file mode 100644 index 706040c34..000000000 --- a/docs/basic-dsa/array/arrays-selectionsort.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -id: arrays-selectionsort-in-dsa -title: Arrays - Selection Sort in DSA -sidebar_label: Selection Sort -sidebar_position: 3 -description: "Selection Sort is an in-place comparison sorting algorithm that divides the input list into two parts: the sublist of items already sorted and the sublist of items remaining to be sorted. It repeatedly finds the minimum element from the unsorted part and puts it at the beginning of the unsorted part. The algorithm maintains two subarrays in a given array. The subarray which is already sorted and the remaining subarray which is unsorted. In every iteration of selection sort, the minimum element from the unsorted subarray is picked and moved to the sorted subarray." -tags: [dsa, arrays, sorting, selection-sort, algorithm of selection-sort, pseudocode of selection-sort, complexity of selection-sort, example of selection-sort, live example of selection-sort, explanation of selection-sort, quiz of selection-sort, conclusion of selection-sort] ---- - -**Selection Sort** is an in-place comparison sorting algorithm that divides the input list into two parts: the sublist of items already sorted and the sublist of items remaining to be sorted. It repeatedly finds the minimum element from the unsorted part and puts it at the beginning of the unsorted part. The algorithm maintains two subarrays in a given array. The subarray which is already sorted and the remaining subarray which is unsorted. In every iteration of selection sort, the minimum element from the unsorted subarray is picked and moved to the sorted subarray. - - - -## Algorithm - -1. The selection sort algorithm divides the input list into two parts: the sublist of items already sorted and the sublist of items remaining to be sorted. -2. The algorithm repeatedly finds the minimum element from the unsorted part and puts it at the beginning of the unsorted part. -3. The algorithm maintains two subarrays in a given array. The subarray which is already sorted and the remaining subarray which is unsorted. -4. In every iteration of selection sort, the minimum element from the unsorted subarray is picked and moved to the sorted subarray. -5. The array is sorted. -6. Exit. -7. The time complexity of the selection sort is O(n^2). -8. The space complexity of the selection sort is O(1). - -## Pseudocode - -```plaintext title="Selection Sort" -procedure selectionSort( A : list of sortable items ) - n = length(A) - for i = 0 to n-1 inclusive do - min = i - for j = i+1 to n inclusive do - if A[j] < A[min] then - min = j - end if - end for - swap(A[i], A[min]) - end for -end procedure -``` - -## Diagram - - -## Complexity - -The time complexity of the selection sort is O(n^2). The space complexity of the selection sort is O(1). - -## Example - -```js title="Selection Sort" -function selectionSort(arr) { - let n = arr.length; - for (let i = 0; i < n - 1; i++) { - let min = i; - for (let j = i + 1; j < n; j++) { - if (arr[j] < arr[min]) { - min = j; - } - } - let temp = arr[i]; - arr[i] = arr[min]; - arr[min] = temp; - } - return arr; -} - -const arr = [64, 25, 12, 22, 11]; - -console.log(selectionSort(arr)); // [11, 12, 22, 25, 64] -``` - -## Practice Problems - -- [Leetcode - Sort an Array](https://leetcode.com/problems/sort-an-array/) -- [HackerRank - The Full Counting Sort](https://www.hackerrank.com/challenges/countingsort4/problem) -- [Codeforces - Sort the Array](https://codeforces.com/problemset/problem/451/B) -- [CodeChef - Turbo Sort](https://www.codechef.com/problems/TSORT) - -## Quiz - -1. What is the time complexity of the selection sort? - - A) O(n) - - B) O(n^2) - - C) O(n log n) - - D) O(1) - - Correct Answer: B - -2. What is the space complexity of the selection sort? - - A) O(n) - - B) O(n^2) - - C) O(n log n) - - D) O(1) - - Correct Answer: D -- Explanation: The space complexity of the selection sort is O(1). - -3. What is the best-case time complexity of the selection sort? - - A) O(n) - - B) O(n^2) - - C) O(n log n) - - D) O(1) - - Correct Answer: B - -4. What is the worst-case time complexity of the selection sort? - - A) O(n) - - B) O(n^2) - - C) O(n log n) - - D) O(1) - - Correct Answer: B - -5. Is the selection sort stable? - - A) Yes - - B) No - - Correct Answer: A - - -:::info Try it yourself - -```js live -function selectionSort() { - let arr = [64, 25, 12, 22, 11]; - let n = arr.length; - for (let i = 0; i < n - 1; i++) { - let min = i; - for (let j = i + 1; j < n; j++) { - if (arr[j] < arr[min]) { - min = j; - } - } - let temp = arr[i]; - arr[i] = arr[min]; - arr[min] = temp; - } - return ( -
    -

    Selection Sort

    -

    Array: [64, 25, 12, 22, 11]

    -

    - Sorted Array: [{arr.join(", ")}] -

    -
    - ) -} -``` - -In the above example, we have an array of numbers `[64, 25, 12, 22, 11]`. We are using the selection sort algorithm to sort the array in ascending order. The selection sort algorithm divides the input list into two parts: the sublist of items already sorted and the sublist of items remaining to be sorted. It repeatedly finds the minimum element from the unsorted part and puts it at the beginning of the unsorted part. The algorithm maintains two subarrays in a given array. The subarray which is already sorted and the remaining subarray which is unsorted. In every iteration of selection sort, the minimum element from the unsorted subarray is picked and moved to the sorted subarray. The sorted array is `[11, 12, 22, 25, 64]`. The time complexity of the selection sort is O(n^2) and the space complexity is O(1). - -::: - -## Conclusion - -In this article, we learned about the selection sort algorithm. Selection sort is an in-place comparison sorting algorithm that divides the input list into two parts: the sublist of items already sorted and the sublist of items remaining to be sorted. It repeatedly finds the minimum element from the unsorted part and puts it at the beginning of the unsorted part. The algorithm maintains two subarrays in a given array. The subarray which is already sorted and the remaining subarray which is unsorted. In every iteration of selection sort, the minimum element from the unsorted subarray is picked and moved to the sorted subarray. The time complexity of the selection sort is O(n^2) and the space complexity is O(1). Selection sort is a stable sorting algorithm. \ No newline at end of file diff --git a/docs/basic-dsa/array/bucket-sort.md b/docs/basic-dsa/array/bucket-sort.md deleted file mode 100644 index e49f0410e..000000000 --- a/docs/basic-dsa/array/bucket-sort.md +++ /dev/null @@ -1,263 +0,0 @@ ---- -id: bucket-sort -title: Bucket sort -sidebar_label: Bucket sort -tags: - - DSA - - Python - - C++ - - Java - - Sorting - -description: "Thsi page containes Bucket Sort, with codes in python, java and c++ " ---- - -### Introduction to Bucket Sort - -Bucket sort is a comparison sorting algorithm that distributes elements into a number of "buckets." Each bucket is then sorted individually, either using another sorting algorithm or recursively applying the bucket sort. Finally, the sorted buckets are combined to form the final sorted array. Bucket sort is particularly useful for uniformly distributed data. - -### Steps of Bucket Sort - -1. **Create Buckets**: Initialize an empty array of buckets. -2. **Distribute Elements**: Distribute the elements of the input array into the appropriate buckets. -3. **Sort Buckets**: Sort each bucket individually. -4. **Concatenate Buckets**: Concatenate all sorted buckets to form the final sorted array. - -### Pseudocode - -```text -function bucketSort(array, bucketSize): - if length(array) == 0: - return array - - // Determine minimum and maximum values - minValue = min(array) - maxValue = max(array) - - // Initialize buckets - bucketCount = floor((maxValue - minValue) / bucketSize) + 1 - buckets = array of empty lists of size bucketCount - - // Distribute input array values into buckets - for i from 0 to length(array) - 1: - bucketIndex = floor((array[i] - minValue) / bucketSize) - append array[i] to buckets[bucketIndex] - - // Sort each bucket and concatenate them - sortedArray = [] - for i from 0 to bucketCount - 1: - sort(buckets[i]) // You can use any sorting algorithm - append buckets[i] to sortedArray - - return sortedArray -``` - -### Implementation in Python, C++, Java and JavaScript - -#### Python Implementation - -```python -def bucket_sort(numbers, size=5): - if len(numbers) == 0: - return numbers - - # Determine minimum and maximum values - min_value = min(numbers) - max_value = max(numbers) - - # Initialize buckets - bucket_count = (max_value - min_value) // size + 1 - buckets = [[] for _ in range(bucket_count)] - - # Distribute input array values into buckets - for number in numbers: - bucket_index = (number - min_value) // size - buckets[bucket_index].append(number) - - # Sort each bucket and concatenate them - sorted_numbers = [] - for bucket in buckets: - sorted_numbers.extend(sorted(bucket)) - - return sorted_numbers - -# Example usage -data = [42, 32, 33, 52, 37, 47, 51] -sorted_data = bucket_sort(data) -print(sorted_data) # Output: [32, 33, 37, 42, 47, 51, 52] -``` - -#### C++ Implementation - -```cpp -#include -#include -#include -using namespace std; - -void bucketSort(vector& nums, int bucketSize) { - if (nums.empty()) - return; - - // Determine minimum and maximum values - int minValue = *min_element(nums.begin(), nums.end()); - int maxValue = *max_element(nums.begin(), nums.end()); - - // Initialize buckets - int numBuckets = (maxValue - minValue) / bucketSize + 1; - vector> buckets(numBuckets); - - // Distribute input array values into buckets - for (int num : nums) { - int bucketIndex = (num - minValue) / bucketSize; - buckets[bucketIndex].push_back(num); - } - - // Sort each bucket and concatenate them - nums.clear(); - for (auto& bucket : buckets) { - sort(bucket.begin(), bucket.end()); - nums.insert(nums.end(), bucket.begin(), bucket.end()); - } -} - -// Example usage -int main() { - vector data = {42, 32, 33, 52, 37, 47, 51}; - bucketSort(data, 5); - for (int num : data) { - cout << num << " "; - } - // Output: 32 33 37 42 47 51 52 - return 0; -} -``` - -#### Java Implementation - -```java -import java.util.ArrayList; -import java.util.Collections; - -public class BucketSort { - public static void bucketSort(int[] array, int bucketSize) { - if (array.length == 0) - return; - - // Determine minimum and maximum values - int minValue = array[0]; - int maxValue = array[0]; - for (int num : array) { - if (num < minValue) - minValue = num; - else if (num > maxValue) - maxValue = num; - } - - // Initialize buckets - int bucketCount = (maxValue - minValue) / bucketSize + 1; - ArrayList> buckets = new ArrayList<>(bucketCount); - for (int i = 0; i < bucketCount; i++) { - buckets.add(new ArrayList()); - } - - // Distribute input array values into buckets - for (int num : array) { - int bucketIndex = (num - minValue) / bucketSize; - buckets.get(bucketIndex).add(num); - } - - // Sort each bucket and concatenate them - int currentIndex = 0; - for (ArrayList bucket : buckets) { - Collections.sort(bucket); - for (int num : bucket) { - array[currentIndex++] = num; - } - } - } - - // Example usage - public static void main(String[] args) { - int[] data = {42, 32, 33, 52, 37, 47, 51}; - bucketSort(data, 5); - for (int num : data) { - System.out.print(num + " "); - } - // Output: 32 33 37 42 47 51 52 - } -} -``` - -#### JavaScript Code Implementation - -```javascript -function bucketSort(nums, bucketSize) { - if (nums.length === 0) return; - - // Determine minimum and maximum values - const minValue = Math.min(...nums); - const maxValue = Math.max(...nums); - - // Initialize buckets - const numBuckets = Math.floor((maxValue - minValue) / bucketSize) + 1; - const buckets = Array.from({ length: numBuckets }, () => []); - - // Distribute input array values into buckets - for (const num of nums) { - const bucketIndex = Math.floor((num - minValue) / bucketSize); - buckets[bucketIndex].push(num); - } - - // Sort each bucket and concatenate them - nums.length = 0; // Clear the original array - for (const bucket of buckets) { - bucket.sort((a, b) => a - b); // Sort the current bucket - nums.push(...bucket); // Concatenate sorted bucket to nums - } -} - -// Example usage -const data = [42, 32, 33, 52, 37, 47, 51]; -bucketSort(data, 5); -console.log(data); // Output: [32, 33, 37, 42, 47, 51, 52] -``` - -### Explanation of the Code - -1. **Function `bucketSort`**: - - The function takes an array `nums` and a `bucketSize` as parameters. - - It first checks if the array is empty and returns if true. - -2. **Finding Minimum and Maximum Values**: - - The minimum and maximum values of the array are determined using `Math.min` and `Math.max`. - -3. **Initializing Buckets**: - - The number of buckets is calculated based on the range of the values divided by the `bucketSize`. - - Buckets are initialized as an array of empty arrays. - -4. **Distributing Values into Buckets**: - - Each number in the input array is placed into its respective bucket based on its calculated index. - -5. **Sorting Buckets**: - - Each bucket is sorted using the native `sort` method. - - The original array `nums` is cleared, and the sorted buckets are concatenated back into it. - -6. **Example Usage**: - - An example array `data` is provided, and `bucketSort` is called with this array and a `bucketSize`. - - The sorted array is printed to the console. - - -### Complexity - -- **Time Complexity**: - - - Best Case: $O(n + k)$, where $n$ is the number of elements and $k$ is the number of buckets. - - Average Case: $O(n + k + n \log(\frac{n}{k}))$ - - Worst Case: $O(n^2)$, when all elements are placed in one bucket and a slow sorting algorithm (like bubble sort) is used within buckets. - -- **Space Complexity**: $O(n + k)$, for the input array and the buckets. - -### Conclusion - -Bucket sort is efficient for sorting uniformly distributed data and can achieve linear time complexity in the best case. However, it may degrade to quadratic time complexity in the worst case if elements are not uniformly distributed. It's essential to choose an appropriate bucket size and secondary sorting algorithm for optimal performance. By understanding its structure and implementation, you can effectively use bucket sort for various sorting tasks. diff --git a/docs/basic-dsa/array/counting-sort.md b/docs/basic-dsa/array/counting-sort.md deleted file mode 100644 index 03d034f6d..000000000 --- a/docs/basic-dsa/array/counting-sort.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -id: counting-sort -title: Counting Sort Algorithm -sidebar_label: Counting sort -sidebar_position: 500 -description: "Counting Sort is an efficient sorting algorithm used for sorting a collection of integers when the range of the integers (k) is not significantly greater than the number of integers (n) in the collection. It works well when the integers are within a known, fixed range." -tags: [counting-sort] ---- - -Counting Sort is an efficient, non-comparative sorting algorithm suitable for sorting integers within a specific range. It operates by counting the occurrences of each unique value in the input data and then using those counts to determine the positions of each value in the sorted output. - -## Characteristics -- **Time Complexity**: $O(n + k)$, where `n` is the number of elements in the input array and `k` is the range of the input values. -- **Space Complexity**: $O(k)$, where `k` is the range of the input values. -- **Stability**: Counting Sort is stable, meaning that it preserves the relative order of equal elements. - -## How It Works -1. **Counting**: Create a count array to store the count of each unique value in the input array. -2. **Accumulating**: Modify the count array to store the cumulative sum of counts. This step determines the position of each element in the sorted array. -3. **Placing Elements**: Iterate through the input array, placing each element in its correct position in the output array based on the count array, and then decrease the count. - -## Example -Given an input array: `[4, 2, 2, 8, 3, 3, 1]` - -The steps for Counting Sort would be: - -1. Create a count array to store the count of each unique value. -2. Modify the count array to store cumulative counts. -3. Build the sorted output array based on the count array. - -## Usage -Here is an example implementation of Counting Sort in Java: -### Java Implementation -```java -public class countingSort { - - public static void countingSort(int arr[]) { - int max = Integer.MIN_VALUE; - for (int i = 0; i < arr.length; i++) { - max = Math.max(max, arr[i]); - } - int count[] = new int[max + 1]; - for (int i = 0; i < arr.length; i++) { - count[arr[i]]++; - } - int j = 0; - for (int i = 0; i < arr.length; i++) { - while (count[i] > 0) { - arr[j] = i; - j++; - count[i]--; - } - } - } - - public static void main(String[] args) { - int arr[] = { 3, 6, 2, 1, 8, 7, 4, 5, 3, 1 }; - countingSort(arr); - } -} -``` - -### JavaScript Implementation - -```javascript -function countingSort(arr) { - // Find the maximum element in the array - let max = Math.max(...arr); // Use spread operator to find max - const count = new Array(max + 1).fill(0); // Create count array initialized to 0 - - // Store the count of each element in the count array - for (let i = 0; i < arr.length; i++) { - count[arr[i]]++; - } - - let j = 0; - // Reconstruct the sorted array - for (let i = 0; i <= max; i++) { - while (count[i] > 0) { - arr[j] = i; // Place the element in the sorted position - j++; - count[i]--; // Decrease the count - } - } -} - -// Example usage -const arr = [3, 6, 2, 1, 8, 7, 4, 5, 3, 1]; -countingSort(arr); -console.log("Sorted array is:", arr); // Output the sorted array -``` - -### Explanation of the Code - -1. **`countingSort` Function**: - - Takes an array (`arr`) as input and sorts it in place. - -2. **Finding the Maximum Value**: - - `Math.max(...arr)` is used to find the maximum value in the array using the spread operator. - -3. **Count Array**: - - An array (`count`) is created with a length of `max + 1` and initialized with zeros to count the occurrences of each element. - -4. **Counting Elements**: - - A loop iterates through the input array, incrementing the count for each element in the `count` array. - -5. **Reconstructing the Sorted Array**: - - A nested loop iterates through the `count` array. - - While the count of an element is greater than zero, it places the element into the original array (`arr`) and decrements the count. - -6. **Example Usage**: - - An example array is created. - - The `countingSort` function is called to sort the array. - - The sorted array is printed to the console. diff --git a/docs/basic-dsa/array/heap-sort.md b/docs/basic-dsa/array/heap-sort.md deleted file mode 100644 index 35eb127ff..000000000 --- a/docs/basic-dsa/array/heap-sort.md +++ /dev/null @@ -1,191 +0,0 @@ ---- -id: arrays-heapsort -title: Arrays - Heap Sort -sidebar_label: Heap Sort -sidebar_position: 4 -description: "Heap Sort is an efficient comparison-based sorting algorithm based on a binary heap data structure. It sorts by building a max-heap from the data and repeatedly extracting the maximum element." -tags: [dsa, arrays, sorting, heap-sort, algorithm of heap-sort, pseudocode of heap-sort, complexity of heap-sort, example of heap-sort, explanation of heap-sort] ---- - - - -**Heap Sort** is an efficient, comparison-based sorting algorithm based on a binary heap data structure. Heap Sort builds a max-heap from the array and then repeatedly extracts the maximum element to achieve the sorted order. It is particularly effective for sorting large datasets due to its time complexity. - - - -## Algorithm Steps -1. **Build a Max-Heap**: Start by building a max-heap from the input array. -2. **Heap Sort Process**: - - Swap the root of the heap (maximum element) with the last element in the array. - - Reduce the size of the heap and call `heapify` on the root to restore the max-heap property. - - Repeat this process until the heap size is reduced to 1. -3. **Final Sorted Array**: The array will be sorted in ascending order as a result. - -## Complexity -- **Time Complexity**: - - **Best Case:** $O(n \log n)$ - - **Average Case:** $O(n \log n)$ - - **Worst Case:** $O(n \log n)$ -- **Space Complexity**: $O(1)$, as Heap Sort is an in-place algorithm. -- **Stability**: Heap Sort is not a stable sort (it does not preserve the relative order of equal elements). - -## Pseudocode - -```plaintext title="Heap Sort" -procedure heapSort(A: list of sortable items) - buildMaxHeap(A) - for end = length(A) down to 2 do - swap(A[1], A[end]) - heapSize = heapSize - 1 - heapify(A, 1) - end for -end procedure - -procedure buildMaxHeap(A: list of sortable items) - for i = floor(length(A) / 2) down to 1 do - heapify(A, i) - end for -end procedure - -procedure heapify(A: list of sortable items, i: integer) - left = 2 * i - right = 2 * i + 1 - largest = i - if left ≤ heapSize and A[left] > A[largest] then - largest = left - end if - if right ≤ heapSize and A[right] > A[largest] then - largest = right - end if - if largest ≠ i then - swap(A[i], A[largest]) - heapify(A, largest) - end if -end procedure -``` - -## Example - -### Java Implementation - -```java -public class HeapSort { - public void heapSort(int arr[]) { - int n = arr.length; - - for (int i = n / 2 - 1; i >= 0; i--) - heapify(arr, n, i); - - for (int i = n - 1; i > 0; i--) { - int temp = arr[0]; - arr[0] = arr[i]; - arr[i] = temp; - heapify(arr, i, 0); - } - } - - void heapify(int arr[], int n, int i) { - int largest = i; - int left = 2 * i + 1; - int right = 2 * i + 2; - - if (left < n && arr[left] > arr[largest]) - largest = left; - - if (right < n && arr[right] > arr[largest]) - largest = right; - - if (largest != i) { - int swap = arr[i]; - arr[i] = arr[largest]; - arr[largest] = swap; - heapify(arr, n, largest); - } - } - - public static void main(String[] args) { - int arr[] = {12, 11, 13, 5, 6, 7}; - HeapSort hs = new HeapSort(); - hs.heapSort(arr); - } -} -``` - -### JavaScript Code Implementation - -```javascript -class HeapSort { - heapSort(arr) { - const n = arr.length; - - // Build a maxheap - for (let i = Math.floor(n / 2) - 1; i >= 0; i--) { - this.heapify(arr, n, i); - } - - // One by one extract elements from heap - for (let i = n - 1; i > 0; i--) { - // Move current root to end - [arr[0], arr[i]] = [arr[i], arr[0]]; // Swap - - // Call heapify on the reduced heap - this.heapify(arr, i, 0); - } - } - - heapify(arr, n, i) { - let largest = i; // Initialize largest as root - const left = 2 * i + 1; // left = 2*i + 1 - const right = 2 * i + 2; // right = 2*i + 2 - - // If left child is larger than root - if (left < n && arr[left] > arr[largest]) { - largest = left; - } - - // If right child is larger than largest so far - if (right < n && arr[right] > arr[largest]) { - largest = right; - } - - // If largest is not root - if (largest !== i) { - // Swap - [arr[i], arr[largest]] = [arr[largest], arr[i]]; // Swap - - // Recursively heapify the affected sub-tree - this.heapify(arr, n, largest); - } - } -} - -// Example usage -const arr = [12, 11, 13, 5, 6, 7]; -const heapSort = new HeapSort(); -heapSort.heapSort(arr); -console.log("Sorted array is:", arr.join(" ")); // Output the sorted array -``` - -### Explanation of the Code - -1. **HeapSort Class**: - - Contains methods for performing heap sort. - -2. **`heapSort` Method**: - - Accepts an array (`arr`) as input. - - Builds a max heap by calling `heapify` for each non-leaf node, starting from the last non-leaf node down to the root. - - Repeatedly extracts the maximum element (the root of the heap) and swaps it with the last element of the heap, then reduces the size of the heap and calls `heapify` on the root. - -3. **`heapify` Method**: - - Maintains the heap property for a subtree rooted at index `i`, ensuring the largest element is at the root. - - Compares the node with its left and right children and swaps if necessary, then recursively calls `heapify` to ensure the subtree maintains the heap property. - -4. **Example Usage**: - - An example array is created. - - An instance of `HeapSort` is created, and `heapSort` is called on the array. - - The sorted array is printed to the console. - - -## Conclusion - -In this article, we explored the Heap Sort algorithm. Heap Sort is a highly efficient, in-place sorting algorithm based on the binary heap data structure. By building a max-heap and then extracting the maximum element repeatedly, it achieves a sorted array with an average time complexity of $O(n \log n)$. However, Heap Sort is not stable, and its space complexity is $O(1)$ due to its in-place nature. It is well-suited for sorting large datasets due to its efficiency. diff --git a/docs/basic-dsa/array/quick-sort.md b/docs/basic-dsa/array/quick-sort.md deleted file mode 100644 index a64c40c9f..000000000 --- a/docs/basic-dsa/array/quick-sort.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -id: arrays-quicksort -title: Arrays - Quick Sort -sidebar_label: Quick Sort -sidebar_position: 5 -description: "Quick Sort is a highly efficient and commonly used sorting algorithm that employs a divide-and-conquer strategy. It is well-suited for large datasets and typically outperforms other algorithms like insertion sort and bubble sort." -tags: [dsa, arrays, sorting, quicksort, sorting-algorithms] ---- - - - -**Quick Sort** is a highly efficient sorting algorithm that employs a divide-and-conquer strategy. It divides the input array into smaller sub-arrays, recursively sorting them. It is commonly used because of its average-case efficiency on large datasets. - - - -### How Quick Sort Works: -1. **Pivot Selection**: Select a pivot element from the array. -2. **Partitioning**: Rearrange the elements so that all elements smaller than the pivot are on its left, and all elements greater are on its right. -3. **Recursion**: Recursively apply the same process to the sub-arrays formed by partitioning. -4. **Base Case**: The recursion ends when the array is reduced to a single element or an empty sub-array. - -## Key Characteristics -- **Time Complexity**: - - **Best Case:** $O(n \log n)$ - - **Average Case:** $O(n \log n)$ - - **Worst Case:** $O(n^2)$ (occurs when the pivot is the smallest or largest element) -- **Space Complexity**: $O(\log n)$ due to the recursion stack. -- **Stability**: Quick Sort is not a stable sort (it does not preserve the relative order of equal elements). -- **In-place Sort**: It requires constant space, excluding the recursion stack. - -### Example -Given an input array: `[3, 6, 8, 10, 1, 2, 1]`, Quick Sort works as follows: - -1. Select a pivot (e.g., `3`). -2. Partition the array: `[1, 2, 1]` on the left of `3` and `[6, 8, 10]` on the right. -3. Recursively sort both sub-arrays. - -### Java Implementation - -Here is a basic implementation of Quick Sort in Java: - -```java -public class QuickSort { - - public static void quickSort(int[] arr, int low, int high) { - if (low < high) { - int pi = partition(arr, low, high); - quickSort(arr, low, pi - 1); - quickSort(arr, pi + 1, high); - } - } - - private static int partition(int[] arr, int low, int high) { - int pivot = arr[high]; - int i = (low - 1); - for (int j = low; j < high; j++) { - if (arr[j] <= pivot) { - i++; - int temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - } - int temp = arr[i + 1]; - arr[i + 1] = arr[high]; - arr[high] = temp; - return i + 1; - } - - public static void main(String[] args) { - int[] arr = {10, 7, 8, 9, 1, 5}; - int n = arr.length; - quickSort(arr, 0, n - 1); - } -} -``` - - -### JavaScript Code Implementation - -```javascript -class QuickSort { - static quickSort(arr, low, high) { - if (low < high) { - const pi = this.partition(arr, low, high); - this.quickSort(arr, low, pi - 1); // Recursively sort elements before partition - this.quickSort(arr, pi + 1, high); // Recursively sort elements after partition - } - } - - static partition(arr, low, high) { - const pivot = arr[high]; // Choose the last element as pivot - let i = low - 1; // Pointer for the smaller element - - for (let j = low; j < high; j++) { - // If current element is smaller than or equal to pivot - if (arr[j] <= pivot) { - i++; // Increment the index of smaller element - // Swap arr[i] and arr[j] - [arr[i], arr[j]] = [arr[j], arr[i]]; // Swap using destructuring - } - } - // Swap arr[i + 1] and arr[high] (or pivot) - [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]]; // Swap pivot to correct position - return i + 1; // Return the partitioning index - } -} - -// Example usage -const arr = [10, 7, 8, 9, 1, 5]; -const n = arr.length; -QuickSort.quickSort(arr, 0, n - 1); -console.log("Sorted array is:", arr.join(" ")); // Output the sorted array -``` - -### Explanation of the Code - -1. **QuickSort Class**: - - Contains static methods for performing the quick sort algorithm. - -2. **`quickSort` Method**: - - Takes an array (`arr`), and the indices (`low` and `high`) that define the portion of the array to be sorted. - - If `low` is less than `high`, it calls the `partition` method to find the pivot index and recursively sorts the subarrays on either side of the pivot. - -3. **`partition` Method**: - - Chooses the last element as the pivot. - - Initializes a pointer (`i`) to track the index of the smaller element. - - Iterates through the array, comparing each element to the pivot, and swaps elements to ensure those smaller than the pivot are to its left. - - Finally, it swaps the pivot element with the element at `i + 1` to place it in its correct sorted position and returns the index of the pivot. - -4. **Example Usage**: - - An example array is created. - - The `quickSort` method is called on the array. - - The sorted array is printed to the console. - - -
    -**Quick Sort** is versatile and efficient, making it a popular choice in practical applications. diff --git a/docs/basic-dsa/array/radix-sort.md b/docs/basic-dsa/array/radix-sort.md deleted file mode 100644 index 54ab30d1c..000000000 --- a/docs/basic-dsa/array/radix-sort.md +++ /dev/null @@ -1,330 +0,0 @@ ---- -id: radix-sort -title: Radix sort -sidebar_label: Radix Sort -tags: - - DSA - - Python - - C++ - - Java - - Sorting - -description: "This page explains Radix sort, with code implementations and resources for further learning." ---- - -### Introduction to Radix Sort - -Radix sort is a non-comparative integer sorting algorithm. It sorts integers by processing individual digits. Starting from the least significant digit (LSD) to the most significant digit (MSD), it uses a stable subroutine sort (like counting sort) to handle the individual digits. The algorithm is efficient for sorting numbers with a fixed number of digits and works well when the range of digits is not excessively large. - -### Steps of Radix Sort (Pseudocode Steps) - -1. **Find the maximum number** to determine the number of digits. -2. **Initialize**: Set up a loop to process each digit from the least significant to the most significant. -3. **Digit by digit sorting**: - - Use a stable sort (e.g., counting sort) to sort based on the current digit. -4. **Repeat** until all digits are processed. - -### Example - -To perform radix sort on the array [170, 45, 75, 90, 802, 24, 2, 66], we follow these steps: -![Example from GFG](https://media.geeksforgeeks.org/wp-content/uploads/20230609164537/Radix-Sort.png) - -Step 1: Find the largest element in the array, which is 802. It has three digits, so we will iterate three times, once for each significant place. - -Step 2: Sort the elements based on the unit place digits (X=0). We use a stable sorting technique, such as counting sort, to sort the digits at each significant place. - -Sorting based on the unit place: - -Perform counting sort on the array based on the unit place digits. -The sorted array based on the unit place is [170, 90, 802, 2, 24, 45, 75, 66]. - -![Example from GFG](https://media.geeksforgeeks.org/wp-content/uploads/20230609164536/Radix-Sort--1.png) - -Step 3: Sort the elements based on the tens place digits. - -Sorting based on the tens place: - -Perform counting sort on the array based on the tens place digits. -The sorted array based on the tens place is [802, 2, 24, 45, 66, 170, 75, 90]. - -![Example from GFG](https://media.geeksforgeeks.org/wp-content/uploads/20230609164535/Radix-Sort--2.png) - -Step 4: Sort the elements based on the hundreds place digits. - -Sorting based on the hundreds place: - -Perform counting sort on the array based on the hundreds place digits. -The sorted array based on the hundreds place is [2, 24, 45, 66, 75, 90, 170, 802]. - -![Example from GFG](https://media.geeksforgeeks.org/wp-content/uploads/20230609164535/Radix-Sort--3.png) - -Step 5: The array is now sorted in ascending order. - -The final sorted array using radix sort is [2, 24, 45, 66, 75, 90, 170, 802]. - -![Example from GFG](https://media.geeksforgeeks.org/wp-content/uploads/20230609164534/Radix-Sort--4.png) - -### Pseudocode for Radix Sort - -```text -function radixSort(array): - maxNumber = findMax(array) - numberOfDigits = countDigits(maxNumber) - - for digit in 1 to numberOfDigits: - countingSortByDigit(array, digit) - -function findMax(array): - maxNumber = array[0] - for number in array: - if number > maxNumber: - maxNumber = number - return maxNumber - -function countDigits(number): - count = 0 - while number != 0: - number = number // 10 - count += 1 - return count - -function countingSortByDigit(array, digit): - count = array of size 10 initialized to 0 - output = array of same size as input array - - # Count occurrences of each digit - for number in array: - digitValue = (number // 10^(digit - 1)) % 10 - count[digitValue] += 1 - - # Change count[i] so that count[i] contains the position of this digit in output - for i from 1 to 9: - count[i] += count[i - 1] - - # Build the output array - for i from length(array) - 1 to 0: - digitValue = (array[i] // 10^(digit - 1)) % 10 - output[count[digitValue] - 1] = array[i] - count[digitValue] -= 1 - - # Copy the output array to the input array - for i from 0 to length(array) - 1: - array[i] = output[i] -``` - -### Radix Sort Implementation in Python, C++, Java and JavaScript - -#### Python - -```python -def radix_sort(array): - def counting_sort_by_digit(array, digit): - count = [0] * 10 - output = [0] * len(array) - - for number in array: - digit_value = (number // 10**(digit - 1)) % 10 - count[digit_value] += 1 - - for i in range(1, 10): - count[i] += count[i - 1] - - for i in range(len(array) - 1, -1, -1): - digit_value = (array[i] // 10**(digit - 1)) % 10 - output[count[digit_value] - 1] = array[i] - count[digit_value] -= 1 - - for i in range(len(array)): - array[i] = output[i] - - max_number = max(array) - number_of_digits = len(str(max_number)) - - for digit in range(1, number_of_digits + 1): - counting_sort_by_digit(array, digit) - -# Example usage -arr = [170, 45, 75, 90, 802, 24, 2, 66] -radix_sort(arr) -print(arr) -``` - -#### C++ - -```cpp -#include -#include -#include - -void countingSortByDigit(std::vector& array, int digit) { - int size = array.size(); - std::vector output(size); - int count[10] = {0}; - - for (int i = 0; i < size; i++) { - int digitValue = (array[i] / digit) % 10; - count[digitValue]++; - } - - for (int i = 1; i < 10; i++) { - count[i] += count[i - 1]; - } - - for (int i = size - 1; i >= 0; i--) { - int digitValue = (array[i] / digit) % 10; - output[count[digitValue] - 1] = array[i]; - count[digitValue]--; - } - - for (int i = 0; i < size; i++) { - array[i] = output[i]; - } -} - -void radixSort(std::vector& array) { - int maxNumber = *max_element(array.begin(), array.end()); - for (int digit = 1; maxNumber / digit > 0; digit *= 10) { - countingSortByDigit(array, digit); - } -} - -// Example usage -int main() { - std::vector arr = {170, 45, 75, 90, 802, 24, 2, 66}; - radixSort(arr); - for (int num : arr) { - std::cout << num << " "; - } - return 0; -} -``` - -#### Java - -```java -import java.util.Arrays; - -public class RadixSort { - - public static void radixSort(int[] array) { - int maxNumber = Arrays.stream(array).max().getAsInt(); - for (int digit = 1; maxNumber / digit > 0; digit *= 10) { - countingSortByDigit(array, digit); - } - } - - private static void countingSortByDigit(int[] array, int digit) { - int size = array.length; - int[] output = new int[size]; - int[] count = new int[10]; - - for (int i = 0; i < size; i++) { - int digitValue = (array[i] / digit) % 10; - count[digitValue]++; - } - - for (int i = 1; i < 10; i++) { - count[i] += count[i - 1]; - } - - for (int i = size - 1; i >= 0; i--) { - int digitValue = (array[i] / digit) % 10; - output[count[digitValue] - 1] = array[i]; - count[digitValue]--; - } - - for (int i = 0; i < size; i++) { - array[i] = output[i]; - } - } - - public static void main(String[] args) { - int[] arr = {170, 45, 75, 90, 802, 24, 2, 66}; - radixSort(arr); - System.out.println(Arrays.toString(arr)); - } -} -``` - -#### JavaScript Code Implementation - -```javascript -function countingSortByDigit(array, digit) { - const size = array.length; - const output = new Array(size); - const count = new Array(10).fill(0); - - // Count occurrences of each digit - for (let i = 0; i < size; i++) { - const digitValue = Math.floor((array[i] / digit) % 10); - count[digitValue]++; - } - - // Update count array to get the actual position of digits - for (let i = 1; i < 10; i++) { - count[i] += count[i - 1]; - } - - // Build the output array - for (let i = size - 1; i >= 0; i--) { - const digitValue = Math.floor((array[i] / digit) % 10); - output[count[digitValue] - 1] = array[i]; - count[digitValue]--; - } - - // Copy the output array to the original array - for (let i = 0; i < size; i++) { - array[i] = output[i]; - } -} - -function radixSort(array) { - const maxNumber = Math.max(...array); - for (let digit = 1; Math.floor(maxNumber / digit) > 0; digit *= 10) { - countingSortByDigit(array, digit); - } -} - -// Example usage -const arr = [170, 45, 75, 90, 802, 24, 2, 66]; -radixSort(arr); -console.log(arr.join(" ")); // Output: 2 24 45 66 75 90 170 802 -``` - -### Explanation of the Code - -1. **Function `countingSortByDigit`**: - - This function sorts the `array` based on the specified `digit`. - - It initializes an output array and a count array to store occurrences of digits. - -2. **Counting Occurrences**: - - For each element, it extracts the digit value and increments the corresponding count. - -3. **Building the Output Array**: - - It calculates the actual positions of each digit by accumulating the counts. - - Then it builds the output array by placing each element in its correct position based on the current digit. - -4. **Copying the Output**: - - Finally, it copies the sorted output back to the original array. - -5. **Function `radixSort`**: - - This function finds the maximum number in the array to determine the number of digits. - - It repeatedly calls `countingSortByDigit`, incrementing the digit value by a factor of 10 each time. - -6. **Example Usage**: - - An example array `arr` is sorted using `radixSort`, and the sorted array is printed to the console. - - -### Complexity of Radix Sort - -- **Time Complexity**: $O(d⋅(n+k))$ - - $d$ : Number of digits in the largest number. - - $n$ : Number of elements in the array. - - $k$ : Range of the digits for decimal system, $k = 10.$ -- **Space Complexity**: $O(n + k)$ - - $n$ : Number of elements in the array. - - $k$ : Range of the digits for decimal system, $k = 10.$ - -### Conclusion - -Radix sort is a powerful sorting algorithm for integers or fixed-length strings. Its efficiency and non-comparative nature make it a valuable tool for specific use cases, especially where the number of digits or characters is limited. Understanding and implementing radix sort can significantly enhance the performance of sorting operations in such scenarios. \ No newline at end of file diff --git a/docs/basic-dsa/matrix-data-structure.md b/docs/basic-dsa/matrix-data-structure.md deleted file mode 100644 index e692f94aa..000000000 --- a/docs/basic-dsa/matrix-data-structure.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: matrix-data-structure -sidebar_position: 1 -title: matrix-ds -sidebar_label: Matrix Data Structure -description: "One more of the basic Data Structure is Matrix Data structure and we'll know more about it." -tags: [dsa, Matrix, DataStructure] ---- - -A **matrix** is a two-dimensional data structure that consists of rows and columns, forming a rectangular arrangement of numbers or other elements. Matrices are widely used in mathematics, computer science, engineering, and various applications such as graphics, machine learning, and optimization. - -## Key Characteristics - -1. **Dimensions**: A matrix is defined by its dimensions, expressed as `m x n`, where `m` is the number of rows and `n` is the number of columns. For example, a matrix with 3 rows and 4 columns is referred to as a `3 x 4` matrix. - -2. **Elements**: Each individual item in a matrix is called an element. The element located at row `i` and column `j` is often denoted as `A[i][j]`. - -3. **Types of Matrices**: - - **Row Matrix**: A matrix with only one row (e.g., `1 x n`). - - **Column Matrix**: A matrix with only one column (e.g., `m x 1`). - - **Square Matrix**: A matrix with the same number of rows and columns (e.g., `n x n`). - - **Diagonal Matrix**: A square matrix where all elements outside the main diagonal are zero. - - **Identity Matrix**: A diagonal matrix where all the elements of the main diagonal are `1`. - - **Zero Matrix**: A matrix in which all elements are zero. - -## Representation -In programming languages, matrices can be represented using arrays or lists. For example, in Python, a matrix can be represented using a list of lists: - -```python -# Example of a 2x3 matrix -matrix = [ - [1, 2, 3], - [4, 5, 6] -] -``` -# Matrix Operations and Applications - -In this example, the first row contains the elements 1, 2, and 3, while the second row contains 4, 5, and 6. - -## Operations on Matrices - -Several operations can be performed on matrices, including: - -1. **Addition**: Two matrices of the same dimensions can be added together by adding their corresponding elements. - - $$C[i][j] = A[i][j] + B[i][j]$$ - -2. **Subtraction**: Similar to addition, two matrices of the same dimensions can be subtracted. - - - $$C[i][j] = A[i][j] - B[i][j]$$ - - -3. **Multiplication**: Matrix multiplication involves the dot product of rows and columns. A matrix with dimensions m x n can be multiplied by a matrix with dimensions n x p to produce a resulting matrix of dimensions m x p. - - - $$C[i][j] = '\sum_{k=1}^{n} A[i][k] \times B[k][j]'$$ - - -4. **Transposition**: The transpose of a matrix is formed by swapping its rows and columns. For a matrix A, the transpose is denoted as A^T. - - $$(A^T)[i][j] = A[j][i]$$ - - -5. **Determinant**: A scalar value that can be computed from a square matrix, providing information about the matrix properties, such as whether it is invertible. - -6. **Inverse**: The inverse of a square matrix A is a matrix B such that A * B = I, where I is the identity matrix. Not all matrices have an inverse. - -## Applications - -Matrices are used in various fields and applications, including: - -- **Computer Graphics**: To perform transformations such as translation, rotation, and scaling. -- **Machine Learning**: In algorithms involving linear regression, neural networks, and more. -- **Physics and Engineering**: To model systems and solve equations. -- **Statistics**: In multivariate analysis and data representation. - -## Conclusion - -Matrices are fundamental data structures in both theoretical and applied contexts. Understanding how to manipulate and utilize matrices is essential for many fields in computer science and mathematics. diff --git a/docs/basic-dsa/pointer.md b/docs/basic-dsa/pointer.md deleted file mode 100644 index 92ed36063..000000000 --- a/docs/basic-dsa/pointer.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: programming-fundamentals -title: References and Pointers in C++ -sidebar_label: Introduction to References and Pointers -sidebar_position: 2 -description: 'Both references and pointers are powerful features in C++ that allow you to manipulate memory and create more efficient programs. Understanding the differences between them and knowing when to use each is crucial for effective C++ programming' -tags: [dsa, data-structures, Pointers] ---- - - -## 1. What are References and Pointers in C++? - -In C++, both references and pointers are used to refer to memory locations, but they have different properties and uses. - -- **References**: An alias for another variable. -- **Pointers**: A variable that holds the memory address of another variable. - - - -## 2. Declaring References and Pointers - -### Declaring References - -A reference is declared using the `&` operator. - -**Syntax:** - -```cpp -datatype &referenceName = variableName; -``` - -**Example:** - -```cpp -#include -using namespace std; - -int main() { - int a = 10; - int &ref = a; // ref is a reference to a - cout << "a: " << a << endl; // Output: 10 - cout << "ref: " << ref << endl; // Output: 10 - return 0; -} -``` - -### Declaring Pointers - -A pointer is declared using the `*` operator. - -**Syntax:** - -```cpp -datatype *pointerName; -``` - -**Example:** - -```cpp -#include -using namespace std; - -int main() { - int a = 10; - int *ptr = &a; // ptr holds the address of a - cout << "a: " << a << endl; // Output: 10 - cout << "ptr: " << ptr << endl; // Output: address of a - cout << "*ptr: " << *ptr << endl; // Output: 10 - return 0; -} -``` - -## 3. Differences Between References and Pointers - -### 1. Syntax and Usage - -- **References**: Use the `&` operator for declaration and do not require dereferencing. -- **Pointers**: Use the `*` operator for declaration and require dereferencing with `*`. - -**Example:** - -```cpp -int a = 5; -int &ref = a; // Reference -int *ptr = &a; // Pointer -``` - -### 2. Initialization - -- **References**: Must be initialized when declared. -- **Pointers**: Can be declared without initialization and assigned later. - -**Example:** - -```cpp -int a = 5; -int &ref = a; // Must be initialized -int *ptr; // Can be declared without initialization -ptr = &a; // Assigned later -``` - -### 3. Reassignment - -- **References**: Cannot be reassigned to refer to another variable. -- **Pointers**: Can be reassigned to point to different variables. - -**Example:** - -```cpp -int a = 5, b = 10; -int &ref = a; // Reference to a -// ref = b; // Error: Cannot reassign a reference - -int *ptr = &a; // Pointer to a -ptr = &b; // Pointer reassigned to b -``` - -### 4. Null Values - -- **References**: Cannot be null. -- **Pointers**: Can be null (useful to indicate that they are not pointing to any valid memory). - -**Example:** - -```cpp -int a = 5; -int &ref = a; // Reference cannot be null - -int *ptr = nullptr; // Pointer can be null -ptr = &a; // Pointer assigned to a valid address -``` - -### 5. Memory Address - -- **References**: Implicitly provide the memory address of the referenced variable. -- **Pointers**: Explicitly hold and can be used to manipulate memory addresses. - -**Example:** - -```cpp -int a = 5; -int &ref = a; // Reference to a -int *ptr = &a; // Pointer to a - -cout << "Address of a: " << &a << endl; -cout << "Address using ref: " << &ref << endl; -cout << "Address using ptr: " << ptr << endl; -``` - -## 4. When to Use References and Pointers - -### Use References: -- When you need an alias for another variable. -- When you want to avoid null checks and pointer arithmetic. -- For pass-by-reference in function arguments to avoid copying large objects. - -### Use Pointers: -- When you need to allocate memory dynamically. -- When you need to implement data structures like linked lists, trees, etc. -- When you need to use null values to indicate "no object". - -## 5. Examples - -### Example 1: Using References - -```cpp -#include -using namespace std; - -void increment(int &ref) { - ref++; -} - -int main() { - int a = 10; - increment(a); - cout << "a: " << a << endl; // Output: 11 - return 0; -} -``` -### Example 2: Using Pointers -```cpp -#include -using namespace std; -void increment(int *ptr) { - (*ptr)++; -} -int main() { - int a = 10; - increment(&a); - cout << "a: " << a << endl; // Output: 11 - return 0; -} -``` - -## 6. Conclusion - -Both references and pointers are powerful features in C++ that allow you to manipulate memory and create more efficient programs. Understanding the differences between them and knowing when to use each is crucial for effective C++ programming diff --git a/docs/binary-search-tree/Binary search tree.md b/docs/binary-search-tree/Binary search tree.md deleted file mode 100644 index 2ad9306cf..000000000 --- a/docs/binary-search-tree/Binary search tree.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -id: bst-intro -sidebar_position: 1 -title: Binary Search Trees -sidebar_label: Binary Search Trees -description: "In this blog post, we'll explore binary search trees (BSTs), a special type of binary tree that allows for efficient searching, insertion, and deletion of elements." -tags: [dsa, data structures, bst] ---- - -## Introduction -A **Binary Search Tree (BST)** is a type of binary tree where each node follows a specific ordering property: -- All the values in the left subtree are less than the root node. -- All the values in the right subtree are greater than the root node. - -This structure makes it efficient for performing operations like searching, insertion, and deletion. BSTs are an important part of computer science and widely used in various applications like databases and search engines. - -## Definition and Structure -A binary search tree consists of nodes, where each node contains: -- **Data:** The value stored in the node. -- **Left Child:** A reference to the left subtree (containing nodes with smaller values). -- **Right Child:** A reference to the right subtree (containing nodes with larger values). - -The hierarchical structure begins with the root node and follows the binary search property across all nodes. - -## Properties -Some important properties of binary search trees include: -- **Height:** The length of the longest path from the root to a leaf. A balanced BST will have a height of log(n), where n is the number of nodes. -- **Depth:** The number of edges from the root to a given node. The root has a depth of 0. -- **Balanced Trees:** A tree is considered balanced when the heights of the left and right subtrees of any node differ by at most one. This ensures the best performance for all operations. - - ``` - 10 - / \ - 5 20 - / \ \ - 2 7 25 - - Height of the tree: 2 - Depth of node 7: 2 - Balanced: Yes - ``` - -## Types of Binary Search Trees -1. **Unbalanced BST:** A BST that has nodes unevenly distributed, which can degrade performance to O(n) in the worst case. - ``` - 1 - \ - 2 - \ - 3 - \ - 4 - ``` - -2. **Self-Balancing BST:** These trees automatically balance themselves, ensuring that the height remains logarithmic. Examples include: - - **AVL Trees**: Ensures that the difference in heights of left and right subtrees is at most 1. - - **Red-Black Trees**: Ensures balanced height using color properties at nodes. - -## Operations on Binary Search Trees - -### 1. Insertion -To insert a new value into the BST: -- If the tree is empty, the new value becomes the root. -- If the new value is smaller than the root, recursively insert it in the left subtree. -- If the new value is greater than the root, recursively insert it in the right subtree. - -#### Code Example (C++) - -```cpp -Node* insert(Node* root, int key) { - if (root == nullptr) { - return new Node(key); - } - - if (key < root->data) { - root->left = insert(root->left, key); - } else if (key > root->data) { - root->right = insert(root->right, key); - } - - return root; -} -``` -### 2. Searching -Searching is a core operation in a **Binary Search Tree (BST)**. The structure of the BST makes searching efficient when the tree is balanced. - -### Searching in a Binary Search Tree -The search process in a BST leverages its structural properties: -- The left subtree contains only values smaller than the root. -- The right subtree contains only values larger than the root. - -### Steps to Search: -1. **Start at the root node.** -2. **Compare** the target value with the root node: - - If the target is **equal** to the root's value, return the node. - - If the target is **less than** the root's value, search the left subtree. - - If the target is **greater than** the root's value, search the right subtree. -3. If the target value is not found, return `false`. - -### C++ Implementation - -#### Recursive Search in C++ -The recursive approach reduces the problem size at each step by calling the function on the left or right subtree based on the comparison. - -```cpp -bool search(Node* root, int key) { - // Base case: root is null or key is present at root - if (root == nullptr) return false; - - // Key found - if (root->data == key) return true; - - // Key is smaller than root's data - if (key < root->data) return search(root->left, key); - - // Key is larger than root's data - return search(root->right, key); -} -``` - - -### 3. Deletion -Deletion is a crucial operation in a **Binary Search Tree (BST)**. Removing a node from a BST must maintain the binary search property: the left subtree contains only values smaller than the root, and the right subtree contains only values larger than the root. - -### Types of Node Deletion in a BST -When deleting a node from a BST, there are three possible cases: - -1. **Node to be deleted is a leaf (has no children).** - - Simply remove the node. - -2. **Node to be deleted has one child.** - - Replace the node with its child. - -3. **Node to be deleted has two children.** - - Find the node's **inorder successor** (smallest node in the right subtree) or **inorder predecessor** (largest node in the left subtree) and replace the node with that value. Then, delete the inorder successor or predecessor. - -### Case 1: Deleting a Leaf Node -If the node to be deleted is a leaf (no children), it can simply be removed from the tree. - -#### Example: -```python - 10 10 - / \ / \ - 5 15 ---------> 5 15 - / \ \ - 12 20 20 - - # Deleting 12 -``` - -### Case 2: Deleting a Node with One Child -If the node to be deleted has one child, replace the node with its child. - -#### Example: -```python - 10 10 - / \ / \ - 5 15 ---------> 5 20 - \ - 20 - - # Deleting 15 -``` - - -### Case 3: Deleting a Node with Two Children -If the node to be deleted has two children, replace it with its **inorder predecessor** (the smallest value in the right subtree). After the replacement, delete the inorder predecessor. - -#### Example: -```python - 10 10 - / \ / \ - 5 15 ---------> 5 12 - / \ \ - 12 20 20 - - # Deleting 15 (12 is inorder predecessor) -``` -### Implementation: -```cpp - Node *InorderPredecessor(Node *node) - { - if (node->left != NULL) - node = node->left; - while (node->right != NULL) - { - if (node->left != NULL) - node = node->left; - else - node = node->right; - } - return node; - } - Node *deletion(Node *node, int key) - { - Node *iPre = new Node; - if (node == NULL) - return NULL; - if (node->left == NULL && node->right == NULL) - { - delete node; - return NULL; - } - if (node->data > key) - node->left = deletion(node->left, key); - else if (node->data < key) - node->right = deletion(node->right, key); - else - { - iPre = InorderPredecessor(node); - node->data = iPre->data; - node->left = deletion(node->left, iPre->data); - } - return node; -} -``` - -## Advantages and Disadvantages -### Advantages: - -- Provides efficient search, insertion, and deletion (O(log n) on average). - -- Maintains data in a sorted manner, allowing for in-order traversal. -### Disadvantages: - -- Can become unbalanced, leading to O(n) worst-case time complexity. -- Extra memory required for storing pointers to left and right children. -## Applications of Binary Search Trees -- **Searching and Sorting:** Efficient for performing binary search and organizing data. -- **Database Indexing:** BSTs help in implementing indexes for fast query retrieval. -- **File Systems:** Used in file systems to maintain directories and files. -- **Priority Queues:** BST-based structures like heaps are used in implementing priority queues. -- **Auto-complete Systems:** Used in search engines to store prefixes of words. \ No newline at end of file diff --git a/docs/binary-search-tree/Post_order_traversal.md b/docs/binary-search-tree/Post_order_traversal.md deleted file mode 100644 index 5b95b818a..000000000 --- a/docs/binary-search-tree/Post_order_traversal.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: postorder-traversal-binary-search-tree -sidebar_position: 18 -title: Post-order Traversal in a Binary Search Tree -sidebar_label: Post-order Traversal in BST -description: "This post explains how to perform Post-order Traversal of a Binary Search Tree (BST) in C++, with code examples and detailed explanations " -tags: [dsa, binary trees, postorder, traversal, c++] ---- - -In this post, we will discuss how to perform **Post-order Traversal** in a **Binary Search Tree (BST)**. The **Post-order Traversal** visits the nodes in the order: left subtree → right subtree → root. - -## Problem Definition -Given a binary search tree, traverse it using the post-order traversal technique and print the values of the nodes. - -### Approach -The post-order traversal of a binary tree is a depth-first traversal that visits the left subtree, then the right subtree, and finally the root node. - -### Steps: -1. **Recursively traverse the left subtree**. -2. **Recursively traverse the right subtree**. -3. **Visit the root node** (process the node's value). - -### C++ Code Implementation - -```cpp -#include -using namespace std; - -// Definition for a binary search tree node -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Function for post-order traversal of the BST -void postOrderTraversal(TreeNode* root) { - if (root == NULL) { - return; - } - - // Traverse left subtree - postOrderTraversal(root->left); - - // Traverse right subtree - postOrderTraversal(root->right); - - // Visit root node - cout << root->val << " "; -} - -int main() { - // Constructing the binary search tree - TreeNode* root = new TreeNode(20); - root->left = new TreeNode(10); - root->right = new TreeNode(30); - root->left->left = new TreeNode(5); - root->left->right = new TreeNode(15); - root->right->right = new TreeNode(35); - - cout << "Post-order Traversal: "; - postOrderTraversal(root); - cout << endl; - - return 0; -} -``` - -## Output: -This will print the values of the nodes in post-order sequence: - -``` -Post-order Traversal: 5 15 10 35 30 20 -``` - -## Explanation: -First, the left subtree (5, 15, 10) is traversed. -Next, the right subtree (35, 30) is traversed. -Finally, the root node (20) is processed. diff --git a/docs/binary-search-tree/Problem-Practice.md b/docs/binary-search-tree/Problem-Practice.md deleted file mode 100644 index 425c85ecb..000000000 --- a/docs/binary-search-tree/Problem-Practice.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: Practice-Problems-on-binary-search-tree -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 2 -description: Practice problems for Binary Search Tree (BST), categorized by difficulty and topic. These problems help in understanding the structure and operations of BSTs. -tags: [DSA, algorithms, binary search tree] ---- - -## Practice Problems on Binary Search Tree (BST) - -Binary Search Trees (BSTs) are a fundamental data structure in computer science. They allow for efficient searching, insertion, and deletion of elements. Here’s a collection of practice problems that will help you master the various aspects of working with Binary Search Trees. The problems are grouped by difficulty, enabling you to build your skills progressively. - ---- - -### Basic Problems: - -These problems will introduce you to basic Binary Search Tree operations and properties. They are ideal for beginners who are just getting started with BSTs. - -- **[Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree?envType=problem-list-v2&envId=binary-search-tree&difficulty=EASY):** - Convert a sorted array into a height-balanced binary search tree, practicing the conversion of linear data structures into trees. - -- **[Closest Binary Search Tree Value](https://leetcode.com/problems/closest-binary-search-tree-value?envType=problem-list-v2&envId=binary-search-tree&difficulty=EASY):** - Find the closest value in a BST to a given target value. This problem tests your ability to navigate the tree structure efficiently. - -- **[Find Mode in Binary Search Tree](https://leetcode.com/problems/find-mode-in-binary-search-tree?envType=problem-list-v2&envId=binary-search-tree&difficulty=EASY):** - Find the mode (most frequent value) in a BST. The problem tests traversal methods and counting techniques. - -- **[Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst?envType=problem-list-v2&envId=binary-search-tree&difficulty=EASY):** - Find the minimum absolute difference between values of any two nodes in a BST. This is a good problem to practice in-order traversal. - -- **[Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst?envType=problem-list-v2&envId=binary-search-tree&difficulty=EASY):** - Given a target value, determine if there exist two elements in a BST that sum up to the target. This problem combines BST traversal with the two-sum technique. - ---- - -### Intermediate Problems: - -These problems require a deeper understanding of BST properties and involve more complex operations such as tree generation, validation, and modifications. - -- **[Unique Binary Search Trees II](https://leetcode.com/problems/unique-binary-search-trees-ii?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Generate all structurally unique BSTs that store values from 1 to n. This problem tests your ability to generate trees recursively. - -- **[Unique Binary Search Trees](https://leetcode.com/problems/unique-binary-search-trees?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Calculate the number of unique BSTs that can be formed with n nodes. This is an exercise in understanding tree permutations and combinatorics. - -- **[Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Validate if a given binary tree is a valid BST. This is a fundamental problem to test your understanding of the BST property. - -- **[Recover Binary Search Tree](https://leetcode.com/problems/recover-binary-search-tree?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Given a BST where two nodes are swapped by mistake, recover the tree without modifying its structure. This problem requires careful analysis of in-order traversal. - -- **[Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Convert a sorted linked list into a height-balanced BST. This problem combines list manipulation with tree generation. - ---- - -### Advanced Problems: - -These problems require advanced techniques and a solid understanding of BST operations. They often involve more than one data structure or sophisticated operations. - -- **[Two Sum BSTs](https://leetcode.com/problems/two-sum-bsts?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Given two binary search trees, determine if there exist two elements (one from each tree) that add up to a target value. - -- **[Balance a Binary Search Tree](https://leetcode.com/problems/balance-a-binary-search-tree?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Convert an unbalanced BST into a balanced BST while maintaining its elements' order. - -- **[All Elements in Two Binary Search Trees](https://leetcode.com/problems/all-elements-in-two-binary-search-trees?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Return all elements from two BSTs in sorted order. This problem requires merging two trees and producing sorted output efficiently. - -- **[Binary Search Tree Iterator II](https://leetcode.com/problems/binary-search-tree-iterator-ii?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Implement an iterator over a binary search tree (BST) that supports the `next()`, `hasNext()`, `prev()`, and `hasPrev()` operations. - -- **[Depth of BST Given Insertion Order](https://leetcode.com/problems/depth-of-bst-given-insertion-order?envType=problem-list-v2&envId=binary-search-tree&difficulty=MEDIUM):** - Given the insertion order of a BST, calculate the depth of the resulting tree. This problem explores the relationship between insertion order and tree depth. - ---- - -### Challenges: - -These problems are for those looking for extra challenges that test edge cases or involve difficult operations on BSTs. - -- **[Closest Binary Search Tree Value II](https://leetcode.com/problems/closest-binary-search-tree-value-ii?envType=problem-list-v2&envId=binary-search-tree&difficulty=HARD):** - Given a target value and a BST, find the k values in the BST that are closest to the target. - -- **[Maximum Sum BST in Binary Tree](https://leetcode.com/problems/maximum-sum-bst-in-binary-tree?envType=problem-list-v2&envId=binary-search-tree&difficulty=HARD):** - Given a binary tree, return the maximum sum of all keys of any subtree that is also a Binary Search Tree (BST). - -- **[Number of Ways to Reorder Array to Get Same BST](https://leetcode.com/problems/number-of-ways-to-reorder-array-to-get-same-bst?envType=problem-list-v2&envId=binary-search-tree&difficulty=HARD):** - Given an array of numbers, return the number of ways to reorder the array such that the constructed BST is identical to the original one. - ---- - -These problems will help you develop a strong understanding of Binary Search Trees, a crucial data structure in many algorithmic problems. Happy coding! diff --git a/docs/binary-search-tree/_category_.json b/docs/binary-search-tree/_category_.json deleted file mode 100644 index 8878305df..000000000 --- a/docs/binary-search-tree/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Binary Search Tree", - "position": 7, - "link": { - "type": "generated-index", - "description": "A **Binary Search Tree (BST)** is a type of binary tree where each node follows a specific ordering property: 1. All the values in the left subtree are less than the root node. 2. All the values in the right subtree are greater than the root node." - } -} diff --git a/docs/binary-search-tree/avl-tree.md b/docs/binary-search-tree/avl-tree.md deleted file mode 100644 index 4cea401b3..000000000 --- a/docs/binary-search-tree/avl-tree.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -id: avl-tree-intro -sidebar_position: 16 -title: AVL Trees -sidebar_label: AVL Trees -description: "In this blog post, we'll explore AVL trees, a type of self-balancing binary search tree that ensures efficient searching, insertion, and deletion operations." -tags: [dsa, data structures, avl] ---- - -## Introduction -An **AVL Tree** is a self-balancing binary search tree (BST) where the difference in heights between the left and right subtrees of any node is at most one. This balancing property ensures that the tree remains approximately balanced after insertions and deletions, resulting in efficient operations. AVL trees are named after their inventors, Georgy Adelson-Velsky and Evgenii Landis, who introduced this data structure in 1962. - -## Definition and Structure -An AVL tree consists of nodes similar to a BST, but with an added balance factor for each node: -- **Data:** The value stored in the node. -- **Left Child:** A reference to the left subtree (containing nodes with smaller values). -- **Right Child:** A reference to the right subtree (containing nodes with larger values). -- **Balance Factor:** The height difference between the left and right subtrees, calculated as `height(left subtree) - height(right subtree)`. - -The AVL tree maintains this balance factor throughout all operations, ensuring that the height remains logarithmic. - -## Properties -Some important properties of AVL trees include: -- **Height:** The height of an AVL tree with `n` nodes is guaranteed to be O(log n). -- **Balance Factor:** For any node, the balance factor must be -1, 0, or +1. -- **Rotations:** To maintain balance during insertions and deletions, AVL trees utilize rotations (single and double) to rebalance the tree. - - ``` - 10 - / \ - 5 20 - / \ / \ - 2 7 15 25 - - Height of the tree: 2 - Balance Factor of node 10: 0 - Balanced: Yes - ``` - -## Types of Rotations -1. **Single Right Rotation (LL Rotation)**: Performed when a left-heavy subtree becomes unbalanced due to an insertion in the left child. - - ![LL Rotation](https://images.javatpoint.com/ds/images/avl-tree2.jpg) - -2. **Single Left Rotation (RR Rotation)**: Performed when a right-heavy subtree becomes unbalanced due to an insertion in the right child. - - ![RR Rotation](https://media.geeksforgeeks.org/wp-content/uploads/20221229131815/avl11-(1)-768.png) - -3. **Left-Right Rotation (LR Rotation)**: Performed when a left-heavy subtree becomes unbalanced due to an insertion in the right child of the left child. - - ![LR Rotation](https://media.geeksforgeeks.org/wp-content/uploads/20221229131629/avl33-(1)-768.png) - -4. **Right-Left Rotation (RL Rotation)**: Performed when a right-heavy subtree becomes unbalanced due to an insertion in the left child of the right child. - - ![RL Rotation](https://media.geeksforgeeks.org/wp-content/uploads/20221229131517/avl44-(1)-768.png) - -## Operations on AVL Trees - -### 1. Insertion -To insert a new value into an AVL tree: -- Insert it like a regular BST. -- After insertion, update the heights and balance factors of nodes along the path back to the root. -- Perform rotations as necessary to maintain the AVL balance property. - -#### Code Example (C++) - -```cpp -Node* insert(Node* root, int key) { - // Regular BST insertion - if (root == nullptr) { - return new Node(key); - } - - if (key < root->data) { - root->left = insert(root->left, key); - } else if (key > root->data) { - root->right = insert(root->right, key); - } else { - return root; // Duplicate keys not allowed - } - - // Update height and balance factor - updateHeight(root); - - // Perform rotations to balance the tree - return balance(root); -} -``` - -### 2. Searching -Searching in an AVL tree is similar to searching in a standard BST due to its structure: -1. Start at the root node. -2. Compare the target value with the root node: - - If equal, return the node. - - If less, search the left subtree. - - If greater, search the right subtree. -3. If the target value is not found, return `false`. - -### C++ Implementation - -```cpp -bool search(Node* root, int key) { - if (root == nullptr) return false; - - if (root->data == key) return true; - - if (key < root->data) return search(root->left, key); - - return search(root->right, key); -} -``` - -### 3. Deletion -Deletion in an AVL tree also follows the binary search tree rules but requires additional steps to maintain balance: -- Delete the node as you would in a BST. -- Update the heights and balance factors. -- Perform rotations if necessary. - -### Case 1: Deleting a Leaf Node -Simply remove the node. - -### Case 2: Deleting a Node with One Child -Replace the node with its child. - -### Case 3: Deleting a Node with Two Children -Find the inorder predecessor or successor and replace the node, then delete the predecessor or successor. - -#### Implementation: -```cpp -Node* deleteNode(Node* root, int key) { - if (root == nullptr) return nullptr; - - if (key < root->data) { - root->left = deleteNode(root->left, key); - } else if (key > root->data) { - root->right = deleteNode(root->right, key); - } else { - // Node with only one child or no child - if ((root->left == nullptr) || (root->right == nullptr)) { - Node* temp = root->left ? root->left : root->right; - delete root; - return temp; - } - - // Node with two children: Get the inorder successor - Node* temp = minValueNode(root->right); - root->data = temp->data; - root->right = deleteNode(root->right, temp->data); - } - - // Update height and balance - updateHeight(root); - return balance(root); -} -``` - -## Advantages and Disadvantages -### Advantages: -- Ensures O(log n) time complexity for search, insertion, and deletion due to strict balancing. -- Self-balancing eliminates the possibility of degradation into a linked list structure. - -### Disadvantages: -- More complex to implement compared to standard binary search trees. -- Additional memory required for storing height information and more rotations may increase overhead. - -## Applications of AVL Trees -- **Database Indexing:** Used in databases to maintain sorted data for efficient retrieval. -- **Memory Management:** Employed in dynamic memory allocation algorithms. -- **Auto-complete Systems:** Utilized in applications that require efficient prefix searches. -- **Routing Algorithms:** Applied in network routing protocols where balanced trees improve efficiency. - -AVL trees are a powerful data structure that combines the advantages of binary search trees with the need for balance, ensuring efficient operations across various applications. \ No newline at end of file diff --git a/docs/binary-search-tree/delete-BST.md b/docs/binary-search-tree/delete-BST.md deleted file mode 100644 index 1cfb10643..000000000 --- a/docs/binary-search-tree/delete-BST.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -id: delete-binary-search-tree -sidebar_position: 15 -title: Delete in a Binary Search Tree -sidebar_label: Delete in BST -description: "This blog post covers how to delete a value from a Binary Search Tree (BST) in C++, along with explanations and code examples." -tags: [dsa, binary trees, delete, c++] ---- - -In this post, we will discuss how to delete a specific value from a **Binary Search Tree (BST)**. A BST is a special kind of binary tree where each node has a value greater than all values in its left subtree and less than all values in its right subtree. - -## Problem Definition -Given a binary search tree and a value to delete, the goal is to remove the node containing the value from the tree while maintaining the BST properties. If the value does not exist in the tree, we do nothing. - -## Approach -To delete a value from a BST, we need to consider three scenarios based on the node to be deleted: - -1. **Node with no children (leaf node):** Simply remove the node. -2. **Node with one child:** Remove the node and link its parent to its child. -3. **Node with two children:** Find the inorder successor (smallest value in the right subtree) or inorder predecessor (largest value in the left subtree) to replace the node's value, and then delete the successor/predecessor. - -### Steps: -1. Start from the root node. -2. If the current node is `NULL`, return `NULL`. -3. Compare the value to delete with the current node's value: - - If they are equal, handle the three scenarios outlined above. - - If the value is less, move to the left child. - - If the value is greater, move to the right child. -4. Repeat until you find the node to delete. - -### C++ Code Implementation - -```cpp -#include -using namespace std; - -// Definition for a binary search tree node -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Function to find the minimum value node in a BST -TreeNode* minValueNode(TreeNode* node) { - TreeNode* current = node; - while (current && current->left != NULL) { - current = current->left; - } - return current; -} - -// Function to delete a value from a binary search tree -TreeNode* deleteBST(TreeNode* root, int val) { - if (root == NULL) { - return root; - } - - // If the value to be deleted is smaller than the root's value - if (val < root->val) { - root->left = deleteBST(root->left, val); - } - // If the value to be deleted is greater than the root's value - else if (val > root->val) { - root->right = deleteBST(root->right, val); - } - // Value is found - else { - // Node with only one child or no child - if (root->left == NULL) { - TreeNode* temp = root->right; - delete root; - return temp; - } else if (root->right == NULL) { - TreeNode* temp = root->left; - delete root; - return temp; - } - - // Node with two children: Get the inorder successor (smallest in the right subtree) - TreeNode* temp = minValueNode(root->right); - - // Copy the inorder successor's content to this node - root->val = temp->val; - - // Delete the inorder successor - root->right = deleteBST(root->right, temp->val); - } - return root; -} - -int main() { - TreeNode* root = new TreeNode(4); - root->left = new TreeNode(2); - root->right = new TreeNode(7); - root->left->left = new TreeNode(1); - root->left->right = new TreeNode(3); - - int valueToDelete = 2; - root = deleteBST(root, valueToDelete); - - cout << "Value " << valueToDelete << " deleted from the BST." << endl; - - return 0; -} -``` - -### JAVA Code Implementation - -```java -import java.util.*; - -class TreeNode { - int val; - TreeNode left, right; - - TreeNode(int x) { - val = x; - left = right = null; - } -} - -public class BinarySearchTree { - - // Function to find the minimum value node in a BST - TreeNode minValueNode(TreeNode node) { - TreeNode current = node; - while (current != null && current.left != null) { - current = current.left; - } - return current; - } - - // Function to delete a value from a binary search tree - TreeNode deleteBST(TreeNode root, int val) { - if (root == null) { - return root; - } - - // If the value to be deleted is smaller than the root's value - if (val < root.val) { - root.left = deleteBST(root.left, val); - } - // If the value to be deleted is greater than the root's value - else if (val > root.val) { - root.right = deleteBST(root.right, val); - } - // Value is found - else { - // Node with only one child or no child - if (root.left == null) { - return root.right; - } else if (root.right == null) { - return root.left; - } - - // Node with two children: Get the inorder successor (smallest in the right subtree) - TreeNode temp = minValueNode(root.right); - - // Copy the inorder successor's content to this node - root.val = temp.val; - - // Delete the inorder successor - root.right = deleteBST(root.right, temp.val); - } - - return root; - } - - // Helper function to perform in-order traversal to print the BST - void inorderTraversal(TreeNode root) { - if (root != null) { - inorderTraversal(root.left); - System.out.print(root.val + " "); - inorderTraversal(root.right); - } - } - - public static void main(String[] args) { - BinarySearchTree bst = new BinarySearchTree(); - - TreeNode root = new TreeNode(4); - root.left = new TreeNode(2); - root.right = new TreeNode(7); - root.left.left = new TreeNode(1); - root.left.right = new TreeNode(3); - - System.out.println("Original BST (in-order traversal): "); - bst.inorderTraversal(root); - System.out.println(); - - int valueToDelete = 2; - root = bst.deleteBST(root, valueToDelete); - - System.out.println("BST after deletion of value " + valueToDelete + " (in-order traversal): "); - bst.inorderTraversal(root); - } -} -``` diff --git a/docs/binary-search-tree/inorder-predecessor-BST.md b/docs/binary-search-tree/inorder-predecessor-BST.md deleted file mode 100644 index 74cf3fae7..000000000 --- a/docs/binary-search-tree/inorder-predecessor-BST.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -id: inorder-predecessor-binary-search-tree -sidebar_position: 16 -title: Inorder Predecessor in a Binary Search Tree -sidebar_label: Inorder Predecessor in BST -description: "This post explains how to find the Inorder Predecessor of a node in a Binary Search Tree (BST) in C++, with code examples and detailed explanations." -tags: [dsa, binary trees, inorder, predecessor, c++] ---- - -In this post, we will discuss how to find the **Inorder Predecessor** of a given node in a **Binary Search Tree (BST)**. The **Inorder Predecessor** of a node is the node that comes immediately before the given node in the in-order traversal of the BST. - -## Problem Definition -Given a node in a binary search tree, find its in-order predecessor. If the given node does not have an in-order predecessor, return `NULL`. - -- The in-order traversal of a binary tree visits the nodes in ascending order (left → root → right). -- The in-order predecessor of a node is the largest node that is smaller than the given node. - -## Approach -To find the in-order predecessor of a node in a BST, we need to consider two cases: - -1. **The node has a left subtree**: - - The in-order predecessor is the rightmost (maximum) node in the left subtree. - -2. **The node does not have a left subtree**: - - We traverse up the tree from the node's parent. The in-order predecessor is the last ancestor for which the node was in the right subtree. - -### Steps: -1. **If the node has a left subtree**: - - Move to the left child and then find the rightmost node in the left subtree. - -2. **If the node does not have a left subtree**: - - Move upwards from the node. Traverse up the ancestors until you find a node that is the right child of its parent. That parent will be the in-order predecessor. - -### C++ Code Implementation - -```cpp -#include -using namespace std; - -// Definition for a binary search tree node -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Helper function to find the rightmost node in a subtree -TreeNode* findMax(TreeNode* node) { - while (node->right != NULL) { - node = node->right; - } - return node; -} - -// Function to find the inorder predecessor of a given node in BST -TreeNode* inorderPredecessor(TreeNode* root, TreeNode* node) { - // Case 1: If there is a left subtree, find the max in that subtree - if (node->left != NULL) { - return findMax(node->left); - } - - // Case 2: If no left subtree, find the deepest ancestor for which the node is in the right subtree - TreeNode* predecessor = NULL; - while (root != NULL) { - if (node->val > root->val) { - predecessor = root; // Potential predecessor - root = root->right; // Move right - } else if (node->val < root->val) { - root = root->left; // Move left - } else { - break; - } - } - - return predecessor; -} - -int main() { - TreeNode* root = new TreeNode(20); - root->left = new TreeNode(10); - root->right = new TreeNode(30); - root->left->left = new TreeNode(5); - root->left->right = new TreeNode(15); - root->right->right = new TreeNode(35); - - TreeNode* node = root->left->right; // Node with value 15 - - TreeNode* predecessor = inorderPredecessor(root, node); - - if (predecessor != NULL) { - cout << "Inorder Predecessor of node " << node->val << " is " << predecessor->val << endl; - } else { - cout << "Inorder Predecessor of node " << node->val << " does not exist." << endl; - } - - return 0; -} -``` \ No newline at end of file diff --git a/docs/binary-search-tree/inorder-successor-BST.md b/docs/binary-search-tree/inorder-successor-BST.md deleted file mode 100644 index e638c01c4..000000000 --- a/docs/binary-search-tree/inorder-successor-BST.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: inorder-successor-binary-search-tree -sidebar_position: 17 -title: Inorder Successor in a Binary Search Tree -sidebar_label: Inorder Successor in BST -description: "This post explains how to find the Inorder Successor of a node in a Binary Search Tree (BST) in C++, with code examples and detailed explanations." -tags: [dsa, binary trees, inorder, successor, c++] ---- - -In this post, we will discuss how to find the **Inorder Successor** of a given node in a **Binary Search Tree (BST)**. The **Inorder Successor** of a node is the node that comes immediately after the given node in the in-order traversal of the BST. - -## Problem Definition -Given a node in a binary search tree, find its in-order successor. If the given node does not have an in-order successor, return `NULL`. - -- The in-order traversal of a binary tree visits the nodes in ascending order (left → root → right). -- The in-order successor of a node is the smallest node that is greater than the given node. - -## Approach -To find the in-order successor of a node in a BST, we need to consider two cases: - -1. **The node has a right subtree**: - - The in-order successor is the leftmost (minimum) node in the right subtree. - -2. **The node does not have a right subtree**: - - We traverse up the tree from the node's parent. The in-order successor is the last ancestor for which the node was in the left subtree. - -### Steps: -1. **If the node has a right subtree**: - - Move to the right child and then find the leftmost node in the right subtree. - -2. **If the node does not have a right subtree**: - - Move upwards from the node. Traverse up the ancestors until you find a node that is the left child of its parent. That parent will be the in-order successor. - - -### C++ Code Implementation - -```cpp -#include -using namespace std; - -// Definition for a binary search tree node -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Helper function to find the leftmost node in a subtree -TreeNode* findMin(TreeNode* node) { - while (node->left != NULL) { - node = node->left; - } - return node; -} - -// Function to find the inorder successor of a given node in BST -TreeNode* inorderSuccessor(TreeNode* root, TreeNode* node) { - // Case 1: If there is a right subtree, find the min in that subtree - if (node->right != NULL) { - return findMin(node->right); - } - - // Case 2: If no right subtree, find the deepest ancestor for which the node is in the left subtree - TreeNode* successor = NULL; - while (root != NULL) { - if (node->val < root->val) { - successor = root; // Potential successor - root = root->left; // Move left - } else if (node->val > root->val) { - root = root->right; // Move right - } else { - break; - } - } - - return successor; -} - -int main() { - TreeNode* root = new TreeNode(20); - root->left = new TreeNode(10); - root->right = new TreeNode(30); - root->left->left = new TreeNode(5); - root->left->right = new TreeNode(15); - root->right->right = new TreeNode(35); - - TreeNode* node = root->left->right; // Node with value 15 - - TreeNode* successor = inorderSuccessor(root, node); - - if (successor != NULL) { - cout << "Inorder Successor of node " << node->val << " is " << successor->val << endl; - } else { - cout << "Inorder Successor of node " << node->val << " does not exist." << endl; - } - - return 0; -} -``` \ No newline at end of file diff --git a/docs/binary-search-tree/insert-BST.md b/docs/binary-search-tree/insert-BST.md deleted file mode 100644 index 1ca25912e..000000000 --- a/docs/binary-search-tree/insert-BST.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: insert-binary-search-tree -sidebar_position: 14 -title: Insert in a Binary Search Tree -sidebar_label: Insert in BST -description: "This blog post covers how to insert a value in a Binary Search Tree (BST) in C++, along with explanations and code examples." -tags: [dsa, binary trees, insert, c++] ---- - -In this post, we will discuss how to insert a specific value into a **Binary Search Tree (BST)**. A BST is a special kind of binary tree where each node has a value greater than all values in its left subtree and less than all values in its right subtree. - -## Problem Definition -Given a binary search tree and a value to insert, the goal is to place the value in the correct position in the tree while maintaining the BST properties. If the value already exists in the tree, we do not insert it again. - -## Approach -To insert a value in a BST, we can utilize the properties of the BST. Starting from the root node, we compare the value to insert with the value of the current node: - -1. If the value is less than the current node's value, we proceed to the left subtree. -2. If the value is greater than the current node's value, we proceed to the right subtree. -3. If we find a `NULL` position, we insert the new value as a new node. - -### Steps: -1. Start from the root node. -2. If the current node is `NULL`, create a new node with the value and return it. -3. Compare the value to insert with the current node's value: - - If the value is less, move to the left child. - - If the value is greater, move to the right child. -4. Repeat until you find a `NULL` position, then insert the new node. - -### C++ Code Implementation - -```cpp -#include -using namespace std; - -// Definition for a binary search tree node -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Function to insert a value in a binary search tree -TreeNode* insertBST(TreeNode* root, int val) { - // If the current node is NULL, create a new node - if (root == NULL) { - return new TreeNode(val); - } - - // If the value is less, go to the left subtree - if (val < root->val) { - root->left = insertBST(root->left, val); - } else if (val > root->val) { // If the value is greater, go to the right subtree - root->right = insertBST(root->right, val); - } - - // Return the unchanged node pointer - return root; -} - -int main() { - TreeNode* root = new TreeNode(4); - root->left = new TreeNode(2); - root->right = new TreeNode(7); - root->left->left = new TreeNode(1); - root->left->right = new TreeNode(3); - - int valueToInsert = 5; - root = insertBST(root, valueToInsert); - - cout << "Value " << valueToInsert << " inserted in the BST." << endl; - - return 0; -} -``` \ No newline at end of file diff --git a/docs/binary-search-tree/red-black-trees.md b/docs/binary-search-tree/red-black-trees.md deleted file mode 100644 index 3e8a15ec2..000000000 --- a/docs/binary-search-tree/red-black-trees.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -id: rbt-intro -sidebar_position: 17 -title: Red-Black Trees -sidebar_label: Red-Black Trees -description: "In this blog post, we'll explore Red-Black trees, a type of self-balancing binary search tree that guarantees logarithmic time complexity for search, insertion, and deletion operations." -tags: [dsa, data structures, rbt] ---- - -A **Red-Black Tree (RBT)** is a self-balancing binary search tree (BST) that ensures the tree remains approximately balanced after insertions and deletions. The primary goal of a Red-Black Tree is to keep the height of the tree O(log n), ensuring efficient operations. - -Each node in a Red-Black Tree has an additional property: a color, which is either **red** or **black**. The tree follows specific rules regarding the colors, which ensures that it remains balanced. - -## Properties of Red-Black Trees - -1. **Every node is either red or black.** -2. **The root is always black.** -3. **Every leaf (null node) is black.** -4. **Red nodes cannot have red children** (no two red nodes appear consecutively along a path). -5. **Every path from a node to its descendant leaves has the same number of black nodes**. - -These properties ensure that the longest path from the root to a leaf is no more than twice as long as the shortest path, guaranteeing O(log n) height. - -## Definition and Structure - -A Red-Black Tree consists of nodes with the following attributes: -- **Data:** The value stored in the node. -- **Left Child:** A reference to the left subtree. -- **Right Child:** A reference to the right subtree. -- **Color:** Each node is either red or black, maintaining the Red-Black properties. - -## Types of Rotations - -To maintain balance, Red-Black Trees utilize rotations similar to AVL Trees. These include: - -1. **Left Rotation**: Shifts the tree to the left when a right-heavy subtree becomes unbalanced. -2. **Right Rotation**: Shifts the tree to the right when a left-heavy subtree becomes unbalanced. -3. **Left-Right Rotation**: A left rotation followed by a right rotation, used when a left-heavy subtree's right child causes imbalance. -4. **Right-Left Rotation**: A right rotation followed by a left rotation, used when a right-heavy subtree's left child causes imbalance. - -## Operations on Red-Black Trees - -### 1. Insertion - -Inserting a new node into a Red-Black Tree involves several steps: - -- Insert the new node as you would in a regular BST. -- Color the new node red. -- Fix any violations of the Red-Black properties by adjusting the tree with recoloring and rotations. - -#### Code Example (C++) - -```cpp -struct Node { - int data; - Node* left; - Node* right; - bool isRed; -}; - -Node* insert(Node* root, int key) { - // Insert like a regular BST node - if (root == nullptr) { - Node* newNode = new Node(); - newNode->data = key; - newNode->left = nullptr; - newNode->right = nullptr; - newNode->isRed = true; // New nodes are always red - return newNode; - } - - if (key < root->data) - root->left = insert(root->left, key); - else if (key > root->data) - root->right = insert(root->right, key); - - // Fix Red-Black properties - return balance(root); -} -``` - -### 2. Searching - -The searching operation in a Red-Black Tree is identical to that of a standard BST. Due to the self-balancing properties of RBTs, the time complexity is guaranteed to be O(log n). - -### Code Example (C++) - -```cpp -bool search(Node* root, int key) { - if (root == nullptr) return false; - - if (root->data == key) return true; - - if (key < root->data) - return search(root->left, key); - - return search(root->right, key); -} -``` - -### 3. Deletion - -Deleting a node from a Red-Black Tree follows the same steps as a standard BST deletion, but with additional balancing to maintain the Red-Black properties. After deletion, the tree may violate the Red-Black rules, so recoloring and rotations are performed to restore balance. - -#### Steps for Deletion: - -1. Remove the node similarly to a regular BST deletion. -2. If the deleted node or its replacement is red, the tree is still balanced. -3. If the deleted node or its replacement is black, the tree needs to be rebalanced through rotations and recoloring. - -### Code Example (C++) - -```cpp -Node* deleteNode(Node* root, int key) { - // Perform standard BST deletion - if (root == nullptr) return nullptr; - - if (key < root->data) - root->left = deleteNode(root->left, key); - else if (key > root->data) - root->right = deleteNode(root->right, key); - else { - if (root->left == nullptr || root->right == nullptr) { - Node* temp = root->left ? root->left : root->right; - delete root; - return temp; - } - - Node* temp = minValueNode(root->right); - root->data = temp->data; - root->right = deleteNode(root->right, temp->data); - } - - // Fix Red-Black properties - return balance(root); -} -``` - -## Advantages and Disadvantages - -### Advantages: -- Guarantees O(log n) time complexity for search, insertion, and deletion. -- Self-balancing, preventing the tree from becoming skewed. -- Simpler than AVL trees in terms of rebalancing operations. - -### Disadvantages: -- Balancing is not as strict as AVL trees, leading to slightly worse balancing in certain cases. -- Complex to implement due to recoloring and rotation logic. - -## Applications of Red-Black Trees - -- **Memory Management:** Used in memory allocators to efficiently manage memory chunks. -- **Linux Kernel:** Red-Black Trees are used in process scheduling and other kernel operations. -- **Database Indexing:** Red-Black Trees are used in databases to maintain balance for indexing. -- **Computational Geometry:** Used for dynamic sets of intervals and points in geometric algorithms. - ---- diff --git a/docs/binary-search-tree/search-BST.md b/docs/binary-search-tree/search-BST.md deleted file mode 100644 index 23c177431..000000000 --- a/docs/binary-search-tree/search-BST.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -id: search-binary-search-tree -sidebar_position: 13 -title: Search in a Binary Search Tree -sidebar_label: Search in BST -description: "This blog post covers how to search for a value in a Binary Search Tree (BST) in C++, along with explanations and code examples." -tags: [dsa, binary trees, search, c++] ---- - -In this post, we will discuss how to search for a specific value in a **Binary Search Tree (BST)**. A BST is a special kind of binary tree where each node has a value greater than all values in its left subtree and less than all values in its right subtree. - -## Problem Definition -Given a binary search tree and a target value, the goal is to determine if the target value exists in the tree. If it exists, we return the corresponding node; otherwise, we return `NULL`. - -## Approach -To search for a value in a BST, we can utilize the properties of the BST. Starting from the root node, we compare the target value with the value of the current node: - -1. If the target value is equal to the current node's value, we have found the target, and we return the current node. -2. If the target value is less than the current node's value, we search in the left subtree. -3. If the target value is greater than the current node's value, we search in the right subtree. - -### Steps: -1. Start from the root node. -2. If the current node is `NULL`, return `NULL`. -3. Compare the target value with the current node's value: - - If they are equal, return the current node. - - If the target value is less, move to the left child. - - If the target value is greater, move to the right child. -4. Repeat until you find the target or exhaust the tree. - -### C++ Code Implementation - -```cpp -#include -using namespace std; - -// Definition for a binary search tree node -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Function to search a value in a binary search tree -TreeNode* searchBST(TreeNode* root, int val) { - if (root == NULL || root->val == val) { - return root; - } - if (val < root->val) { - return searchBST(root->left, val); - } else { - return searchBST(root->right, val); - } -} - -int main() { - TreeNode* root = new TreeNode(4); - root->left = new TreeNode(2); - root->right = new TreeNode(7); - root->left->left = new TreeNode(1); - root->left->right = new TreeNode(3); - - int target = 2; - TreeNode* result = searchBST(root, target); - - if (result != NULL) { - cout << "Found: " << result->val << endl; - } else { - cout << "Value not found in the BST." << endl; - } - - return 0; -} -``` -### JAVA Code Implementation - -```java -// Definition for a binary search tree node -class TreeNode { - int val; - TreeNode left; - TreeNode right; - - // Constructor for initializing a TreeNode with a value - TreeNode(int x) { - val = x; - left = null; - right = null; - } -} - -public class BinarySearchTree { - - // Function to search a value in a binary search tree - public TreeNode searchBST(TreeNode root, int val) { - if (root == null || root.val == val) { - return root; - } - if (val < root.val) { - return searchBST(root.left, val); - } else { - return searchBST(root.right, val); - } - } - - public static void main(String[] args) { - BinarySearchTree bst = new BinarySearchTree(); - - // Building the binary search tree - TreeNode root = new TreeNode(4); - root.left = new TreeNode(2); - root.right = new TreeNode(7); - root.left.left = new TreeNode(1); - root.left.right = new TreeNode(3); - - // Define the target value to search for - int target = 2; - - // Search for the target value in the tree - TreeNode result = bst.searchBST(root, target); - - // Output the result - if (result != null) { - System.out.println("Found: " + result.val); - } else { - System.out.println("Value not found in the BST."); - } - } -} - -``` diff --git a/docs/binary-search/Exponential-Search.md b/docs/binary-search/Exponential-Search.md deleted file mode 100644 index 12c2311bd..000000000 --- a/docs/binary-search/Exponential-Search.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: exponential-search-dsa -sidebar_position: 4 -title: Exponential Search -sidebar_label: Exponential Search -description: "In this blog post, we'll explore Exponential Search, a searching algorithm that efficiently finds an element in a sorted array, especially when the size of the array is unknown." -tags: [dsa, algorithms, binary search] ---- - -## Introduction -Exponential Search is a searching algorithm that efficiently locates an element in a sorted array, especially in scenarios where the size of the array is not known beforehand. Unlike traditional binary search, which requires the boundaries of the search space to be defined, Exponential Search cleverly combines the approach of linear search with binary search to accommodate unknown-sized arrays. - -The algorithm works in two main phases: - -1.Finding the Range: In the first phase, Exponential Search aims to identify a range in which the target element may exist. It starts by checking the first element of the array. If the target is not found there, the algorithm begins to double the index at each step (e.g., checking the element at index 1, then index 2, then index 4, and so on) until it either finds an element larger than the target or reaches the end of the array. This phase ensures that the algorithm can quickly pinpoint the potential range of the search without needing to know the total length of the array. - -2.Binary Search: Once the appropriate range is determined, Exponential Search transitions to binary search within that range. The binary search efficiently narrows down the position of the target element by repeatedly dividing the search interval in half. This combination allows Exponential Search to achieve a time complexity of O(log n) for the actual search phase, making it particularly effective for large datasets.. - -## Implementation - -Let us see how to implement Exponential Search in Java: -## Time Complexity: -Linear search: O(n)
    -Exponential search: O(log n) - -## Points to Remember: - Exponential Search is effective when the size of the array is unknown. - - It quickly finds the range in which the target value may exist. - - Combines sequential and binary search methods. - - Particularly efficient when the target is near the start of a large sorted array. - - Suitable for dynamic datasets where the size might change frequently. - -```java -public class ExponentialSearch { - - public int binarySearch(int[] arr, int low, int high, int target) { - while (low <= high) { - int mid = low + (high - low) / 2; - if (arr[mid] == target) { - return mid; // Target found - } else if (arr[mid] < target) { - low = mid + 1; // Search right half - } else { - high = mid - 1; // Search left half - } - } - return -1; // Target not found - } - - public int exponentialSearch(int[] arr, int target) { - if (arr[0] == target) return 0; // Check first element - - int index = 1; - while (index < arr.length && arr[index] <= target) { - index *= 2; // Double the index - } - - return binarySearch(arr, index / 2, Math.min(index, arr.length - 1), target); - } - - public static void main(String[] args) { - ExponentialSearch searcher = new ExponentialSearch(); - int[] arr = {2, 3, 4, 10, 40, 50, 60, 70, 80, 90}; - int target = 10; - int result = searcher.exponentialSearch(arr, target); - System.out.println("Target found at index: " + result); // Output: Target found at index: 3 - } -} diff --git a/docs/binary-search/Iterative_binary_search.md b/docs/binary-search/Iterative_binary_search.md deleted file mode 100644 index 1c3df1791..000000000 --- a/docs/binary-search/Iterative_binary_search.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: iterative-binary-search-DSA -title: Iterative Binary Search -sidebar_label: Iterative Binary Search -sidebar_position: 2 -description: "In this blog post, we'll explore the iterative binary search algorithm, a fundamental technique in computer science for efficiently finding an element in a sorted array. You'll learn what iterative binary search is, how it works, and its time complexity. We'll also cover practical applications and common problems you can solve using this algorithm. By the end, you'll have a thorough understanding of iterative binary search and how to implement it in your programming projects." -tags: [dsa, algorithms, binary search, iterative] ---- - -Iterative Binary Search is powerful algorithm that is essential for efficiently finding elements in sorted arrays, making it a staple in the toolkit of any adept programmer. Whether you're optimizing search operations or solving complex algorithmic challenges, understanding iterative binary search is crucial. Let's delve into its mechanics, applications, and implementation. - -## What is Iterative Binary Search? - -Iterative binary search is a highly efficient algorithm used to find an element in a sorted array. It works by repeatedly dividing the search interval in half, using an iterative approach. If the value of the search key is less than the item in the middle of the interval, the algorithm narrows the interval to the lower half. Otherwise, it narrows it to the upper half. The process continues until the search key is found or the interval is empty. - -In pseudo-code, iterative binary search is defined as follows: - -```cpp -FUNCTION iterativeBinarySearch(array, key): -low = 0 -high = array.length - 1 -WHILE low <= high: -mid = (low + high) / 2 -IF array[mid] == key: -RETURN mid -ELSE IF array[mid] < key: -low = mid + 1 -ELSE: -high = mid - 1 -RETURN -1 -``` - -```cpp -int iterativeBinarySearch(int array[], int size, int key) { - int low = 0; - int high = size - 1; - while (low <= high) { - int mid = low + (high - low) / 2; - if (array[mid] == key) { - return mid; - } else if (array[mid] < key) { - low = mid + 1; - } else { - high = mid - 1; - } - } - return -1; -} -``` - -## How Iterative Binary Search Works - -### Step-by-Step Explanation - -1. Initialize: Set two pointers, low at the beginning and high at the end of the array. -2. Middle Element: Calculate the middle element's index. -Comparison: -3. If the middle element is the target, return its index. -4. If the middle element is less than the target, discard the left half by setting low to mid + 1. -5. If the middle element is greater than the target, discard the right half by setting high to mid - 1. -6. Repeat: Repeat steps 2 and 3 until the target is found or the low pointer exceeds the high pointer. - -### Time Complexity - -The time complexity of iterative binary search is $O(logn)$, -where $𝑛$ is the number of elements in the array. This logarithmic time complexity makes iterative binary search significantly faster than linear search for large datasets. - -## Practical Applications - -Iterative binary search is widely used in various real-world applications and algorithmic problems: - -1. Searching in a Sorted Array - The primary use of iterative binary search is to find elements in a sorted array efficiently. It is the foundation for more complex search algorithms. - -2. Dictionary Lookups - Iterative binary search is used in dictionaries (like the one you're reading now) to quickly find words and their definitions. - -3. Binary Search Trees - Iterative binary search is the basis for searching in binary search trees (BSTs), a fundamental data structure in computer science. - -4. Finding Boundaries - Iterative binary search can be adapted to find the first or last occurrence of a target element, making it useful in problems requiring boundary searches. - -Common Problems Solved Using Iterative Binary Search -Iterative binary search can be adapted in various ways to solve different types of problems. Here are a couple of common problems: - -1. Lower Bound and Upper Bound - These variations of iterative binary search are used to find the first and last occurrence of a target element in a sorted array. - -Lower Bound Pseudo-Code: - -```cpp -FUNCTION lowerBound(array, key): - low = 0 - high = array.length - WHILE low < high: - mid = (low + high) / 2 - IF array[mid] < key: - low = mid + 1 - ELSE: - high = mid - RETURN low - -``` - -Upper Bound Pseudo-Code: - -```cpp -FUNCTION upperBound(array, key): - low = 0 - high = array.length - WHILE low < high: - mid = (low + high) / 2 - IF array[mid] <= key: - low = mid + 1 - ELSE: - high = mid - RETURN low - - -``` - -2. Rotated Sorted Array - Iterative binary search can be modified to handle rotated sorted arrays, where the array is sorted but then rotated at some pivot point. - -:::tip -Handle Edge Cases: Ensure your implementation correctly handles cases where the target element is not present or when the array is empty. -Prevent Overflow: When calculating the middle index, use $\text{mid} = \text{low} + \frac{\text{high} - \text{low}}{2}$ instead of $\text{mid} = \frac{\text{low} + \text{high}}{2}$ to prevent potential overflow. -Efficiency: The iterative approach often uses less memory than the recursive approach because it doesn't involve the overhead of multiple recursive function calls. -::: - -## Conclusion - -Iterative binary search is a fundamental algorithm that every programmer should master. Its efficiency and versatility make it a powerful tool for solving a wide range of problems. By understanding how iterative binary search works and how to implement its variations, you'll be well-equipped to tackle numerous challenges in your programming journey. diff --git a/docs/binary-search/Painter_Partition_problem.md b/docs/binary-search/Painter_Partition_problem.md deleted file mode 100644 index 6211541d5..000000000 --- a/docs/binary-search/Painter_Partition_problem.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: painter-partition-problem -title: Painter Partition Problem (C++) -sidebar_label: Painter Partition -sidebar_position: 1 -description: Solve the Painter Partition problem using Binary Search and Greedy approaches. -tags: [binary search, greedy, algorithms, c++] ---- - -# Painter Partition Problem (C++) - -## Problem Statement -You are given an array `boards[]` where `boards[i]` represents the length of the i-th board. You have `k` painters and each painter takes 1 unit of time to paint 1 unit length of the board. Each painter can only paint continuous sections of boards. Your task is to minimize the time taken to paint all the boards. - -## Approach -This problem can be solved using **Binary Search** on the time range and a **Greedy approach** to allocate boards to painters. - -- Use Binary Search to find the minimal maximum time (`mid`) a painter can take to paint the boards. -- Use a greedy method to count the number of painters required for each time guess (`mid`). -- The goal is to minimize the maximum time required. - -## Solution in C++ - -```cpp -#include -using namespace std; - -// Function to count the number of painters required to paint all boards in "time" -int countPainters(vector &boards, int time) { - int n = boards.size(); // Size of the array - int painters = 1; // Start with 1 painter - long long boardsPainter = 0; - - for (int i = 0; i < n; i++) { - if (boardsPainter + boards[i] <= time) { - // Allocate board to the current painter - boardsPainter += boards[i]; - } else { - // Allocate board to the next painter - painters++; - boardsPainter = boards[i]; - } - } - - return painters; -} - -// Function to find the largest minimum distance -int findLargestMinDistance(vector &boards, int k) { - // Find the search space for binary search - int low = *max_element(boards.begin(), boards.end()); - int high = accumulate(boards.begin(), boards.end(), 0); - - // Apply binary search: - while (low <= high) { - int mid = (low + high) / 2; - int painters = countPainters(boards, mid); - - if (painters > k) { - low = mid + 1; - } else { - high = mid - 1; - } - } - - return low; // Minimum possible maximum time -} - -int main() { - vector boards = {10, 20, 30, 40}; - int k = 2; // Number of painters - - int ans = findLargestMinDistance(boards, k); - cout << "The answer is: " << ans << "\n"; - - return 0; -} -``` - -## Key Concepts - -- **Binary Search**: Used to find the minimum maximum time required to paint all the boards. -- **Greedy Approach**: The helper function `countPainters` assigns boards to painters ensuring the total time doesn’t exceed the given limit for that iteration. - -## Mathematical Representation - -The problem can be thought of in terms of minimizing the largest workload: - -$$ \text{Minimize } \max(\text{time taken by any painter}) $$ - -### Mermaid Diagram - -```mermaid -graph TD; - Start-->BinarySearch; - BinarySearch-->MidCalculation; - MidCalculation-->PainterCount; - PainterCount--Yes-->MinTime; - PainterCount--No-->AdjustBounds; - AdjustBounds-->BinarySearch; -``` - - diff --git a/docs/binary-search/Problem-Practice.md b/docs/binary-search/Problem-Practice.md deleted file mode 100644 index 67beac754..000000000 --- a/docs/binary-search/Problem-Practice.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -id: Practice-Problems-on-binary-search -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 2 -description: Here are some practice problems for Binary Search, divided into topic-wise and difficulty-wise categories. -tags: [DSA, algorithms, binary search] ---- - -### Basic Problems: - -- [Search insert Position](https://leetcode.com/problems/search-insert-position?envType=problem-list-v2&envId=binary-search&difficulty=EASY) -- [Count Complete Tree Nodes](https://leetcode.com/problems/count-complete-tree-nodes?envType=problem-list-v2&envId=binary-search&difficulty=EASY) -- [Missing Number](https://leetcode.com/problems/missing-number?envType=problem-list-v2&envId=binary-search&difficulty=EASY) -- [Closest Binary Search Tree Value](https://leetcode.com/problems/closest-binary-search-tree-value?envType=problem-list-v2&envId=binary-search&difficulty=EASY) -- [First Bad Version](https://leetcode.com/problems/first-bad-version?envType=problem-list-v2&envId=binary-search&difficulty=EASY) -- [Distribute Candies to People](https://leetcode.com/problems/distribute-candies-to-people/description/) - - -### Intermediate Problems: - -- [Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array?envType=problem-list-v2&envId=binary-search&difficulty=MEDIUM) -- [Find First and Last Position of Element in Sorted Array](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array?envType=problem-list-v2&envId=binary-search&difficulty=MEDIUM) -- [Search a 2D Matrix](https://leetcode.com/problems/search-a-2d-matrix?envType=problem-list-v2&envId=binary-search&difficulty=MEDIUM) -- [Search in Rotated Sorted Array II](https://leetcode.com/problems/search-in-rotated-sorted-array-ii?envType=problem-list-v2&envId=binary-search&difficulty=MEDIUM) -- [Find Peak Element](https://leetcode.com/problems/find-peak-element?envType=problem-list-v2&envId=binary-search&difficulty=MEDIUM) -- [Kth Smallest Element in a Sorted Matrix](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/description/) -- [Aggressive cows](https://www.spoj.com/problems/AGGRCOW/) -- [Ugly Number III](https://leetcode.com/problems/ugly-number-iii/description/?envType=problem-list-v2&envId=binary-search) - -### Advanced Problems: - -- [Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays?envType=problem-list-v2&envId=binary-search&difficulty=HARD) -- [Find Minimum in Rotated Sorted Array II](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii?envType=problem-list-v2&envId=binary-search&difficulty=HARD) -- [Smallest Rectangle Enclosing Black Pixels](https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels?envType=problem-list-v2&envId=binary-search&difficulty=HARD) -- [Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self?envType=problem-list-v2&envId=binary-search&difficulty=HARD) -- [Super Egg Drop](https://leetcode.com/problems/super-egg-drop/description/) - -### Challenges: - -- [Escape the Spreading Fire](https://leetcode.com/problems/escape-the-spreading-fire?envType=problem-list-v2&envId=binary-search&difficulty=HARD) -- [Number of Flowers in Full Bloom](https://leetcode.com/problems/number-of-flowers-in-full-bloom?envType=problem-list-v2&envId=binary-search&difficulty=HARD) -- [Maximum Number of Robots Within Budget](https://leetcode.com/problems/maximum-number-of-robots-within-budget?envType=problem-list-v2&envId=binary-search&difficulty=HARD) diff --git a/docs/binary-search/_category_.json b/docs/binary-search/_category_.json deleted file mode 100644 index 56d2329ba..000000000 --- a/docs/binary-search/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Binary Search", - "position": 7, - "link": { - "type": "generated-index", - "description": "Binary search is a searching algorithm, used to search for an element in an array. It follows a unique approach which reduces the time complexity as compared to linear search. However, to use binary search, the array must be sorted." - } -} diff --git a/docs/binary-search/binary-search.md b/docs/binary-search/binary-search.md deleted file mode 100644 index 71fef2382..000000000 --- a/docs/binary-search/binary-search.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: binary-search-dsa -sidebar_position: 1 -title: Binary Search -sidebar_label: Binary Search -description: "In this blog post, we'll dive into the binary search algorithm, a fundamental technique in computer science for efficiently finding an element in a sorted array." -tags: [dsa, algorithms, binary search] ---- - - -## Introduction -Binary search is a searching algorithm, used to search for an element in an array. It follows a unique approach which reduces the time complexity as compared to linear search. However, to use binary search, the array must be sorted. - -## Implementation - -Let us see how to implement binary search in Java: - -```java - //let element to be found=target - int low=0; - int high=n-1; //where n is the length of the sorted array - int mid; //represents the mid index of the array - - int flag=0; //element not yet found - - while(low<=high) { - - mid=(low + high)/2; - if(arr[mid]==target) { - flag=1; //element found - System.out.println("Target found!"); - break; - } - else if(arr[mid] -Binary search : O(log n) - -## Points to Remember: - -- Binary search requires a sorted array. -- Works for 1 dimensional arrays. -- Faster and complex than sequential search. -- Uses the divide and conquer approach. -- Best if arrays are too long (large datasets). diff --git a/docs/binary-search/binary-search_rotated-sorted-array.md b/docs/binary-search/binary-search_rotated-sorted-array.md deleted file mode 100644 index 73dfae2a7..000000000 --- a/docs/binary-search/binary-search_rotated-sorted-array.md +++ /dev/null @@ -1,323 +0,0 @@ ---- -id: binary-search-rotated-sorted-array -sidebar_position: 5 -title: Binary Search Rotated sort array -sidebar_label: Binary Search -description: "In this blog post, we'll dive into the rotated array approach with binary search algorithm, a fundamental technique in computer science for efficiently finding an element in a sorted array." -tags: [dsa, algorithms, binary search] ---- - - -# Binary Search in Rotated Sorted Array - -## Problem Description - -Given a sorted array that has been rotated at some pivot point, implement a function to find a target element in the array. The function should return the index of the target element if found, or -1 if not found. - -A rotated sorted array is an array that was originally sorted in ascending order but has been rotated around a pivot point. For example: -- Original sorted array: `[1, 2, 3, 4, 5, 6, 7]` -- After rotation at index 3: `[4, 5, 6, 7, 1, 2, 3]` - -## Time Complexity -- **Time Complexity**: O(log n) -- **Space Complexity**: O(1) - -## Algorithm Overview - -The algorithm uses a modified binary search approach that takes into account the rotation of the array. The key insight is that at least one half of the array (either left or right) will always be sorted. - -### Key Steps: - -1. Initialize two pointers: - - `left` pointing to the start of array (index 0) - - `right` pointing to the end of array (index n-1) - -2. While `left <= right`: - - Calculate middle point: `mid = (left + right) / 2` - - If target is found at mid, return mid - -3. Check which half of the array is sorted: - - If left half is sorted (`arr[left] <= arr[mid]`): - - Check if target lies in the left half - - If yes, search left half - - If no, search right half - - If right half is sorted: - - Check if target lies in the right half - - If yes, search right half - - If no, search left half - -4. If element is not found, return -1 - -## Implementation - -```python -def search(nums: list[int], target: int) -> int: - if not nums: - return -1 - - left, right = 0, len(nums) - 1 - - while left <= right: - mid = (left + right) // 2 - - # Found target - if nums[mid] == target: - return mid - - # Check if left half is sorted - if nums[left] <= nums[mid]: - # Check if target is in left half - if nums[left] <= target <= nums[mid]: - right = mid - 1 - else: - left = mid + 1 - # Right half is sorted - else: - # Check if target is in right half - if nums[mid] <= target <= nums[right]: - left = mid + 1 - else: - right = mid - 1 - - return -1 -``` - -## Example Usage - -```python -# Example 1: Regular case -arr = [4, 5, 6, 7, 0, 1, 2] -target = 0 -result = search(arr, target) # Returns 4 - -# Example 2: Target not found -arr = [4, 5, 6, 7, 0, 1, 2] -target = 3 -result = search(arr, target) # Returns -1 - -# Example 3: Array with single element -arr = [1] -target = 1 -result = search(arr, target) # Returns 0 -``` - -## Edge Cases to Consider - -1. Empty array -2. Array with single element -3. Target not present in array -4. Duplicate elements (not handled in basic implementation) -5. Array not rotated (regular sorted array) -6. Array rotated n times (back to original position) -7. Target at the first or last position - -## Common Pitfalls - -1. **Not Handling Empty Arrays**: Always check if the input array is empty before processing. -2. **Integer Overflow**: When calculating mid point, use `left + (right - left) // 2` instead of `(left + right) // 2` to prevent integer overflow in some languages. -3. **Incorrect Boundary Conditions**: Be careful with the conditions when checking if target lies in sorted portion. -4. **Duplicate Elements**: The basic implementation assumes all elements are unique. Handling duplicates requires additional logic. - -## Applications - -1. **Database Indexing**: When indexes are partially sorted or reorganized -2. **Circular Buffer Search**: Finding elements in circular buffer data structures -3. **Version Control**: Finding specific versions in circular version histories -4. **Resource Allocation**: Finding available slots in circular resource allocation systems - -## Related Problems - -1. Find Minimum in Rotated Sorted Array -2. Search in Rotated Sorted Array II (with duplicates) -3. Find Rotation Count in Rotated Sorted Array -4. Find Maximum in Rotated Sorted Array - -## Testing Guide - -### Test Cases to Cover: - -1. Basic cases: - ```python - assert search([4, 5, 6, 7, 0, 1, 2], 0) == 4 - assert search([4, 5, 6, 7, 0, 1, 2], 3) == -1 - ``` - -2. Edge cases: - ```python - assert search([], 5) == -1 - assert search([1], 1) == 0 - assert search([1], 0) == -1 - ``` - -3. Rotation variations: - ```python - assert search([1, 2, 3, 4, 5], 4) == 3 # No rotation - assert search([2, 3, 4, 5, 1], 1) == 4 # Rotated once - assert search([5, 1, 2, 3, 4], 5) == 0 # Target at start - ``` - -## Performance Optimization Tips - -1. Use binary search variant that avoids integer overflow -2. Consider adding early termination conditions for obvious cases -3. If dealing with large arrays, consider parallelization for multiple searches -4. Cache frequently searched values if appropriate for your use case - -## Additional Resources - -1. Time Complexity Analysis: [Master Theorem](https://en.wikipedia.org/wiki/Master_theorem_(analysis_of_algorithms)) -2. Related Reading: Binary Search Trees and Their Applications -3. Practice Problems: LeetCode #33, #81, #153 -4. Advanced Topics: Variants with duplicates, Finding multiple occurrences - -## Practice Problems Collection - -### Essential Problems - -| Problem | Difficulty | LeetCode Link | Description | Key Concepts | -|---------|------------|---------------|-------------|--------------| -| Search in Rotated Sorted Array | Medium | [LC-33](https://leetcode.com/problems/search-in-rotated-sorted-array/) | Find target in rotated array with unique elements | Basic rotated array search | -| Search in Rotated Sorted Array II | Medium | [LC-81](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/) | Find target in rotated array with duplicates | Handling duplicates | -| Find Minimum in Rotated Sorted Array | Medium | [LC-153](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | Find minimum element in rotated array | Modified binary search | -| Find Minimum in Rotated Sorted Array II | Hard | [LC-154](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/) | Find minimum in rotated array with duplicates | Complex duplicate handling | - -### Related Binary Search Problems - -| Problem | Difficulty | LeetCode Link | Description | Key Concepts | -|---------|------------|---------------|-------------|--------------| -| Peak Element | Medium | [LC-162](https://leetcode.com/problems/find-peak-element/) | Find any peak element in array | Binary search on unsorted array | -| Find First and Last Position | Medium | [LC-34](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/) | Find range of target element | Modified binary search | -| Single Element in Sorted Array | Medium | [LC-540](https://leetcode.com/problems/single-element-in-a-sorted-array/) | Find element that appears once | Binary search with parity | -| Search Insert Position | Easy | [LC-35](https://leetcode.com/problems/search-insert-position/) | Find insertion position | Basic binary search | - -### Problem-Solving Patterns - -#### Pattern 1: Basic Rotated Array Search -```python -def findPivot(nums): - left, right = 0, len(nums) - 1 - while left < right: - mid = left + (right - left) // 2 - if nums[mid] > nums[right]: - left = mid + 1 - else: - right = mid - return left -``` - -#### Pattern 2: Handling Duplicates -```python -def searchWithDuplicates(nums, target): - left, right = 0, len(nums) - 1 - while left <= right: - # Skip duplicates from left - while left < right and nums[left] == nums[left + 1]: - left += 1 - # Skip duplicates from right - while left < right and nums[right] == nums[right - 1]: - right -= 1 - # Regular binary search logic follows... -``` - -#### Pattern 3: Finding Range -```python -def searchRange(nums, target): - def findBound(nums, target, isFirst): - left, right = 0, len(nums) - 1 - while left <= right: - mid = left + (right - left) // 2 - if nums[mid] == target: - if isFirst: - if mid == left or nums[mid-1] < target: - return mid - right = mid - 1 - else: - if mid == right or nums[mid+1] > target: - return mid - left = mid + 1 - elif nums[mid] < target: - left = mid + 1 - else: - right = mid - 1 - return -1 - - return [findBound(nums, target, True), - findBound(nums, target, False)] -``` - -### Problem-Solving Tips - -1. **For Basic Rotated Array**: - - Always check which half is sorted first - - Compare target with endpoints of sorted half - - Move to appropriate half based on comparison - -2. **For Duplicate Elements**: - - Skip duplicate elements at boundaries - - Consider worst-case time complexity becomes O(n) - - Handle edge cases where all elements are same - -3. **For Finding Ranges**: - - Use two binary searches for left and right bounds - - Modify condition to find first/last occurrence - - Handle cases where element doesn't exist - -### Common Patterns and Templates - -#### Template 1: Basic Binary Search in Rotated Array -```python -def search(nums: List[int], target: int) -> int: - left, right = 0, len(nums) - 1 - - while left <= right: - mid = left + (right - left) // 2 - - if nums[mid] == target: - return mid - - # Check if left half is sorted - if nums[left] <= nums[mid]: - if nums[left] <= target <= nums[mid]: - right = mid - 1 - else: - left = mid + 1 - # Right half is sorted - else: - if nums[mid] <= target <= nums[right]: - left = mid + 1 - else: - right = mid - 1 - - return -1 -``` - -#### Template 2: Binary Search with Duplicates -```python -def searchWithDuplicates(nums: List[int], target: int) -> bool: - left, right = 0, len(nums) - 1 - - while left <= right: - # Handle duplicates - while left < right and nums[left] == nums[left + 1]: - left += 1 - while left < right and nums[right] == nums[right - 1]: - right -= 1 - - mid = left + (right - left) // 2 - - if nums[mid] == target: - return True - - if nums[left] <= nums[mid]: - if nums[left] <= target <= nums[mid]: - right = mid - 1 - else: - left = mid + 1 - else: - if nums[mid] <= target <= nums[right]: - left = mid + 1 - else: - right = mid - 1 - - return False -``` \ No newline at end of file diff --git a/docs/binary-search/binary.md b/docs/binary-search/binary.md deleted file mode 100644 index 7d7fdd401..000000000 --- a/docs/binary-search/binary.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: binary-search-dsa -sidebar_position: 1 -title: Binary Search -sidebar_label: Binary Search -description: "In this blog post, we'll dive into the binary search algorithm, a fundamental technique in computer science for efficiently finding an element in a sorted array." -tags: [dsa, algorithms, binary search] ---- - - -## Introduction -Binary search is a searching algorithm, used to search for an element in an array. It follows a unique approach which reduces the time complexity as compared to linear search. However, to use binary search, the array must be sorted. - -## Implementation - -Let us see how to implement binary search in Java: - -```java - //let element to be found=target - int low=0; - int high=n-1; //where n is the length of the sorted array - int mid; //represents the mid index of the array - - int flag=0; //element not yet found - - while(low<=high) { - - mid=(low + high)/2; - if(arr[mid]==target) { - flag=1; //element found - System.out.println("Target found!"); - break; - } - else if(arr[mid] -#include - -void binarySearch(const std::vector& arr, int target) { - int low = 0; - int high = arr.size() - 1; - int mid; - bool found = false; // element not yet found - - while (low <= high) { - mid = low + (high - low) / 2; // to avoid potential overflow - if (arr[mid] == target) { - found = true; // element found - std::cout << "Target found!" << std::endl; - break; - } - else if (arr[mid] < target) { - // target is to the right of mid element - low = mid + 1; - } - else { - // target is to the left of mid element - high = mid - 1; - } - } - - if (!found) { - std::cout << "Target not found!" << std::endl; - } -} - -int main() { - std::vector arr = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // example sorted array - int target = 5; // example target - - binarySearch(arr, target); - - return 0; -} - -``` - -In this algorithm, the searching interval of the array is divided into half at every iteration until the target is found. This results in lesser comparisions and decreases the time required. - -## Time complexity: - -Linear/Sequential search: O(n)
    -Binary search : O(log n) - -## Points to Remember: - -- Binary search requires a sorted array. -- Works for 1 dimensional arrays. -- Faster and complex than sequential search. -- Uses the divide and conquer approach. -- Best if arrays are too long (large datasets). diff --git a/docs/binary-search/binary_search_questions.md b/docs/binary-search/binary_search_questions.md deleted file mode 100644 index 552cf157e..000000000 --- a/docs/binary-search/binary_search_questions.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -id: binary-search-q -sidebar_position: 6 -title: Binary Search -sidebar_label: Binary Search -description: "In this blog post, we'll dive into the binary search algorithm, a fundamental technique in computer science for efficiently finding an element in a sorted array." -tags: [dsa, algorithms, binary search] ---- - -# Binary Search Patterns: A Comprehensive Guide - -Welcome to this in-depth exploration of binary search patterns! This guide is designed to help you master the art of binary search through a curated collection of problems, explanations, and real-world applications. - - -## Introduction to Binary Search - -Binary search is a fundamental algorithm in computer science that efficiently locates an element in a sorted array. By repeatedly dividing the search interval in half, binary search achieves a time complexity of O(log n), making it significantly faster than linear search for large datasets. - -## Why Master Binary Search? - -Understanding binary search is crucial for several reasons: - -1. **Efficiency**: Binary search reduces time complexity from O(n) to O(log n), essential for working with large datasets. -2. **Versatility**: The core concept of dividing the search space applies to various problem types, from simple searches to complex optimization problems. -3. **Problem-Solving Skills**: Mastering binary search enhances your ability to think algorithmically and approach problems systematically. -4. **Interview Preparation**: Binary search is a popular topic in technical interviews, appearing in questions from leading tech companies. -5. **Foundation for Advanced Algorithms**: Many advanced algorithms and data structures build upon the principles of binary search. - -## Binary Search Patterns - -### Pattern 1: Binary Search on 1D Arrays - -This pattern focuses on applying binary search to one-dimensional sorted arrays. It covers: - -- Basic binary search implementation -- Finding boundaries (first/last occurrences) -- Searching in rotated sorted arrays -- Finding peak elements - -**Key Techniques**: -- Modifying search conditions -- Handling duplicate elements -- Identifying search spaces in modified arrays - -### Pattern 2: Binary Search on Answer Space - -This pattern applies binary search to a range of possible answers rather than a specific array. It's useful for: - -- Optimization problems -- Finding roots of equations -- Minimizing/maximizing values subject to constraints - -**Key Techniques**: -- Defining a feasible answer range -- Creating a condition to check answer validity -- Adjusting the search space based on the condition - -### Pattern 3: Binary Search on 2D Arrays - -This pattern extends binary search to two-dimensional arrays or matrices. It covers: - -- Searching in row-wise and column-wise sorted matrices -- Finding peak elements in 2D arrays -- Calculating matrix medians - -**Key Techniques**: -- Treating 2D arrays as flattened 1D arrays -- Utilizing properties of sorted rows/columns -- Combining binary search with other techniques (e.g., merge) - -## Problem Collections - -### Pattern 1: Binary Search on 1D Arrays - -| Problem | Difficulty | Practice Link | Explanation | -|---------|------------|---------------|-------------| -| Binary Search | Easy | [LeetCode](https://leetcode.com/problems/binary-search/) | [Explanation](https://takeuforward.org/data-structure/binary-search-explained/) | -| Implement Lower Bound | Easy | [GeeksforGeeks](https://www.geeksforgeeks.org/problems/floor-in-a-sorted-array-1587115620/1) | [Explanation](https://takeuforward.org/arrays/implement-lower-bound-bs-2/) | -| Search in Rotated Sorted Array | Medium | [LeetCode](https://leetcode.com/problems/search-in-rotated-sorted-array/) | [Explanation](https://takeuforward.org/data-structure/search-element-in-a-rotated-sorted-array/) | -| Find Minimum in Rotated Sorted Array | Medium | [LeetCode](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | [Explanation](https://takeuforward.org/data-structure/minimum-in-rotated-sorted-arrayy) | - -### Pattern 2: Binary Search on Answer Space - -| Problem | Difficulty | Practice Link | Explanation | -|---------|------------|---------------|-------------| -| Koko Eating Bananas | Medium | [LeetCode](https://leetcode.com/problems/koko-eating-bananas/) | [Explanation](https://takeuforward.org/binary-search/koko-eating-bananas/) | -| Find the Smallest Divisor | Medium | [LeetCode](https://leetcode.com/problems/find-the-smallest-divisor-given-a-threshold/) | [Explanation](https://takeuforward.org/arrays/find-the-smallest-divisor-given-a-threshold/) | -| Aggressive Cows | Hard | [GeeksforGeeks](https://www.geeksforgeeks.org/problems/aggressive-cows/0) | [Explanation](https://takeuforward.org/data-structure/aggressive-cows-detailed-solution/) | -| Median of Two Sorted Arrays | Hard | [LeetCode](https://leetcode.com/problems/median-of-two-sorted-arrays/) | [Explanation](https://takeuforward.org/data-structure/median-of-two-sorted-arrays-of-different-sizes) | -| Capacity to Ship Packages Within D days | Medium | [LeetCode](https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/description/) | [Explanation](https://takeuforward.org/arrays/capacity-to-ship-packages-within-d-days/) | - -### Pattern 3: Binary Search on 2D Arrays - -| Problem | Difficulty | Practice Link | Explanation | -|---------|------------|---------------|-------------| -| Search a 2D Matrix | Medium | [LeetCode](https://leetcode.com/problems/search-a-2d-matrix/) | [Explanation](https://takeuforward.org/data-structure/search-in-a-sorted-2d-matrix/) | -| Find Peak Element II | Hard | [LeetCode](https://leetcode.com/problems/find-a-peak-element-ii) | Not Available | -| Matrix Median | Hard | [InterviewBit](https://www.interviewbit.com/problems/matrix-median/) | [Explanation](https://takeuforward.org/data-structure/median-of-row-wise-sorted-matrix/) | - -## Real-World Applications - -Binary search and its patterns find applications in various real-world scenarios: - -1. **Database Systems**: Efficient data retrieval in sorted indexes. -2. **Machine Learning**: Hyperparameter tuning and model selection. -3. **Computer Graphics**: Collision detection in video games and simulations. -4. **Network Routing**: Finding optimal paths in network topologies. -5. **Version Control**: Identifying commits in large repositories (e.g., git bisect). -6. **Resource Allocation**: Optimizing resource distribution in cloud computing. -7. **Financial Analysis**: Finding breakeven points or optimal investment strategies. - -## Benefits of Mastering Binary Search - -By working through these problems and understanding the patterns, you'll gain: - -1. **Improved Problem-Solving Skills**: Develop a systematic approach to breaking down complex problems. -2. **Enhanced Algorithmic Thinking**: Learn to identify opportunities for optimization in various scenarios. -3. **Interview Readiness**: Build confidence in tackling a wide range of coding challenges. -4. **Efficiency Mindset**: Cultivate an intuition for designing efficient algorithms in your daily coding tasks. -5. **Foundation for Advanced Topics**: Prepare yourself for more complex algorithmic concepts and data structures. - -## How to Use This Guide - -1. Start with the basic binary search implementation in Pattern 1. -2. Progress through each pattern, solving problems of increasing difficulty. -3. For each problem: - - Attempt to solve it independently. - - If stuck, refer to the provided explanation. - - After solving, compare your solution with the optimal approach. -4. Reflect on the patterns and techniques used in each problem. -5. Try to apply these patterns to new, unseen problems to reinforce your learning. - - diff --git a/docs/binary-search/matrix-binary-dsa.md b/docs/binary-search/matrix-binary-dsa.md deleted file mode 100644 index 734296211..000000000 --- a/docs/binary-search/matrix-binary-dsa.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: matrix-binary-dsa -sidebar_position: 10 -title: Binary Search in Matrix -sidebar_label: Binary Search in Matrix -description: "In this blog post, we'll explore binary search in a matrix, an optimized method to find an element in a sorted 2D matrix efficiently in C++." -tags: [dsa, algorithms, binary search, matrix] ---- - -## Introduction -Binary Search in a Matrix is an extension of the binary search algorithm used for a two-dimensional matrix. In a sorted 2D matrix where each row and column are sorted, binary search can be applied to search for an element efficiently. This is particularly useful when working with large matrices where a linear search would be too slow. - -To apply binary search in a matrix, the matrix is treated as a flattened sorted array (while maintaining the row and column structure), and binary search is performed using the virtual array indices. - -## Implementation - -Let us see how to implement binary search in a 2D matrix in Java: - -### Problem Setup: - -We are given an `m x n` matrix where each row is sorted in ascending order from left to right, and the first integer of each row is greater than the last integer of the previous row. The goal is to search for a target value in this matrix. - -### Time Complexity: - - Linear/Sequential search: O(m * n) where m is the number of rows and n is the number of columns. - Binary search in a matrix: O(log(m * n)), because we are effectively performing a binary search over the entire matrix treated as a single sorted array. - -### Points to Remember: - Binary search requires that the matrix is sorted both row-wise and column-wise. - - Works effectively for two-dimensional arrays. - - Faster and more efficient than sequential search, especially for larger datasets. - - Utilizes the divide and conquer approach, similar to standard binary search. - - Ideal for large datasets where the matrix dimensions are substantial, enabling quick lookups. -### Code Implementation: - -```cpp -#include -#include - -class BinarySearchInMatrix { -public: - bool searchMatrix(const std::vector>& matrix, int target) { - int rows = matrix.size(); - if (rows == 0) return false; - int cols = matrix[0].size(); - - int low = 0; - int high = (rows * cols) - 1; // Treating the 2D matrix as a single flat array - - while (low <= high) { - int mid = low + (high - low) / 2; // To prevent overflow - int midElement = matrix[mid / cols][mid % cols]; // Mapping the 1D index back to 2D - - if (midElement == target) { - return true; // Target found - } else if (midElement < target) { - low = mid + 1; // Target is to the right - } else { - high = mid - 1; // Target is to the left - } - } - return false; // Target not found - } -}; - -int main() { - BinarySearchInMatrix searcher; - std::vector> matrix = { - {1, 3, 5, 7}, - {10, 11, 16, 20}, - {23, 30, 34, 60} - }; - int target = 3; - bool result = searcher.searchMatrix(matrix, target); - std::cout << "Target found: " << std::boolalpha << result << std::endl; // Output: Target found: true - return 0; -} - -``` -### Code Implementation: - -```java -import java.util.*; - -public class BinarySearchInMatrix { - public boolean searchMatrix(int[][] matrix, int target) { - int rows = matrix.length; - if (rows == 0) return false; - int cols = matrix[0].length; - - int low = 0; - int high = (rows * cols) - 1; // Treating the 2D matrix as a single flat array - - while (low <= high) { - int mid = low + (high - low) / 2; // To prevent overflow - int midElement = matrix[mid / cols][mid % cols]; // Mapping the 1D index back to 2D - - if (midElement == target) { - return true; // Target found - } else if (midElement < target) { - low = mid + 1; // Target is to the right - } else { - high = mid - 1; // Target is to the left - } - } - return false; // Target not found - } - - public static void main(String[] args) { - BinarySearchInMatrix searcher = new BinarySearchInMatrix(); - int[][] matrix = { - {1, 3, 5, 7}, - {10, 11, 16, 20}, - {23, 30, 34, 60} - }; - int target = 3; - boolean result = searcher.searchMatrix(matrix, target); - System.out.println("Target found: " + result); // Output: Target found: true - } -} - -``` - diff --git a/docs/binary-search/recursive_binary_search.md b/docs/binary-search/recursive_binary_search.md deleted file mode 100644 index 6db495059..000000000 --- a/docs/binary-search/recursive_binary_search.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: recursive-binary-search-DSA -title: Recursive Binary Search -sidebar_label: Recursive Binary Search -sidebar_position: 3 -description: "In this blog post, we'll explore the recursive binary search algorithm, a fundamental technique in computer science for efficiently finding an element in a sorted array. You'll learn what recursive binary search is, how it works, and its time complexity. We'll also cover practical applications and common problems you can solve using this algorithm. By the end, you'll have a thorough understanding of recursive binary search and how to implement it in your programming projects." -tags: [dsa, algorithms, binary search, recursive] ---- - -Recursive Binary Search algorithm is essential for efficiently finding elements in sorted arrays, making it a staple in the toolkit of any adept programmer. Whether you're optimizing search operations or solving complex algorithmic challenges, understanding recursive binary search is crucial. Let's delve into its mechanics, applications, and implementation. - -## What is Recursive Binary Search? - -Recursive binary search is a highly efficient algorithm used to find an element in a sorted array. It works by repeatedly dividing the search interval in half, using a recursive approach. If the value of the search key is less than the item in the middle of the interval, the algorithm narrows the interval to the lower half. Otherwise, it narrows it to the upper half. The process continues until the search key is found or the interval is empty. - -In pseudo-code, recursive binary search is defined as follows: - -```cpp -FUNCTION recursiveBinarySearch(array, low, high, key): -IF low > high: -RETURN -1 -mid = (low + high) / 2 -IF array[mid] == key: -RETURN mid -ELSE IF array[mid] < key: -RETURN recursiveBinarySearch(array, mid + 1, high, key) -ELSE: -RETURN recursiveBinarySearch(array, low, mid - 1, key) -``` - -```cpp -int recursiveBinarySearch(int array[], int low, int high, int key) { - if (low > high) { - return -1; - } - int mid = low + (high - low) / 2; - if (array[mid] == key) { - return mid; - } else if (array[mid] < key) { - return recursiveBinarySearch(array, mid + 1, high, key); - } else { - return recursiveBinarySearch(array, low, mid - 1, key); - } -} -``` - -## How Recursive Binary Search Works - -### Step-by-Step Explanation - -1. Initialize: Set two pointers, low at the beginning and high at the end of the array. -2. Middle Element: Calculate the middle element's index. -Comparison: -3. If the middle element is the target, return its index. -4. If the middle element is less than the target, discard the left half by setting low to mid + 1. -5. If the middle element is greater than the target, discard the right half by setting high to mid - 1. -6. Repeat: Repeat steps 2 and 3 until the target is found or the low pointer exceeds the high pointer. - -### Time Complexity - -The time complexity of iterative binary search is $𝑂(log𝑛)$. - -where $n$ is the number of elements in the array. This logarithmic time complexity makes iterative binary search significantly faster than linear search for large datasets. - -## Practical Applications - -Iterative binary search is widely used in various real-world applications and algorithmic problems: - -1. Searching in a Sorted Array - The primary use of iterative binary search is to find elements in a sorted array efficiently. It is the foundation for more complex search algorithms. - -2. Dictionary Lookups - Iterative binary search is used in dictionaries (like the one you're reading now) to quickly find words and their definitions. - -3. Binary Search Trees - Iterative binary search is the basis for searching in binary search trees (BSTs), a fundamental data structure in computer science. - -4. Finding Boundaries - Iterative binary search can be adapted to find the first or last occurrence of a target element, making it useful in problems requiring boundary searches. - -Common Problems Solved Using Iterative Binary Search -Iterative binary search can be adapted in various ways to solve different types of problems. Here are a couple of common problems: - -1. Lower Bound and Upper Bound - These variations of iterative binary search are used to find the first and last occurrence of a target element in a sorted array. - -Lower Bound Pseudo-Code: - -```cpp -FUNCTION lowerBound(array, low, high, key): - IF low == high: - RETURN low - mid = (low + high) / 2 - IF array[mid] < key: - RETURN lowerBound(array, mid + 1, high, key) - ELSE: - RETURN lowerBound(array, low, mid, key) - - -``` - -Upper Bound Pseudo-Code: - -```cpp -FUNCTION upperBound(array, low, high, key): - if low == high: - return low - mid = (low + high) / 2 - if array[mid] <= key: - return upperBound(array, mid + 1, high, key) - else: - return upperBound(array, low, mid, key) - -``` - -2. Rotated Sorted Array - Recursive binary search can be modified to handle rotated sorted arrays, where the array is sorted but then rotated at some pivot point. - -:::tip -Handle Edge Cases: Ensure your implementation correctly handles cases where the target element is not present or when the array is empty. -Prevent Stack Overflow: Be mindful of the recursion depth, especially for large arrays, as deep recursion can lead to stack overflow. -Efficiency: The recursive approach can be more intuitive and elegant, but consider the iterative approach for environments with limited stack size. -::: - -## Conclusion -Recursive binary search is a fundamental algorithm that every programmer should master. Its efficiency and versatility make it a powerful tool for solving a wide range of problems. By understanding how recursive binary search works and how to implement its variations, you'll be well-equipped to tackle numerous challenges in your programming journey. diff --git a/docs/binary-trees/_category_.json b/docs/binary-trees/_category_.json deleted file mode 100644 index ee9112b78..000000000 --- a/docs/binary-trees/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Binary Trees", - "position": 7, - "link": { - "type": "generated-index", - "description": "Binary trees are a fundamental data structure used to represent hierarchical relationships between elements. Each node in a binary tree has at most two children, referred to as the left child and the right child. This structure allows for efficient searching, insertion, and deletion operations, making binary trees an essential concept in computer science." - } -} diff --git a/docs/binary-trees/basic-operations.md b/docs/binary-trees/basic-operations.md deleted file mode 100644 index 8e3b33ef2..000000000 --- a/docs/binary-trees/basic-operations.md +++ /dev/null @@ -1,230 +0,0 @@ ---- -id: binary-tree-operations -sidebar_position: 2 -title: Basic Operations on Binary Trees -sidebar_label: Binary Tree Operations -description: "In this blog post, we'll cover the basic operations on binary trees, including insertion, deletion, searching, and traversal techniques, with examples in C++." -tags: [dsa, data structures, binary trees] ---- - -## Introduction -Binary trees are a versatile data structure that allows for efficient operations like searching, insertion, and deletion. In this post, we’ll explore the core operations used to manipulate binary trees, along with traversal methods that are key to utilizing binary trees effectively. - -## Basic Operations on Binary Trees - -### 1. Insertion -Inserting a new node into a binary tree involves placing the node in its correct position, maintaining the structure of the binary tree. - -#### Example in C++: -```cpp -// Insert function -Node* insert(Node* root, int val) { - if (root == nullptr) { - return new Node(val); // Inserting at an empty spot - } - if (val < root->data) { - root->left = insert(root->left, val);//Traversing to left sub-tree - } else { - root->right = insert(root->right, val);//Traversing to right sub-tree - } - return root; -} -``` -``` -Inserting E at the right of B - - A A - / \ / \ - B C ------> B C - / / \ / \ / \ - D F G D E F G -``` -### 2. Deletion -In a binary tree, when deleting a node, the node to be deleted is replaced by the deepest node in the tree. This approach ensures that the tree remains complete. The deletion process involves the following steps: - -#### 1. Identify the Deepest Node: -Traverse the binary tree to find the deepest node (the node that is the last in the level order traversal). This node will be used to replace the node being deleted. - -#### 2. Replace the Node: -Replace the value of the node to be deleted with the value of the deepest node. - -#### 3. Delete the Deepest Node: -Remove the deepest node from the tree. Since it is a leaf node, you can simply delete it. - -#### Example in C++: -```cpp -// Helper function to remove the deepest rightmost node -void remove_node(Node* root, Node* n) { - if (root == nullptr) { - return; - } - if (root == n) { - delete root; - root = nullptr; - return; - } - if (root->left == n) { - delete n; - root->left = nullptr; - return; - } - if (root->right == n) { - delete n; - root->right = nullptr; - return; - } - remove_node(root->left, n); - remove_node(root->right, n); -} - -// Function to delete a node in a binary tree -Node* delete_node(Node* root, int key) { - if (root == nullptr) - return nullptr; - - // Queue for level order traversal - std::queue Q; - Q.push(root); - - Node* key_node = nullptr; - Node* curr_node = nullptr; - - // Level order traversal to find the node to delete and the deepest node - while (!Q.empty()) { - curr_node = Q.front(); - Q.pop(); - - // If the node with the given key is found, store it - if (curr_node->data == key) { - key_node = curr_node; - } - - // Traverse the left child - if (curr_node->left != nullptr) { - Q.push(curr_node->left); - } - - // Traverse the right child - if (curr_node->right != nullptr) { - Q.push(curr_node->right); - } - } - - // If the node to delete was found, replace its value with the deepest node's value - if (key_node != nullptr) { - int x = curr_node->data; // Value of the deepest rightmost node - key_node->data = x; // Replace the key_node's data with deepest node data - remove_node(root, curr_node); // Remove the deepest rightmost node - } - - return root; -} -``` -``` -Case # 01: Deleting A (Root Node Removal) - - A G - / \ / \ - B C ------> B C - / \ / \ / \ / - D E F G D E F -``` -### 3. Searching -Searching for a value in a binary tree involves comparing the value with the current node’s data and then recursively searching in the left or right subtree based on the comparison. - -#### Example in C++: -```cpp -bool search(Node* root, int val) { - if (root == nullptr) { - return false; // Base case: reached a null node, value not found - } - if (root->data == val) { - return true; // Value found - } else if (val < root->data) { - return search(root->left, val); // Search in the left subtree - } else { - return search(root->right, val); // Search in the right subtree - } -} -``` -## Complexity Analysis of Binary Tree Operations - -### 1. Time Complexity - -| OPERATION | BEST CASE | AVERAGE CASE | WORST CASE | -|------------|------------|--------------|------------| -| Insertion | O(logN) | O(N^0.5) | O(N) | -| Search | O(1) | O(N^0.5) | O(N) | -| Deletion | O(logN) | O(N^0.5) | O(N) | - -### 2. Space Complexity -The space complexity of the Binary Tree for all operations is O(N). - - -## Binary Tree Traversals -Traversal refers to visiting all nodes in a binary tree in a specific order. There are three main types of traversal: - -#### a) Pre-order Traversal (Root, Left, Right) -In pre-order traversal, we visit the root node first, then the left subtree, and finally the right subtree. This method is useful for creating a copy of the tree or for prefix expression evaluations. - -#### Example in C++: -```cpp -void preOrder(Node* root) { - if (root == nullptr) return; - cout << root->data << " "; // Visit the root node - preOrder(root->left); // Traverse the left subtree - preOrder(root->right); // Traverse the right subtree -} -``` -``` - A - / \ - B C - / \ / \ - D E F G - - Pre-Order Traversal: A B D E C F G -``` - -#### b) In-order Traversal (Left, Root, Right) -In in-order traversal, we visit the left subtree first, then the root node, and finally the right subtree. For binary search trees, in-order traversal visits nodes in ascending order. - -#### Example in C++: -```cpp -void inOrder(Node* root) { - if (root == nullptr) return; - inOrder(root->left); // Traverse the left subtree - cout << root->data << " "; // Visit the root node - inOrder(root->right); // Traverse the right subtree -} -``` -``` - A - / \ - B C - / \ / \ - D E F G - - In-Order Traversal: D B E A F C G -``` -#### c) Post-order Traversal (Left, Right, Root) -In post-order traversal, we visit the left subtree first, followed by the right subtree, and finally the root node. - -#### Example in C++: -```cpp -void postOrder(Node* root) { - if (root == nullptr) return; - postOrder(root->left); // Traverse the left subtree - postOrder(root->right); // Traverse the right subtree - cout << root->data << " "; // Visit the root node -} -``` -``` - A - / \ - B C - / \ / \ - D E F G - - Post-Order Traversal: D E B F G C A -``` diff --git a/docs/binary-trees/binary-tree.md b/docs/binary-trees/binary-tree.md deleted file mode 100644 index 76595fe80..000000000 --- a/docs/binary-trees/binary-tree.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: binary-tree-intro -sidebar_position: 1 -title: Binary Trees -sidebar_label: Binary Trees -description: "In this blog post, we'll explore binary trees, a fundamental data structure in computer science that enables efficient data organization and retrieval." -tags: [dsa, data structures, binary trees] ---- - -## Introduction -Binary trees are a fundamental data structure used to represent hierarchical relationships between elements. Each node in a binary tree has at most two children, referred to as the left child and the right child. This structure allows for efficient searching, insertion, and deletion operations, making binary trees an essential concept in computer science. - -## Definition and Structure -A binary tree consists of nodes, where each node contains: -- **Data:** The value stored in the node. -- **Left Child:** A reference to the left subtree (or null if no left child exists). -- **Right Child:** A reference to the right subtree (or null if no right child exists). - -The tree begins with a single node called the **root**. The hierarchical structure allows for organized storage and retrieval of data. - -## Properties -Key characteristics of binary trees include: -- **Height:** The length of the longest path from the root to a leaf node. The height of an empty tree is -1, and the height of a tree with only one node is 0. -- **Depth:** The distance from the root to a specific node. The root node has a depth of 0. -- **Balance:** A tree is considered balanced if the heights of the left and right subtrees of any node differ by at most one. - - ``` - A - / \ - B C - / / \ - D F G - - Height of the tree: 2 - - Depth of D, E, F: 2 - - Balanced: Yes, the tree is balanced. - ``` - - -## Types of Binary Trees -1. **Full Binary Trees:** Every node has either 0 or 2 children. - ``` - A - / \ - B C - / \ - D E - ``` - -2. **Complete Binary Trees:** All levels are completely filled except possibly for the last level, which is filled from left to right. - ``` - A - / \ - B C - / \ / - D E F - ``` -3. **Perfect Binary Trees:** All internal nodes have two children, and all leaf nodes are at the same level. - ``` - A - / \ - B C - / \ / \ - D E F G - ``` -4. **Balanced Binary Trees:** The heights of the two child subtrees of any node differ by at most one (e.g., AVL Trees, Red-Black Trees). - ``` - A (d=1) - / \ - (d=0) B C (d=0) - / \ - (d=0) F G (d=0) - - Depth of a node(d)=[height of left child - height of right child] - ``` - - -5. **Degenerate Trees:** Each parent node has only one child, essentially behaving like a linked list. - ``` - A - \ - B - \ - C - \ - D -## Implementation - -Let us see how to implement binary search in C++: -```cpp -struct Node { - int data; - Node* left; - Node* right; - - Node(int val) { - data = val; - left = nullptr; - right = nullptr; - } -}; -int main(){ - - Node* root = new Node(1); - root->left = new Node(2); - root->right = new Node(3); - root->left->left = new Node(4); - root->right->left = new Node(5); - root->right->right = new Node(6); - // 1 - // / \ - // 2 3 - // / / \ - // 4 5 6 - -} -``` -## Advantages and Disadvantages -**Advantages:** -- Efficient searching, insertion, and deletion operations. -- Provides a hierarchical representation of data. -- Allows for ease of traversal using various methods (in-order, pre-order, post-order). - -**Disadvantages:** -- Can become unbalanced, leading to degraded performance (e.g., O(n) in the worst case). -- Memory overhead for pointers, as each node must store references to its children. - - -## Applications of Binary Trees - -- **Search Algorithms**: - Binary search algorithms use the structure of binary trees to efficiently search for a specific element. - -- **Sorting Algorithms**: - Binary trees can be used to implement efficient sorting algorithms, such as tree sort and heap sort. - -- **Database Systems**: - Binary trees can be used to store data in a database system, with each node representing a record. This allows for efficient search operations and enables the database system to handle large amounts of data. - -- **File Systems**: - Binary trees can be used to implement file systems, where each node represents a directory or file. - -- **Compression Algorithms**: - Binary trees can be used to implement Huffman coding, a compression algorithm that assigns variable-length codes to characters based on their frequency of occurrence in the input data. - -- **Decision Trees**: - Binary trees can be used to implement decision trees. - -- **Game AI**: - Binary trees can be used to implement game AI, where each node represents a possible move in the game. The AI algorithm can search the tree to find the best possible move. - - diff --git a/docs/binary-trees/expression-tree.md b/docs/binary-trees/expression-tree.md deleted file mode 100644 index 0065eb0fe..000000000 --- a/docs/binary-trees/expression-tree.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: expression tree -title: Postfix to Infix conversion -sidebar_label: expression tree -description: "Given a postfix expression construct a tree that stores operator as internal nodes and the opernads as leaves. On inorder traversal it gives the infix expression of the postfix." -tags: [dsa, binary trees, recursion, c++] ---- - -## Introduction -Binary trees are a fundamental data structure used to represent hierarchical relationships between elements. Each node in a binary tree has at most two children, referred to as the left child and the right child. This structure allows for efficient searching, insertion, and deletion operations, making binary trees an essential concept in computer science. A postfix expression is an arithmetic expression where operators follow their operands, allowing evaluation without parentheses or precedence rules, using a stack-based approach. An infix expression is an arithmetic expression where operators are placed between operands (e.g., A + B), requiring parentheses or operator precedence to determine the order of operations. - - -## Problem Definition -Given a postfix expression, construct an expression tree from the given expression, where operators are internal nodes, and operands are leaf nodes. When you perform an inorder traversal on this tree, it should yield the corresponding infix expression of the postfix input. - -## Approach -### 1. Initialize a Stack - - Create an empty stack to store tree nodes. - -### 2. Process Each Character in the Postfix Expression - - **If the character is an operand** (e.g., a letter or number), create a new tree node with this operand as its value, and push it onto the stack. - - **If the character is an operator** (e.g., `+`, `-`, `*`, `/`): - - Pop the top two nodes from the stack. The first node popped is the **right child**, and the second node is the **left child**. - - Create a new tree node with the operator as its value and set the popped nodes as its children (left and right). - - Push this new node (subtree) back onto the stack. - -### 3. Final Root Node - - After processing all characters, the stack will contain only one node, which is the **root of the expression tree**. - -### 4. Inorder Traversal to Get Infix Expression - - Perform an **inorder traversal** on the tree. This traversal will give the infix expression equivalent of the original postfix expression. - -## Example Walkthrough -For a postfix expression `"ab+c*"`: - -1. Process `a` and `b` (operands): push as nodes onto the stack. -2. Process `+` (operator): pop `b` and `a`, create a `+` node with `a` as the left child and `b` as the right child, and push the `+` node back. -3. Process `c` (operand): push as a node onto the stack. -4. Process `*` (operator): pop the `+` subtree and `c`, create a `*` node with `+` as the left child and `c` as the right child, and push the `*` node back. -5. The stack now has one node (root of the tree). - -**Inorder traversal** on this tree will yield `((a + b) * c)`, which is the infix expression. - -## C++ Code Implementation - -```cpp - -#include -#include -#include - -using namespace std; - -// TreeNode class to represent each node in the expression tree -class TreeNode { -public: - char value; - TreeNode* left; - TreeNode* right; - - TreeNode(char val) : value(val), left(nullptr), right(nullptr) {} -}; - -// Function to check if a character is an operator -bool isOperator(char c) { - return (c == '+' || c == '-' || c == '*' || c == '/'); -} - -// Function to construct the expression tree from a postfix expression -TreeNode* constructExpressionTree(const string& postfix) { - stack stack; - - for (char ch : postfix) { - if (isOperator(ch)) { - // Pop two nodes for the operator - TreeNode* right = stack.top(); stack.pop(); - TreeNode* left = stack.top(); stack.pop(); - - // Create a new node with the operator and attach left and right children - TreeNode* node = new TreeNode(ch); - node->left = left; - node->right = right; - - // Push the new subtree back onto the stack - stack.push(node); - } else { - // Push operand as a new node onto the stack - stack.push(new TreeNode(ch)); - } - } - - // The remaining node in the stack is the root of the expression tree - return stack.top(); -} - -// Function to perform inorder traversal of the expression tree -void inorderTraversal(TreeNode* root) { - if (root == nullptr) return; - - // Add parentheses for operators to get the correct infix expression - if (isOperator(root->value)) cout << "("; - - inorderTraversal(root->left); - cout << root->value; - inorderTraversal(root->right); - - if (isOperator(root->value)) cout << ")"; -} - -int main() { - string postfix = "ab+c*"; - - // Construct the expression tree - TreeNode* root = constructExpressionTree(postfix); - - // Print the infix expression using inorder traversal - cout << "Infix Expression: "; - inorderTraversal(root); - cout << endl; - - return 0; -} - -``` -## Code Analysis - -### Time Complexity -- **Constructing the Expression Tree**: **O(n)**, where **n** is the number of characters in the postfix expression. -- **Inorder Traversal**: **O(n)**. -- **Overall**: **O(n)**. - -### Space Complexity -- **Stack and Tree Storage**: **O(n)** for both the stack and the expression tree. - -## Summary -The implementation effectively constructs an expression tree from a postfix expression and outputs the corresponding infix expression, with efficient time and space complexities, and a clear, maintainable structure. diff --git a/docs/binary-trees/maximum-depth.md b/docs/binary-trees/maximum-depth.md deleted file mode 100644 index a55894a2e..000000000 --- a/docs/binary-trees/maximum-depth.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: maximum-depth-binary-tree -sidebar_position: 11 -title: Maximum Depth of a Binary Tree -sidebar_label: Maximum Depth -description: "This blog post covers how to find the maximum depth (or height) of a binary tree in C++, along with explanations and code examples." -tags: [dsa, binary trees, recursion, c++] ---- - - -In this post, we will discuss how to calculate the **maximum depth** (also known as the height) of a binary tree. The maximum depth of a binary tree is the number of nodes along the longest path from the root node down to the farthest leaf node. - -## Problem Definition -Given a binary tree, the **maximum depth** is defined as the length of the longest path from the root to a leaf. In other words, it represents the number of nodes along the longest path from the root node down to the deepest leaf node. - -### Example -Consider the following binary tree: - -``` - 1 - / \ - 2 3 - / \ -4 5 -``` - -The maximum depth of this tree is `3`, as the longest path is either `1 → 2 → 4` or `1 → 2 → 5`. - -## Approach -To calculate the maximum depth of a binary tree, we can use a recursive approach. At each node, we need to determine the depth of the left subtree and the right subtree. The maximum depth is the larger of the two, plus one (for the current node). - -### Steps: -1. If the tree is empty (i.e., the current node is `NULL`), the depth is `0`. -2. Recursively calculate the depth of the left and right subtrees. -3. Return the maximum of the two depths, plus `1` for the current node. - -### C++ Code Implementation - -```cpp -#include -using namespace std; - -// Definition for a binary tree node -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Function to find the maximum depth of a binary tree -int maxDepth(TreeNode* root) { - // Base case: if the tree is empty, return 0 - if (root == NULL) - return 0; - - // Recursive case: calculate the depth of left and right subtrees - int leftDepth = maxDepth(root->left); - int rightDepth = maxDepth(root->right); - - // Return the larger of the two depths, plus 1 for the current node - return max(leftDepth, rightDepth) + 1; -} - -int main() { - // Create a sample binary tree - TreeNode* root = new TreeNode(1); - root->left = new TreeNode(2); - root->right = new TreeNode(3); - root->left->left = new TreeNode(4); - root->left->right = new TreeNode(5); - - // Calculate and print the maximum depth of the binary tree - cout << "Maximum Depth of the Binary Tree: " << maxDepth(root) << endl; - - return 0; -} -``` -## Explanation of the Code - -### TreeNode Structure -We define a `TreeNode` structure to represent each node in the binary tree. Each node contains the following fields: -- **val:** The value stored in the node. -- **left:** A pointer/reference to the left child node (or `NULL` if there is no left child). -- **right:** A pointer/reference to the right child node (or `NULL` if there is no right child). - -### maxDepth Function -The `maxDepth` function is a recursive function used to calculate the maximum depth of the binary tree. - -- **Base Case:** If the current node is `NULL`, the function returns `0`, indicating an empty tree or subtree. -- **Recursive Case:** If the current node is not `NULL`, the function recursively computes the depth of the left and right subtrees. - - It then returns the maximum of the two depths plus `1`, which accounts for the current node's depth. - -### main Function -In the `main` function: -- We create a sample binary tree by manually assigning nodes and their left and right children. -- The `maxDepth` function is then called with the root of the binary tree to calculate the maximum depth. -- Finally, the result is printed to the console. - -## Time Complexity - -The time complexity of this approach is **O(N)**, where `N` is the number of nodes in the binary tree. This is because the function visits each node exactly once during the recursive traversal. diff --git a/docs/binary-trees/merkle-tree.md b/docs/binary-trees/merkle-tree.md deleted file mode 100644 index 27b96236a..000000000 --- a/docs/binary-trees/merkle-tree.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -id: merkle-tree-algorithm -title: Merkle Tree Algorithm -sidebar_label: Merkle Tree Algorithm -sidebar_position: 1 -description: "The Merkle Tree is a cryptographic structure used for efficient and secure data verification in distributed systems." -tags: [Cryptography, merkle-tree-algorithm, Data Integrity, Distributed Systems, Blockchain] ---- - - -# Merkle Tree Algorithm - -## Overview -Merkle Tree is a cryptographic data structure used to ensure the integrity and consistency of data in systems such as blockchain, distributed storage, and peer-to-peer networks. By using a tree of hash functions, Merkle Trees allow efficient and secure verification of large data sets. - -## Introduction -A Merkle Tree, also known as a hash tree, is a binary tree where each leaf node contains a hash of data blocks, and each non-leaf node contains a hash of its child nodes. The root node of the Merkle Tree is called the Merkle Root and provides a unique fingerprint of the entire dataset. Merkle Trees enable fast verification of data integrity without requiring access to the entire dataset. - -## Characteristics of Merkle Tree Algorithm -- **Efficient Verification**: Merkle Trees allow efficient verification of whether a data block belongs to a dataset by providing proof with logarithmic complexity. -- **Tamper Resistance**: Any modification to the underlying data changes the Merkle Root, ensuring tamper-proof data integrity. -- **Scalability**: Merkle Trees scale well with increasing data size, enabling their use in distributed systems and large datasets. - -## How the Merkle Tree Algorithm Works -1. **Initialization**: - - Divide the dataset into smaller blocks of data. - - Hash each block using a cryptographic hash function (e.g., SHA-256) to create leaf nodes. - -2. **Building the Tree**: - - Pair the leaf nodes and compute the hash of each pair to form the parent nodes. - - Continue pairing and hashing the parent nodes until only one node (Merkle Root) remains. - -3. **Verification Process**: - - To verify the inclusion of a specific data block, provide the hashes of sibling nodes along the path from the leaf node to the root. - - Recompute the hashes up the tree to ensure the resulting Merkle Root matches the original root. - -## Step-by-Step Execution - -Here’s an example of how the Merkle Tree Algorithm works on a small dataset of four blocks: - -```mermaid -graph TB - A((Block1)) --> H1((Hash1)) - B((Block2)) --> H2((Hash2)) - C((Block3)) --> H3((Hash3)) - D((Block4)) --> H4((Hash4)) - H1 --> P1((Parent1)) - H2 --> P1 - H3 --> P2((Parent2)) - H4 --> P2 - P1 --> R((MerkleRoot)) - P2 --> R -``` -## Execution Steps -1. **Hash each block**: - - `H1 = Hash(Block1)` - - `H2 = Hash(Block2)` - - `H3 = Hash(Block3)` - - `H4 = Hash(Block4)` - -2. **Combine hashes**: - - `P1 = Hash(H1 + H2)` - - `P2 = Hash(H3 + H4)` - -3. **Compute the Merkle Root**: - - `MerkleRoot = Hash(P1 + P2)` - -## Time Complexity -- Constructing a Merkle Tree: **O(n)**, where **n** is the number of leaf nodes (data blocks). -- Verifying the inclusion of a block: **O(log n)** comparisons due to the binary structure. - -## Applications -- **Blockchain Technology**: Ensures transaction integrity. -- **Peer-to-Peer Networks**: Verifies file integrity in distributed systems like BitTorrent. -- **Data Storage Systems**: Detects data corruption in distributed storage. -- **Version Control Systems**: Tracks changes in file versions across distributed repositories. -# Merkle Tree Algorithm - -## Pseudocode - -1. **Divide the dataset into blocks** and hash each block to create leaf nodes. -2. **While more than one node exists**: - - a. Pair adjacent nodes and hash their concatenated values. - - b. Form a parent node with the resulting hash. -3. The final node is the **Merkle Root**. -4. **To verify a block**: - - a. Obtain the hash path from the leaf to the root. - - b. Recompute hashes using sibling nodes and check if the Merkle Root matches. - -## Advantages of Merkle Tree Algorithm -- **Efficient Data Verification**: Minimal data is required for verification, making it scalable. -- **Tamper Detection**: Any change to the data alters the Merkle Root, ensuring data integrity. -- **Scalability**: Ideal for large datasets due to its logarithmic structure. - -## Limitations -- **Hash Collisions**: Though unlikely, hash functions may produce the same hash for different data, compromising integrity. -- **Fixed Data Size**: Works well with fixed-size blocks; varying block sizes require extra processing. - -# Merkle Tree vs. Binary Tree - -| Feature | Merkle Tree | Binary Tree | -|-----------------|---------------------------------------------------------------------------|------------------------------------------------------------| -| **Data Storage** | Stores hashes in non-leaf nodes and data in leaf nodes | Stores actual data in both leaf and non-leaf nodes | -| **Verification** | Efficient cryptographic verification using hash paths | Does not provide cryptographic verification | -| **Time Complexity** | O(log n) for verification | O(n) for searching or traversing the tree | -| **Use Case** | Used for verifying data integrity in large datasets | Used for general data storage and searching tasks | - -## Conclusion - -The Merkle Tree Algorithm is a key cryptographic tool for ensuring data integrity in distributed systems. Its scalability and efficiency make it essential for applications in blockchain, distributed storage, and data verification. Understanding Merkle Trees is crucial for anyone working in modern cryptographic or distributed technologies. - diff --git a/docs/binary-trees/minimum-depth.md b/docs/binary-trees/minimum-depth.md deleted file mode 100644 index 5936defe1..000000000 --- a/docs/binary-trees/minimum-depth.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: minimum-depth-binary-tree -sidebar_position: 12 -title: Minimum Depth of a Binary Tree -sidebar_label: Minimum Depth -description: "This blog post covers how to find the minimum depth (or height) of a binary tree in C++, along with explanations and code examples." -tags: [dsa, binary trees, recursion, c++] ---- - - -In this post, we will discuss how to calculate the **minimum depth** of a binary tree. The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. - -## Problem Definition -Given a binary tree, the **minimum depth** is defined as the length of the shortest path from the root to a leaf. In other words, it represents the number of nodes along the shortest path from the root node down to the closest leaf node. - - -## Approach -To calculate the minimum depth of a binary tree, we can use a recursive approach. At each node, we need to determine the depth of the left subtree and the right subtree. The minimum depth is the smaller of the two, but we need to be careful when one of the subtrees is missing (i.e., `NULL`), in which case we must consider only the non-`NULL` subtree. - -### Steps: -1. If the tree is empty (i.e., the current node is `NULL`), the depth is `0`. -2. If one of the subtrees is `NULL`, we return the depth of the non-`NULL` subtree plus `1` (to account for the current node). -3. Otherwise, we recursively calculate the depth of the left and right subtrees, and return the smaller of the two depths, plus `1` for the current node. - -### C++ Code Implementation - -```cpp -#include -using namespace std; - -// Definition for a binary tree node -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; - -// Function to find the minimum depth of a binary tree -int minDepth(TreeNode* root) { - // Base case: if the tree is empty, return 0 - if (root == NULL) - return 0; - - // If the left subtree is NULL, recurse on the right subtree - if (root->left == NULL) - return minDepth(root->right) + 1; - - // If the right subtree is NULL, recurse on the left subtree - if (root->right == NULL) - return minDepth(root->left) + 1; - - // If both left and right subtrees are non-NULL, find the minimum depth - return min(minDepth(root->left), minDepth(root->right)) + 1; -} - -int main() { - // Create a sample binary tree - TreeNode* root = new TreeNode(1); - root->left = new TreeNode(2); - root->right = new TreeNode(3); - root->left->left = new TreeNode(4); - - // Calculate and print the minimum depth of the binary tree - cout << "Minimum Depth of the Binary Tree: " << minDepth(root) << endl; - - return 0; -} - -``` - -## Explanation of the Code - -### TreeNode Structure -We define a `TreeNode` structure to represent each node in the binary tree. Each node contains the following fields: - -- **val:** The value stored in the node. -- **left:** A pointer/reference to the left child node (or `NULL` if there is no left child). -- **right:** A pointer/reference to the right child node (or `NULL` if there is no right child). - -### minDepth Function -The `minDepth` function is a recursive function used to calculate the minimum depth of the binary tree. - -- **Base Case:** If the current node is `NULL`, the function returns `0`, indicating an empty tree or subtree. -- **Subtree Case:** If the current node has only one non-`NULL` child, the function recurses on that child and adds `1` for the current node. -- **Recursive Case:** If the current node has both left and right children, the function recursively computes the depth of both subtrees and returns the smaller of the two depths, plus `1` for the current node. - -### main Function -In the `main` function: - -1. We create a sample binary tree by manually assigning nodes and their left and right children. -2. The `minDepth` function is then called with the root of the binary tree to calculate the minimum depth. -3. Finally, the result is printed to the console. - -## Time Complexity -The time complexity of this approach is **O(N)**, where `N` is the number of nodes in the binary tree. This is because the function visits each node exactly once during the recursive traversal. - diff --git a/docs/binary-trees/practice-problems.md b/docs/binary-trees/practice-problems.md deleted file mode 100644 index ce59b23c6..000000000 --- a/docs/binary-trees/practice-problems.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -id: binary-trees-practice-problems -title: Practice Problems on Binary Trees -sidebar_label: Practice Problems - -description: "In this post, we'll provide a list of curated practice problems on Binary Trees from platforms like LeetCode and GeeksforGeeks. Binary Trees are fundamental in computer science, and practicing these problems will help in strengthening your understanding of tree data structures." - -tags: [dsa, algorithms, binary-trees, practice-problems] ---- - -## Binary Trees Practice Problems - -### Tree Traversal (Inorder, Preorder, Postorder) - -- [Preorder Traversal of Binary Tree](https://leetcode.com/problems/binary-tree-preorder-traversal/) -- [Inorder Traversal of Binary Tree](https://leetcode.com/problems/binary-tree-inorder-traversal/) -- [Post-order Traversal of Binary Tree](https://leetcode.com/problems/binary-tree-postorder-traversal/) -- [Level order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) - -### Medium problems - -- [Height of a Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) -- [Check if the Binary tree is height-balanced or not](https://leetcode.com/problems/balanced-binary-tree/) -- [Diameter of Binary Tree](https://leetcode.com/problems/diameter-of-binary-tree/) -- [Maximum path sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) -- [Check if two trees are identical or not](https://leetcode.com/problems/same-tree/) -- [Zig Zag Traversal of Binary Tree](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) -- [Boundary Traversal of Binary Tree](https://leetcode.com/problems/boundary-of-binary-tree/) -- [Vertical Order Traversal of Binary Tree](https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree/) -- [Top View of Binary Tree](https://practice.geeksforgeeks.org/problems/top-view-of-binary-tree/1) -- [Bottom View of Binary Tree](https://practice.geeksforgeeks.org/problems/bottom-view-of-binary-tree/1) -- [Right/Left View of Binary Tree](https://leetcode.com/problems/binary-tree-right-side-view/) -- [Symmetric Binary Tree](https://leetcode.com/problems/symmetric-tree/) - -### Hard problems - -- [Root to Node Path in Binary Tree](https://bit.ly/3QA600D) -- [LCA in Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) -- [Maximum width of a Binary Tree](https://leetcode.com/problems/maximum-width-of-binary-tree/) -- [Check for Children Sum Property](https://bit.ly/3dEr73g) -- [Print all the Nodes at a distance of K in a Binary Tree](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/) -- [Minimum time taken to BURN the Binary Tree from a Node](https://bit.ly/3wcg7k1) -- [Count total Nodes in a COMPLETE Binary Tree](https://leetcode.com/problems/count-complete-tree-nodes/) -- [Requirements needed to construct a Unique Binary Tree | Theory](https://bit.ly/3UVCR1U) -- [Construct Binary Tree from inorder and preorder](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) diff --git a/docs/binary-trees/splay-trees.md b/docs/binary-trees/splay-trees.md deleted file mode 100644 index 396a13528..000000000 --- a/docs/binary-trees/splay-trees.md +++ /dev/null @@ -1,155 +0,0 @@ ---- - -id: splay-intro -sidebar_position: 2 -title: Splay Trees -sidebar_label: Splay Trees -description: "In this blog post, we'll explore Splay Trees, a type of self-adjusting binary search tree that provides amortized logarithmic time complexity for search, insertion, and deletion operations." -tags: [dsa, data structures, splay-trees] - ---- - -## Introduction - -A **Splay Tree** is a self-adjusting binary search tree (BST) that performs basic operations such as search, insertion, and deletion in amortized O(log n) time. The tree self-adjusts by moving the most recently accessed element to the root through a process called **splaying**. This ensures that frequently accessed elements are quick to reach in future operations. - -Splay trees are particularly effective when access patterns exhibit locality of reference, meaning that recently accessed elements are likely to be accessed again soon. - -## Properties of Splay Trees - -1. **Self-adjusting**: The most recently accessed node is moved to the root of the tree. -2. **Binary Search Tree**: Maintains the basic properties of a BST, where for any node `x`, the left subtree contains nodes with keys less than `x` and the right subtree contains nodes with keys greater than `x`. -3. **Amortized Complexity**: Although individual operations can take O(n) in the worst case, the amortized time complexity of operations is O(log n). - -## Definition and Structure - -A Splay Tree consists of nodes with the following attributes: -- **Data**: The value stored in the node. -- **Left Child**: A reference to the left subtree. -- **Right Child**: A reference to the right subtree. - -## Splaying Operations - -Splaying is the process of moving a node to the root of the tree by performing a sequence of rotations. This operation restructures the tree based on access patterns, making frequently accessed nodes easier to reach. - -### Types of Rotations - -Splay Trees perform three types of rotations during splaying: - -1. **Zig Rotation**: Performed when the node is a child of the root. A single rotation is performed to move the node to the root. -2. **Zig-Zig Rotation**: Performed when both the node and its parent are either left or right children. Two single rotations are performed. -3. **Zig-Zag Rotation**: Performed when the node is a left child, but its parent is a right child (or vice versa). A double rotation is performed to move the node to the root. - -## Operations on Splay Trees - -### 1. Insertion - -Inserting a new node into a Splay Tree involves a typical BST insertion followed by splaying the newly inserted node to the root. - -#### Code Example (C++) - -```cpp -struct Node { - int data; - Node* left; - Node* right; -}; - -Node* splay(Node* root, int key); - -Node* insert(Node* root, int key) { - if (root == nullptr) { - Node* newNode = new Node(); - newNode->data = key; - newNode->left = nullptr; - newNode->right = nullptr; - return newNode; - } - - // Splay the tree to bring the closest node to root - root = splay(root, key); - - if (root->data == key) return root; // Node already exists - - Node* newNode = new Node(); - newNode->data = key; - - if (key < root->data) { - newNode->right = root; - newNode->left = root->left; - root->left = nullptr; - } else { - newNode->left = root; - newNode->right = root->right; - root->right = nullptr; - } - - return newNode; -} -``` - -### 2. Searching - -Searching for a node in a Splay Tree involves first performing a standard BST search. Once the node is found (or the closest node), splaying brings it to the root to optimize future searches. - -### Code Example (C++) - -```cpp -Node* splay(Node* root, int key); - -Node* search(Node* root, int key) { - return splay(root, key); -} -``` - -### 3. Deletion - -Deletion in a Splay Tree is a two-step process. First, the node to be deleted is splayed to the root. Then, the tree is split into two subtrees (left and right), and the right subtree is splayed to bring the smallest element to the root, after which it is joined with the left subtree. - -### Code Example (C++) - -```cpp -Node* deleteNode(Node* root, int key) { - if (root == nullptr) return nullptr; - - // Splay the node to the root - root = splay(root, key); - - // If the node isn't present, return - if (root->data != key) return root; - - Node* temp; - if (root->left == nullptr) { - temp = root; - root = root->right; - } else { - temp = root; - root = splay(root->left, key); - root->right = temp->right; - } - - delete temp; - return root; -} -``` - -## Advantages and Disadvantages - -### Advantages: -- **Amortized O(log n)** time complexity for search, insertion, and deletion. -- Frequently accessed elements are fast to access, making the tree ideal for caches and other data structures with locality of reference. -- Simpler than AVL or Red-Black trees since no explicit balancing is required after every operation. - -### Disadvantages: -- **Worst-case O(n)** time complexity for individual operations, though this is rare with random access patterns. -- Not as strictly balanced as other self-balancing trees like AVL or Red-Black Trees. -- Performance can degrade if access patterns are highly unbalanced. - -## Applications of Splay Trees - -- **Cache Implementations**: Splay trees are often used in cache implementations where recent access patterns exhibit temporal locality. -- **Data Compression**: Splay trees are used in some data compression algorithms like adaptive Huffman encoding. -- **Memory Management**: Splay trees are employed in certain dynamic memory allocation schemes for efficient block management. -- **Network Routers**: Splay trees are used to manage routing tables that require frequent updates. - ---- diff --git a/docs/bit-manipulation/_category_.json b/docs/bit-manipulation/_category_.json deleted file mode 100644 index 396537ead..000000000 --- a/docs/bit-manipulation/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Bit Manipulation", - "position": 7, - "link": { - "type": "generated-index", - "description": "Bit manipulation involves operating directly on binary digits or bits, which are the most basic units of data in computing. Bit manipulation is used in low-level programming tasks where performance and memory efficiency are crucial. This documentation covers key concepts, operations, and techniques in bit manipulation." - } -} diff --git a/docs/bit-manipulation/bit-manipulation-technique.md b/docs/bit-manipulation/bit-manipulation-technique.md deleted file mode 100644 index 976acbb62..000000000 --- a/docs/bit-manipulation/bit-manipulation-technique.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -id: bit-manipulation-technique -title: Bit Manipulation Technique -sidebar_label: Bit Manipulation introduction -sidebar_position: 2 -description: 'Bit manipulation involves operating directly on binary digits or bits, which are the most basic units of data in computing. Bit manipulation is used in low-level programming tasks where performance and memory efficiency are crucial. This documentation covers key concepts, operations, and techniques in bit manipulation.' -tags: [dsa, Bit-Manipulation, technique] ---- - -## 1. Introduction to Bit and Binary Numbers - -A **bit** is the smallest unit of data in a computer and can have a value of either 0 or 1. A sequence of bits can represent numbers, with binary being the base-2 numeral system used by computers. For example, the binary number 101 represents the decimal number 5. - -In **bit manipulation**, we deal with data at the bit level. Operations such as setting, clearing, flipping, or shifting bits are performed using bitwise operators. - -*NOTE: In programming, when you read a series of bits (binary sequence), you start from the right. The last bit on the right is called the Least Significant Bit (LSB), and the first bit on the left is the Most Significant Bit (MSB).* - - -## 2. Basics of bit manipulation: - -### a. AND (&) - -The AND operator compares each bit of two numbers and returns 1 if both bits are 1, otherwise 0. - -```text - 5 & 3 = 101 & 011 = 001 = 1 -``` -### b. OR (|) - -The OR operator compares each bit of two numbers and returns 1 if at least one of the bits is 1, otherwise 0. - -```text - 5 | 3 = 101 | 011 = 111 = 7 -``` - -### c. XOR (^) - -The XOR operator returns 1 if the corresponding bits of the two numbers are different, otherwise it returns 0. - -```text - 5 ^ 3 = 101 ^ 011 = 110 = 6 -``` - -### d. NOT (~) - -The NOT operator inverts the bits of the number (i.e., it converts 1 to 0 and 0 to 1). - -```text - ~5 = ~101 = ...11111010 (depends on bit width, typically 32 bits in practice) -``` - -### e. Left Shift - -The left shift operator shifts the bits of the number to the left by a specified number of positions. For each shift, the leftmost bits are discarded, and zeros are filled in on the right. - -```text - 5 << 1 = 101 << 1 = 1010 = 10 -``` - -### f. Right Shift - -The right shift operator shifts the bits of the number to the right by a specified number of positions. For each shift, the rightmost bits are discarded. - -```text - 5 >> 1 = 101 >> 1 = 10 = 2 -``` - -## 3. Common Bit Manipulation Techniques and Algorithms - -### **Checking if a Number is Odd or Even** -You can check if a number is odd or even by using the AND operator with 1. - -Example: - -```cpp -if (n & 1) { - // n is odd -} else { - // n is even -} -``` -### **Swapping Two Numbers Without a Temporary Variable** -You can swap two numbers using XOR without needing a temporary variable. - -Example: - -```cpp -a = a ^ b; -b = a ^ b; // Now b is the original value of a -a = a ^ b; // Now a is the original value of b -``` -### **Clearing, Setting, and Toggling Bits Clearing a Bit** -To clear a specific bit at position pos, use the AND operator with the bitwise complement of a mask that has a 1 at position pos. - -Example: - -```cpp -n = n & ~(1 << pos); -``` -### **Setting a Bit** -To set a specific bit at position pos, use the OR operator with a mask that has a 1 at position pos. - -Example: - -```cpp -n = n | (1 << pos); -``` -### **Toggling a Bit** -To toggle a bit at position pos, use the XOR operator with a mask that has a 1 at position pos. - -Example: - -```cpp -n = n ^ (1 << pos); -``` -### **Checking a Specific Bit** -To check if a specific bit at position pos is set, use the AND operator. - -Example: - -```cpp -if (n & (1 << pos)) { - // Bit is set -} else { - // Bit is not set -} -``` -### **Counting Set Bits (Hamming Weight)** -The number of 1s in the binary representation of a number is called the Hamming weight or population count. - -Example using *Brian Kernighan’s Algorithm* : -It takes advantage of the idea that when you subtract 1 from a number, it changes all the bits from the rightmost set bit (1) to the end. - -Implementation in C++: - -```cpp -int countSetBits(int n) { - int count = 0; - while (n) { - n = n & (n - 1); // This clears the lowest set bit - count++; - } - return count; -} -``` -### **Isolating the Rightmost 1-bit** -To isolate the rightmost 1 bit in a number, you can use the expression n & -n. - -Example: - -```cpp -rightmostBit = n & -n; -``` -### **Inverting the Lowest Set Bit** -To invert the lowest set bit, you can use the expression n & (n - 1). - -Example: - -```cpp -n = n & (n - 1); -``` - -## 4. Applications of Bit Manipulation -- **Data Compression**: Bit manipulation is used in compression algorithms (e.g., Huffman encoding) to represent data in fewer bits. -- **Cryptography**: Many cryptographic algorithms rely on fast bit-level operations. -- **Embedded Systems**: Bit manipulation is often used in embedded systems for tasks like setting or clearing specific bits in hardware registers. -- **Graphics and Game Development**: Manipulating pixels and color values often requires bit manipulation. -- **Networking**: Network protocols like IP require efficient manipulation of bits to represent addresses, masks, and other data. -## 5. Advantages and Limitations of Bit Manipulation -### Advantages: -**Speed**: Bit manipulation operations are generally faster than arithmetic operations. -**Memory Efficiency**: By operating on individual bits, you can save memory when working with large datasets. -### Limitations: -**Complexity**: Code involving bit manipulation can be harder to read and maintain. -**Limited Use Cases**: Not all applications require bit-level operations, and they are mainly used in performance-critical or hardware-specific applications. -## Conclusion -Bit manipulation is a powerful tool for optimizing code performance and memory usage in low-level programming. Mastering bitwise operators and common techniques is essential for tasks involving hardware interaction, cryptography, and other specialized fields. By understanding how to efficiently use bit manipulation, developers can write faster and more efficient code. \ No newline at end of file diff --git a/docs/bit-manipulation/bitmanipulation-practice-problem.md b/docs/bit-manipulation/bitmanipulation-practice-problem.md deleted file mode 100644 index 06fdfcd18..000000000 --- a/docs/bit-manipulation/bitmanipulation-practice-problem.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -id: practice-problems-for-bitmanipulation -title: Practice Problems for Bit Manipulation -sidebar_label: Practice Problems -sidebar_position: 1 -description: Practice problems for Bit Manipulation to help you understand the concepts better. -tags: [Bit Manipulation, Practice Problems, Bitwise Operators, XOR, AND, OR, Shifting, Masking] ---- - -### Basic Bit Manipulation Problems - -- [Counting Bits](https://leetcode.com/problems/counting-bits/) -- [Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/) -- [Reverse Bits](https://leetcode.com/problems/reverse-bits/) -- [Power of Two](https://leetcode.com/problems/power-of-two/) -- [Single Number](https://leetcode.com/problems/single-number/) -- [Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/) - -### XOR Problems - -- [Single Number II](https://leetcode.com/problems/single-number-ii/) -- [Find Missing Number](https://leetcode.com/problems/missing-number/) -- [XOR Queries of a Subarray](https://leetcode.com/problems/xor-queries-of-a-subarray/) -- [Maximum XOR of Two Numbers in an Array](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) -- [Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) - -### AND, OR, and Shifting Problems - -- [Range Bitwise AND](https://leetcode.com/problems/bitwise-and-of-numbers-range/) -- [Subsets](https://leetcode.com/problems/subsets/) -- [Divide Two Integers](https://leetcode.com/problems/divide-two-integers/) -- [Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) -- [Find Complement](https://leetcode.com/problems/number-complement/) - -### Advanced Bit Manipulation Problems - -- [Maximum XOR of Two Numbers in an Array](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) -- [Total Hamming Distance](https://leetcode.com/problems/total-hamming-distance/) -- [Binary Watch](https://leetcode.com/problems/binary-watch/) -- [Gray Code](https://leetcode.com/problems/gray-code/) -- [Concatenation of Consecutive Binary Numbers](https://leetcode.com/problems/concatenation-of-consecutive-binary-numbers/) - -### Masking and Shifting Problems - -- [Palindrome Partitioning IV](https://leetcode.com/problems/palindrome-partitioning-iv/) -- [Minimum Number of Flips to Convert Binary Matrix to Zero Matrix](https://leetcode.com/problems/minimum-number-of-flips-to-convert-binary-matrix-to-zero-matrix/) -- [Decode XORed Permutation](https://leetcode.com/problems/decode-xored-permutation/) -- [Find XOR Sum of All Pairs Bitwise AND](https://leetcode.com/problems/find-xor-sum-of-all-pairs-bitwise-and/) - -### Miscellaneous Bit Manipulation Problems - -- [Binary Representation of a Number](https://practice.geeksforgeeks.org/problems/binary-representation-of-a-number-1587115620/1) -- [Find Position of Set Bit](https://practice.geeksforgeeks.org/problems/find-position-of-set-bit3706/1) -- [Find the Only Repeating Element](https://practice.geeksforgeeks.org/problems/find-the-only-repeating-element/0) - ---- - -Bit manipulation is a powerful technique to optimize problems related to numbers and binary operations. Practicing these problems will help you get familiar with how bitwise operators work and how to apply them in different scenarios. diff --git a/docs/bit-manipulation/brain-kernighan-algo.md b/docs/bit-manipulation/brain-kernighan-algo.md deleted file mode 100644 index 6d4ff1895..000000000 --- a/docs/bit-manipulation/brain-kernighan-algo.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: brian-kernighan-algo -title: Bit Manipulation Technique -sidebar_label: Brian-Kernighan-Algoithm -sidebar_position: 2 -Description: Brian Kernighan’s Algorithm is an efficient method for counting the number of set bits (1s) in the binary representation of an integer. By leveraging the property that subtracting 1 from a number flips all bits after the rightmost set bit, this algorithm repeatedly clears the lowest set bit until the number becomes zero. It is widely used in applications involving bit manipulation, cryptography, and performance-critical programming, making it a fundamental technique in data structures and algorithms. - -Tags: [dsa, bit manipulation, algorithm, counting bits, efficiency] ---- -# Brian Kernighan's Algorithm for Counting Set Bits (Hamming Weight) - -## Introduction - -**Brian Kernighan’s Algorithm** is an efficient method to count the number of set bits (1s) in the binary representation of a number. This count is often referred to as the **Hamming weight** or **population count**. The algorithm works by repeatedly clearing the lowest set bit of the number until the number becomes zero. - -## How it Works - -The key insight of the algorithm is based on the fact that subtracting 1 from a number flips all the bits after the rightmost set bit (including the set bit itself). By performing a bitwise AND between the number and `n - 1`, the rightmost set bit is cleared. This operation can be repeated until the number becomes 0, with each iteration representing one set bit. - -### Steps in the Algorithm: -1. Initialize a `count` variable to 0. -2. While `n` is not zero: - - Perform `n = n & (n - 1)`. This operation clears the lowest set bit. - - Increment the `count`. -3. When `n` becomes zero, `count` will hold the total number of set bits. - -### Example Walkthrough - -Let’s take an example where `n = 13` (which is `1101` in binary). - -- **Initial value of n**: - `n = 1101` - - First, subtract 1: - `n - 1 = 1100` - - Perform the AND operation: - `n & (n - 1) = 1101 & 1100 = 1100` - - Increment `count = 1` - -- **Second iteration**: - `n = 1100` - - Subtract 1: - `n - 1 = 1011` - - Perform the AND operation: - `n & (n - 1) = 1100 & 1011 = 1000` - - Increment `count = 2` - -- **Third iteration**: - `n = 1000` - - Subtract 1: - `n - 1 = 0111` - - Perform the AND operation: - `n & (n - 1) = 1000 & 0111 = 0000` - - Increment `count = 3` - -Now, `n = 0`, so the loop terminates, and the total number of set bits in `13` is `3`. - -### C++ Implementation - -```cpp -int countSetBits(int n) { - int count = 0; - while (n) { - n = n & (n - 1); // This clears the lowest set bit - count++; - } - return count; -} -``` -### Time Complexity -The time complexity of Brian Kernighan’s Algorithm is O(k), where k is the number of set bits in the number. The algorithm runs in proportion to the number of set bits, making it more efficient than iterating through all bits (which would take O(log n) or O(b) for b bits). - -### Why It's Efficient -Unlike a naive approach that examines each bit in the number (which would involve shifting and counting), Brian Kernighan’s Algorithm only iterates once for each set bit. This makes it especially efficient when the number has relatively few set bits. - -### Conclusion -Brian Kernighan's Algorithm is a powerful technique for counting set bits efficiently, and it is widely used in applications that require bit manipulation. By understanding this algorithm, you can write faster and more optimized code, especially in low-level systems programming, cryptography, and other performance-critical applications. \ No newline at end of file diff --git a/docs/bit-manipulation/clear-ith-Bit.md b/docs/bit-manipulation/clear-ith-Bit.md deleted file mode 100644 index be67f3cbd..000000000 --- a/docs/bit-manipulation/clear-ith-Bit.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: clear-ith-bit -tittle: Clear ith Bit -sidebar-level: Clear ith Bit -sidebar-position: 2 -Description: Clearing the i-th bit in a number is a nifty bit manipulation technique. This involves setting the i-th bit to 0, leaving all other bits unchanged. -tags: [dsa, bit manipulation, clear bits] ---- - -# Description - -Clearing the i-th bit in a number is a common bit manipulation technique. This operation involves setting the i-th bit to 0 while leaving all other bits unchanged. - -## Steps to Clear the i-th Bit -**1. Create a Mask:** Create a number that has all bits set to 1 except for the i-th bit, which is set to 0. - -**2. AND Operation:** Perform a bitwise AND between the original number and the mask. This will clear the i-th bit while keeping all other bits unchanged. - -## Formula -> `mask =∼ (1<<𝑖)` - -> `result = num&mask` - - -# Code in Java -```java -import java.util.*; - -public class clearIthBit { - - public static int clearIthBit(int n, int i) { - int bitMask = ~(1< 0`, `[1] -> 1`, `[2] -> 2`, `[3] -> 3`, `[1,2] -> 3`, `[1,3] -> 2`, `[2,3] -> 1`, `[1,2,3] -> 0`) - - - **Hint:** Use recursion or bit manipulation to generate all subsets. - - **Link:** [Sum of All Subset XOR Totals - LeetCode](https://leetcode.com/problems/sum-of-all-subset-xor-totals?envType=problem-list-v2&envId=combinatorics&difficulty=EASY) - -2. **Distribute Candies Among Children I** - **Description:** You have a certain number of candies to distribute among `k` children in such a way that each child receives at least one candy. The challenge is to maximize the number of children that receive candies while ensuring that no child receives more than one candy. Given `n` candies and `k` children, determine how many children can receive candies. - - - **Example:** - Input: `n = 7, k = 4` - Output: `4` (Each child can get at least one candy) - - - **Hint:** Use the formula for distribution and check constraints. - - **Link:** [Distribute Candies Among Children I - LeetCode](https://leetcode.com/problems/distribute-candies-among-children-i?envType=problem-list-v2&envId=combinatorics&difficulty=EASY) - ---- - -### Medium Problems: - -1. **Unique Paths** - **Description:** Given an `m x n` grid, count the number of unique paths from the top-left corner to the bottom-right corner, moving only down or to the right. The challenge is to implement an algorithm that computes this efficiently. - - - **Example:** - Input: `m = 3, n = 7` - Output: `28` (There are 28 unique paths in a 3x7 grid) - - - **Hint:** Use dynamic programming to store intermediate results. - - **Link:** [Unique Paths - LeetCode](https://leetcode.com/problems/unique-paths?envType=problem-list-v2&envId=combinatorics&difficulty=MEDIUM) - -2. **Ugly Number III** - **Description:** An ugly number is a positive number whose prime factors only include `2`, `3`, and `5`. Given an integer `n`, your task is to find the `n-th` ugly number. - - - **Example:** - Input: `n = 10` - Output: `12` (The first 10 ugly numbers are `1, 2, 3, 4, 5, 6, 8, 9, 10, 12`) - - - **Hint:** Consider a min-heap or dynamic programming to generate ugly numbers efficiently. - - **Link:** [Ugly Number III - LeetCode](https://leetcode.com/problems/ugly-number-iii?envType=problem-list-v2&envId=combinatorics&difficulty=MEDIUM) - -3. **Number of Sets of K Non-Overlapping Line Segments** - **Description:** Given an array of segments defined by their endpoints, count the number of ways to select `k` non-overlapping segments. - - - **Example:** - Input: `segments = [[1, 2], [2, 3], [3, 4]], k = 2` - Output: `1` (Only one way to select two non-overlapping segments) - - - **Hint:** Use combinatorial counting and dynamic programming. - - **Link:** [Number of Sets of K Non-Overlapping Line Segments - LeetCode](https://leetcode.com/problems/number-of-sets-of-k-non-overlapping-line-segments?envType=problem-list-v2&envId=combinatorics&difficulty=MEDIUM) - -4. **Vowels of All Substrings** - **Description:** Count the number of vowels in all substrings of a given string. Each vowel contributes to each substring it appears in. - - - **Example:** - Input: `s = "abc"` - Output: `3` (Vowels: `a` contributes to 1 substring, `b` and `c` contribute to 0) - - - **Hint:** Use a two-pointer technique to count contributions of each vowel. - - **Link:** [Vowels of All Substrings - LeetCode](https://leetcode.com/problems/vowels-of-all-substrings?envType=problem-list-v2&envId=combinatorics&difficulty=MEDIUM) - -5. **The Number of Beautiful Subsets** - **Description:** Determine the number of beautiful subsets of a given array based on specific conditions that define a beautiful subset. - - - **Example:** - Input: `nums = [1, 2, 3], condition = even sum` - Output: `4` (The beautiful subsets could be `[]`, `[2]`, `[1, 3]`, and `[1, 2, 3]`) - - - **Hint:** Apply a combinatorial approach to generate subsets and filter based on the condition. - - **Link:** [The Number of Beautiful Subsets - LeetCode](https://leetcode.com/problems/the-number-of-beautiful-subsets?envType=problem-list-v2&envId=combinatorics&difficulty=MEDIUM) - ---- - -### Hard Problems: - -1. **Poor Pigs** - **Description:** You have a certain number of pigs and buckets. Each bucket may contain either water or poison, and you need to find out which buckets are poisoned using the least number of pigs within a given time limit. - - - **Example:** - Input: `pigs = 1, buckets = 1000, minutes = 15, minutesToDie = 15` - Output: `1` (One pig is enough to find the poisoned bucket) - - - **Hint:** Use a binary approach to represent the pigs' tests. - - **Link:** [Poor Pigs - LeetCode](https://leetcode.com/problems/poor-pigs?envType=problem-list-v2&envId=combinatorics&difficulty=HARD) - -2. **Kth Smallest Instructions** - **Description:** Given a number of `k`, your task is to find the `k-th` smallest instruction in a certain set of instructions. - - - **Example:** - Input: `n = 3, k = 5` - Output: `5` (Find the 5th smallest instruction) - - - **Hint:** Use combinatorial techniques to generate the set of instructions. - - **Link:** [Kth Smallest Instructions - LeetCode](https://leetcode.com/problems/kth-smallest-instructions?envType=problem-list-v2&envId=combinatorics&difficulty=HARD) - -3. **Number of Music Playlists** - **Description:** Calculate the number of playlists of a given length that can be created under specific conditions, such as the maximum number of unique songs allowed in the playlist. - - - **Example:** - Input: `n = 3, l = 3, k = 1` - Output: `6` (Six different playlists can be created) - - - **Hint:** Use dynamic programming to keep track of playlists. - - **Link:** [Number of Music Playlists - LeetCode](https://leetcode.com/problems/number-of-music-playlists?envType=problem-list-v2&envId=combinatorics&difficulty=HARD) - -4. **Number of Ways to Reorder Array to Get Same BST** - **Description:** Given an array, find the number of ways to reorder it to obtain the same binary search tree (BST). - - - **Example:** - Input: `arr = [2, 1, 3]` - Output: `1` (Only one way to order the array for the same BST structure) - - - **Hint:** Use combinatorial counting based on the properties of BST. - - **Link:** [Number of Ways to Reorder Array to Get Same BST - LeetCode](https://leetcode.com/problems/number-of-ways-to-reorder-array-to-get-same-bst?envType=problem-list-v2&envId=combinatorics&difficulty=HARD) - -5. **Count the Number of Ideal Arrays** - **Description:** Count the number of ideal arrays based on certain properties defined in the problem. - - - **Example:** - Input: `n = 5, maxValue = 2` - Output: `7` (Count ideal arrays of length 5 with values not exceeding 2) - - - **Hint:** Use combinatorial counting and generating functions. - - **Link:** [Count the Number of Ideal Arrays - LeetCode](https://leetcode.com/problems/count-the-number-of-ideal-arrays?envType=problem-list-v2&envId=combinatorics&difficulty=HARD) - ---- - -## Conclusion - -These problems are designed to strengthen your understanding of combinatorial mathematics. Make sure to attempt each problem and utilize the hints provided to assist your learning. Solutions may be found online for additional support. diff --git a/docs/combinatorics/_category_.json b/docs/combinatorics/_category_.json deleted file mode 100644 index 7ede1a913..000000000 --- a/docs/combinatorics/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Combinatorics", - "position": 7, - "link": { - "type": "generated-index", - "description": "Combinatorics is a branch of mathematics dealing with combinations, arrangements, and counting of objects. In the context of Data Structures and Algorithms (DSA), combinatorial techniques are used to solve problems related to counting, arrangement, and selection of data. These techniques are crucial in algorithm design and analysis, particularly in fields like graph theory, probability, and optimization." - } -} diff --git a/docs/combinatorics/combinatorics-examples.md b/docs/combinatorics/combinatorics-examples.md deleted file mode 100644 index 8a0763d6d..000000000 --- a/docs/combinatorics/combinatorics-examples.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -id: combinatorics-example -title: combinatorics in data structure -sidebar_label: Combinatorics Examples -sidebar_position: 2 -description: Combinatorics is a branch of mathematics dealing with combinations, arrangements, and counting of objects. -tags: [Competitive Programming,math,counting] - ---- - -# Combinatorics in C++ with Examples - -## Introduction - -In this section, we will see how to implement basic combinatorics concepts like permutations, combinations, and some common problems in C++. - -## 1. **Permutations** - -To generate all possible permutations of a given set of elements, C++ provides the `std::next_permutation` function. Below is an example using this function. - -### Example: Generating All Permutations of a String - -```cpp -#include -#include -#include - -int main() { - std::string s = "ABC"; - std::sort(s.begin(), s.end()); - - std::cout << "All permutations of the string \"ABC\":\n"; - do { - std::cout << s << "\n"; - } while (std::next_permutation(s.begin(), s.end())); - - return 0; -} -``` -``` -ABC -ACB -BAC -BCA -CAB -CBA -``` - -## 2. Combinations -```cpp -#include -#include - -void printCombination(const std::vector& arr, std::vector& comb, int start, int r) { - if (comb.size() == r) { - for (int i : comb) { - std::cout << i << " "; - } - std::cout << std::endl; - return; - } - - for (int i = start; i < arr.size(); ++i) { - comb.push_back(arr[i]); - printCombination(arr, comb, i + 1, r); - comb.pop_back(); - } -} - -int main() { - std::vector arr = {1, 2, 3, 4}; - std::vector comb; - int r = 2; - - std::cout << "Combinations of size 2 from the set {1, 2, 3, 4}:\n"; - printCombination(arr, comb, 0, r); - - return 0; -} -``` -``` -1 2 -1 3 -1 4 -2 3 -2 4 -3 4 -``` -## 3. Binomial Coefficient - -```cpp -#include -#include - -int binomialCoeff(int n, int r) { - std::vector> C(n + 1, std::vector(r + 1, 0)); - - // Calculate binomial coefficient using DP - for (int i = 0; i <= n; ++i) { - for (int j = 0; j <= std::min(i, r); ++j) { - // Base cases - if (j == 0 || j == i) { - C[i][j] = 1; - } else { - C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; - } - } - } - - return C[n][r]; -} - -int main() { - int n = 5, r = 2; - std::cout << "C(5, 2) = " << binomialCoeff(n, r) << std::endl; - - return 0; -} -``` - -``` -C(5, 2) = 10 -``` diff --git a/docs/combinatorics/combinatorics-theory.md b/docs/combinatorics/combinatorics-theory.md deleted file mode 100644 index 67c7633ad..000000000 --- a/docs/combinatorics/combinatorics-theory.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -id: combinatorics-theory -title: combinatorics in data structure -sidebar_label: Combinatorics -sidebar_position: 1 -description: Combinatorics is a branch of mathematics dealing with combinations, arrangements, and counting of objects. -tags: [Competitive Programming,math,counting] - ---- - -# Combinatorics in Data Structures and Algorithms - -## Introduction to Combinatorics - -Combinatorics is a branch of mathematics dealing with combinations, arrangements, and counting of objects. In the context of Data Structures and Algorithms (DSA), combinatorial techniques are used to solve problems related to counting, arrangement, and selection of data. These techniques are crucial in algorithm design and analysis, particularly in fields like graph theory, probability, and optimization. - -## Fundamental Concepts - -### 1. **Permutations** - -Permutations refer to the different arrangements of a set of elements. The number of permutations of $n$ distinct objects is given by: - -$$ -P(n) = n! -$$ - -where $$n!$$ (n factorial) is the product of all positive integers up to $n$. - -**Example:** -- The permutations of the set $(A, B, C)$ are: - - ABC - - ACB - - BAC - - BCA - - CAB - - CBA - -### 2. **Combinations** - -Combinations refer to the selection of items from a larger set where the order does not matter. The number of ways to choose $r$ elements from $n$ elements is given by the binomial coefficient: - -$$ -C(n, r) = \frac{n!}{r!(n-r)!} -$$ - -**Example:** -- The combinations of choosing 2 elements from the set $(A, B, C)$ are: - - AB - - AC - - BC - -### 3. **Binomial Theorem** - -The Binomial Theorem provides a formula for expanding expressions of the form $(x + y)^n$ - -$$ -(x + y)^n = \sum_{k=0}^{n} C(n, k) x^{n-k} y^k -$$ - -This theorem is useful in combinatorial problems, especially in counting paths or arrangements. - -## Applications in DSA - -Combinatorics has several applications in DSA, including: - -### 1. **Counting Problems** - -Counting the number of ways to arrange or select elements is fundamental in various algorithms, especially in: - -- **Graph Theory**: Counting paths, cycles, and spanning trees. -- **Dynamic Programming**: Problems like the "coin change problem" often require combinatorial counting. - -### 2. **Probability and Randomization** - -Combinatorial techniques are essential in analyzing the probability of different outcomes in randomized algorithms. For example: - -- **Monte Carlo Methods**: These rely on combinatorial counting to estimate probabilities and optimize performance. - -### 3. **Backtracking Algorithms** - -Combinatorial counting is crucial in backtracking algorithms, especially in problems like: - -- **N-Queens Problem**: Counting valid arrangements of queens on a chessboard. -- **Subset Sum Problem**: Finding combinations of numbers that sum to a given target. - -### 4. **Dynamic Programming** - -Dynamic programming often employs combinatorial principles to solve optimization problems by breaking them down into simpler subproblems. Examples include: - -- **Fibonacci Sequence**: Counting the number of ways to reach the $n^{th}$ step. -- **Longest Common Subsequence (LCS)**: Finding the longest sequence that can be derived from two sequences through deletion. - -## Key Combinatorial Problems - -### 1. **The Traveling Salesman Problem (TSP)** - -A classic combinatorial optimization problem where the objective is to find the shortest possible route visiting a set of cities and returning to the origin city. - -### 2. **Subset Generation** - -Generating all possible subsets of a given set, which is often implemented using backtracking or iterative methods. - -### 3. **Graph Combinatorics** - -Studying properties of graphs through combinatorial methods, including: - -- **Graph Coloring**: Assigning colors to vertices so that no two adjacent vertices share the same color. -- **Clique Problems**: Finding complete subgraphs within larger graphs. - -## Conclusion - -Combinatorics plays a vital role in Data Structures and Algorithms. Understanding its principles enables algorithm designers to tackle complex counting problems, optimize solutions, and analyze algorithm efficiency. Mastering combinatorial techniques is essential for anyone looking to excel in competitive programming or algorithm development. diff --git a/docs/complexity/_category_.json b/docs/complexity/_category_.json deleted file mode 100644 index 0e8d2127b..000000000 --- a/docs/complexity/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Complexity", - "position": 7, - "link": { - "type": "generated-index", - "description": "Learn about the complexity of algorithms and how to analyze them." - } - } \ No newline at end of file diff --git a/docs/complexity/how-to-calculate-complexity.md b/docs/complexity/how-to-calculate-complexity.md deleted file mode 100644 index 50138e96f..000000000 --- a/docs/complexity/how-to-calculate-complexity.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -id: how-to-calculate-complexity -title: How to Calculate Time and Space Complexity -sidebar_label: How to Calculate Time and Space Complexity -sidebar_position: 4 -description: "Calculating time and space complexity is an essential skill for analyzing the efficiency of algorithms. By understanding how to determine the time and space complexity of an algorithm, you can evaluate its performance and make informed decisions when designing and optimizing algorithms." -tags: [time-complexity, space-complexity, algorithm-analysis, big-o-notation, how-to-calculate-complexity] ---- - -Calculating time and space complexity is an essential skill for analyzing the efficiency of algorithms. By understanding how to determine the time and space complexity of an algorithm, you can evaluate its performance and make informed decisions when designing and optimizing algorithms. - - - -## What is Time Complexity? - -Time complexity refers to the amount of time an algorithm takes to run as a function of the length of the input. It helps us understand how an algorithm scales with input size and provides insights into its efficiency. - -Time complexity is typically denoted using Big O notation, which describes the upper bound of an algorithm's running time in terms of the input size. For example, an algorithm with a time complexity of $O(n)$ indicates that its running time grows linearly with the input size. - -Analyzing time complexity involves counting the number of operations an algorithm performs as a function of the input size. This analysis helps us compare different algorithms and determine which one is more efficient for a given problem. - -## What is Space Complexity? - -Space complexity refers to the amount of memory an algorithm uses as a function of the length of the input. It helps us understand how much memory an algorithm requires to perform its operations. - -Similar to time complexity, space complexity is also denoted using Big O notation, which describes the upper bound of an algorithm's memory usage in terms of the input size. For example, an algorithm with a space complexity of $O(n)$ indicates that it uses linear memory with respect to the input size. - -Analyzing space complexity involves counting the memory used by an algorithm, including variables, data structures, and other resources. Understanding the space complexity of an algorithm is crucial, especially when dealing with limited memory resources. - - - -## How to Calculate Time Complexity - -Calculating the time complexity of an algorithm involves analyzing the number of operations it performs as a function of the input size. Here are some common steps to calculate the time complexity of an algorithm: - -1. Identify the input size: Determine the parameter that defines the size of the input to the algorithm. This could be the length of an array, the number of nodes in a graph, or any other relevant metric. -2. Count the number of operations: Analyze the algorithm to determine the number of basic operations it performs for a given input size. This could involve counting loops, recursive calls, comparisons, assignments, and other fundamental operations. -3. Express the time complexity: Use Big O notation to express the time complexity of the algorithm in terms of the input size. This provides an upper bound on the running time of the algorithm and helps compare its efficiency with other algorithms. -4. Analyze the worst-case scenario: Consider the worst-case scenario when calculating time complexity, as it provides a conservative estimate of the algorithm's performance. This ensures that the algorithm performs efficiently even in challenging situations. -5. Compare with other algorithms: Once you have calculated the time complexity of an algorithm, compare it with other algorithms that solve the same problem. This comparison helps you identify the most efficient algorithm for a given problem. -6. Optimize if necessary: If the time complexity of an algorithm is higher than desired, consider optimizing the algorithm by redesigning its logic, reducing redundant operations, or using more efficient data structures. -7. Test and validate: Validate the time complexity analysis of the algorithm by testing it with different input sizes and scenarios. This helps ensure that the algorithm performs as expected and meets the performance requirements. -8. Iterate and refine: Iterate on the time complexity analysis of the algorithm based on feedback, performance measurements, and further optimizations. Refine the analysis to accurately reflect the algorithm's efficiency and scalability. - -By following these steps, you can calculate the time complexity of an algorithm and gain insights into its efficiency and performance characteristics. - - - -## How to Calculate Space Complexity - -Calculating the space complexity of an algorithm involves analyzing the amount of memory it uses as a function of the input size. Here are some common steps to calculate the space complexity of an algorithm: - -1. Identify the memory usage: Determine the variables, data structures, and resources used by the algorithm that contribute to its memory usage. This could include arrays, lists, maps, counters, and other memory-intensive components. -2. Analyze the memory requirements: Count the memory used by the algorithm for a given input size, including the space required for variables, data structures, and other resources. Consider both static memory usage (e.g., fixed-size arrays) and dynamic memory usage (e.g., dynamically allocated memory). -3. Express the space complexity: Use Big O notation to express the space complexity of the algorithm in terms of the input size. This provides an upper bound on the memory usage of the algorithm and helps compare its efficiency with other algorithms. -4. Analyze the worst-case scenario: Consider the worst-case scenario when calculating space complexity, as it provides a conservative estimate of the algorithm's memory requirements. This ensures that the algorithm uses memory efficiently even in challenging situations. -5. Compare with other algorithms: Once you have calculated the space complexity of an algorithm, compare it with other algorithms that solve the same problem. This comparison helps you identify the most memory-efficient algorithm for a given problem. -6. Optimize if necessary: If the space complexity of an algorithm is higher than desired, consider optimizing the algorithm by reducing memory usage, using more efficient data structures, or implementing memory-saving techniques. -7. Test and validate: Validate the space complexity analysis of the algorithm by testing it with different input sizes and scenarios. This helps ensure that the algorithm uses memory as expected and meets the memory requirements. -8. Iterate and refine: Iterate on the space complexity analysis of the algorithm based on feedback, memory measurements, and further optimizations. Refine the analysis to accurately reflect the algorithm's memory usage and efficiency. -9. Consider trade-offs: When optimizing space complexity, consider trade-offs with time complexity and other performance metrics. Balancing these trade-offs is essential to design algorithms that meet the memory requirements without sacrificing performance. -10. Document and communicate: Document the space complexity analysis of the algorithm, including the memory usage, Big O notation, worst-case scenario, optimizations, and trade-offs. Communicate this information to stakeholders, team members, and collaborators to ensure a shared understanding of the algorithm's memory requirements. - -By following these steps, you can calculate the space complexity of an algorithm and evaluate its memory usage, efficiency, and performance characteristics. - - - -## Conclusion - -Calculating time and space complexity is a fundamental skill for analyzing the efficiency of algorithms. By understanding how to determine the time and space complexity of an algorithm, you can evaluate its performance, optimize its efficiency, and make informed decisions when designing algorithms. \ No newline at end of file diff --git a/docs/complexity/image-1.png b/docs/complexity/image-1.png deleted file mode 100644 index cd127aab3647d3b8a854a7fb819e59273140fa37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12924 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 PPyteqRhFrgG79`3igf%< diff --git a/docs/complexity/image.png b/docs/complexity/image.png deleted file mode 100644 index 8a263334fd992286c3d518de34ab71cf48d0de6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6623 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 diff --git a/docs/complexity/space-complexity.md b/docs/complexity/space-complexity.md deleted file mode 100644 index 34bb78192..000000000 --- a/docs/complexity/space-complexity.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -id: space-complexity -title: Space Complexity -sidebar_label: Space Complexity -sidebar_position: 2 -description: "Space complexity is a measure of the amount of working storage an algorithm needs. It is a measure of the amount of memory space an algorithm needs to solve a problem as a function of the size of the input to the problem. It is the amount of memory space required by the algorithm to execute in its life cycle." -tags: [Space Complexity, Big O Notation, Memory, Algorithm, Complexity Analysis, Data Structure, DSA, JavaScript, Java, Python, C, C++, Space Complexity Example, Space Complexity Calculation, Space Complexity Analysis, Space Complexity Explanation, Space Complexity Conclusion, Space Complexity Importance, Space Complexity Formula, Space Complexity Constant Space, Space Complexity Auxiliary Space, Space Complexity Example, Space Complexity Program, Space Complexity Code] ---- - -Space complexity is a measure of the amount of working storage an algorithm needs. It is a measure of the amount of memory space an algorithm needs to solve a problem as a function of the size of the input to the problem. It is the amount of memory space required by the algorithm to execute in its life cycle. - - - -## Why is Space Complexity important? - -Space complexity is important because the memory that is allocated to the program is limited. If the program uses more memory than the available memory, the program will crash. Therefore, it is important to know the space complexity of the algorithm. - -## How to calculate Space Complexity? - -Space complexity is calculated by counting the amount of memory space used by the algorithm. It is calculated by counting the amount of memory space used by the algorithm as a function of the size of the input to the problem. - -## Example - -```js title="Space Complexity" -function sumOfN(n) { - let sum = 0; - for (let i = 1; i <= n; i++) { - sum += i; - } - return sum; -} -``` - -In the above example, the space complexity of the algorithm is O(1) because the algorithm uses a constant amount of memory space. - - - -## Example of Space Complexity - -1. Write a program to fine maximum and minimum element in an array. - - - - - ```js {6,9,12} - function findMaxMin(arr) { - let max = arr[0]; - let min = arr[0]; - for (let i = 1; i < arr.length; i++) { - if (arr[i] > max) { - max = arr[i]; - } - if (arr[i] < min) { - min = arr[i]; - } - } - return { max, min }; - } - - const arr = [2, 5, 1, 20, 10]; - console.log(findMaxMin(arr)); // { max: 20, min: 1 } - ``` - - - - - ```java - public class Main { - public static void main(String[] args) { - int[] arr = {2, 5, 1, 20, 10}; - System.out.println(findMaxMin(arr)); // { max: 20, min: 1 } - } - - public static Map findMaxMin(int[] arr) { - int max = arr[0]; - int min = arr[0]; - for (int i = 1; i < arr.length; i++) { - if (arr[i] > max) { - max = arr[i]; - } - if (arr[i] < min) { - min = arr[i]; - } - } - Map result = new HashMap<>(); - result.put("max", max); - result.put("min", min); - return result; - } - } - ``` - - - - - ```python - def find_max_min(arr): - max = arr[0] - min = arr[0] - for i in range(1, len(arr)): - if arr[i] > max: - max = arr[i] - if arr[i] < min: - min = arr[i] - return {"max": max, "min": min} - - arr = [2, 5, 1, 20, 10] - print(find_max_min(arr)) # { max: 20, min: 1 } - ``` - - - - - ```c - #include - - struct MaxMin { - int max; - int min; - }; - - struct MaxMin findMaxMin(int arr[], int n) { - struct MaxMin result; - result.max = arr[0]; - result.min = arr[0]; - for (int i = 1; i < n; i++) { - if (arr[i] > result.max) { - result.max = arr[i]; - } - if (arr[i] < result.min) { - result.min = arr[i]; - } - } - return result; - } - - int main() { - int arr[] = {2, 5, 1, 20, 10}; - struct MaxMin result = findMaxMin(arr, 5); - printf("{ max: %d, min: %d }\n", result.max, result.min); // { max: 20, min: 1 } - return 0; - } - ``` - - - - - ```cpp - #include - #include - #include - - std::map findMaxMin(std::vector arr) { - int max = arr[0]; - int min = arr[0]; - for (int i = 1; i < arr.size(); i++) { - if (arr[i] > max) { - max = arr[i]; - } - if (arr[i] < min) { - min = arr[i]; - } - } - std::map result; - result["max"] = max; - result["min"] = min; - return result; - } - - int main() { - std::vector arr = {2, 5, 1, 20, 10}; - std::map result = findMaxMin(arr); - std::cout << "{ max: " << result["max"] << ", min: " << result["min"] << " }\n"; // { max: 20, min: 1 } - return 0; - } - ``` - - - - -In the above example, the space complexity of the algorithm is O(1) because the algorithm uses a constant amount of memory space. - -**Explanation:** In the above example, we are finding the maximum and minimum element in an array. We are using two variables `max` and `min` to store the maximum and minimum element in the array. We are using a constant amount of memory space to store the maximum and minimum element in the array. Therefore, the space complexity of the algorithm is O(1). - -:::info Complexity Analysis -**Farmula to calculate Space Complexity** - -Space Complexity = Constant Space + Auxiliary Space - -**Constant Space:** The amount of space used by the algorithm that is not dependent on the size of the input to the problem. It is a constant amount of memory space used by the algorithm. - -**Auxiliary Space:** The amount of space used by the algorithm that is dependent on the size of the input to the problem. It is a variable amount of memory space used by the algorithm. - -```plaintext title="Space Complexity" -Space Complexity = O(1) + O(n) = O(n) -``` - -**For Example:** - -```js title="Space Complexity" -function sumOfN(n) { - let sum = 0; // Constant Space (O(1)) - for (let i = 1; i <= n; i++) { - sum += i; // Auxiliary Space (O(n)) - } - return sum; -} -``` - -In the above example, the space complexity of the algorithm is `O(1) + O(n) = O(n)`. - -::: - - - -## Conclusion - -Space complexity is a measure of the amount of working storage an algorithm needs. It is a measure of the amount of memory space an algorithm needs to solve a problem as a function of the size of the input to the problem. It is the amount of memory space required by the algorithm to execute in its life cycle. \ No newline at end of file diff --git a/docs/complexity/time-complexity.md b/docs/complexity/time-complexity.md deleted file mode 100644 index dde3308e0..000000000 --- a/docs/complexity/time-complexity.md +++ /dev/null @@ -1,314 +0,0 @@ ---- -id: time-complexity -title: Time Complexity -sidebar_label: Time Complexity -sidebar_position: 1 -description: "Time Complexity is a measure of the amount of time an algorithm takes to solve a problem as a function of the size of the input to the problem. It is commonly estimated by counting the number of elementary operations performed by the algorithm, where an elementary operation takes a fixed amount of time to perform." -tags: [time complexity, big o notation, algorithm, complexity analysis, data structure, dsa, javascript, java, python, c, c++, time complexity example, time complexity calculation, time complexity analysis, time complexity explanation, time complexity conclusion, time complexity importance, time complexity formula, time complexity constant time, time complexity linear time, time complexity logarithmic time, time complexity quadratic time, time complexity exponential time, time complexity factorial time, time complexity polynomial time, time complexity sublinear time, time complexity linearithmic time, time complexity quasilinear time, time complexity superpolynomial time, time complexity subexponential time, time complexity log factorial time, time complexity exponential factorial time, time complexity exponential exponential time, time complexity exponential factorial exponential time, time complexity exponential exponential factorial time] ---- - -Time Complexity is a measure of the amount of time an algorithm takes to solve a problem as a function of the size of the input to the problem. It is commonly estimated by counting the number of elementary operations performed by the algorithm, where an elementary operation takes a fixed amount of time to perform. - - - -## Why is Time Complexity Important? - -Time Complexity is important because it helps us understand the efficiency of an algorithm. It allows us to compare different algorithms and choose the most efficient one for a given problem. It also helps us analyze the performance of an algorithm as the size of the input grows. - -## Common Notations for Time Complexity - -The most common notations used to represent the time complexity of an algorithm are: - -- **Big O Notation (O):** It represents the upper bound of the time complexity of an algorithm. It gives the worst-case time complexity of an algorithm. -- **Omega Notation (Ω):** It represents the lower bound of the time complexity of an algorithm. It gives the best-case time complexity of an algorithm. -- **Theta Notation (Θ):** It represents the average-case time complexity of an algorithm. It gives the tight bound of the time complexity of an algorithm. - - - -### Big O Notation (O) - -Big O Notation is used to represent the upper bound of the time complexity of an algorithm. It gives the worst-case time complexity of an algorithm. It is commonly used to analyze the performance of an algorithm as the size of the input grows. - -![Big O Notation](image.png) - -The Big O Notation is written as `O(f(n))`, where `f(n)` is a function that represents the time complexity of the algorithm. It is read as "O of f of n" or "order of f of n". - -### Omega Notation (Ω) - -Omega Notation is used to represent the lower bound of the time complexity of an algorithm. It gives the best-case time complexity of an algorithm. It is commonly used to analyze the performance of an algorithm as the size of the input grows. - -![Omega Notation](image-1.png) - -The Omega Notation is written as `Ω(f(n))`, where `f(n)` is a function that represents the time complexity of the algorithm. It is read as "Omega of f of n". - -### Theta Notation (Θ) - -Theta Notation is used to represent the average-case time complexity of an algorithm. It gives the tight bound of the time complexity of an algorithm. It is commonly used to analyze the performance of an algorithm as the size of the input grows. - -The Theta Notation is written as `Θ(f(n))`, where `f(n)` is a function that represents the time complexity of the algorithm. It is read as "Theta of f of n". - - - -## Examples of Time Complexity - -Here are some examples of time complexity for different algorithms: - -- **Constant Time (O(1)):** An algorithm that takes the same amount of time to run, regardless of the size of the input. -- **Linear Time (O(n)):** An algorithm that takes time proportional to the size of the input. -- **Logarithmic Time (O(log n)):** An algorithm that takes time proportional to the logarithm of the size of the input. -- **Quadratic Time (O(n^2)):** An algorithm that takes time proportional to the square of the size of the input. -- **Exponential Time (O(2^n)):** An algorithm that takes time proportional to an exponential function of the size of the input. -- **Factorial Time (O(n!)):** An algorithm that takes time proportional to the factorial of the size of the input. -- **Polynomial Time (O(n^k)):** An algorithm that takes time proportional to a polynomial function of the size of the input. -- **Sublinear Time (O(log log n)):** An algorithm that takes time proportional to the logarithm of the logarithm of the size of the input. -- **Linearithmic Time (O(n log n)):** An algorithm that takes time proportional to the product of the size of the input and the logarithm of the size of the input. -- **Quasilinear Time (O(n log^k n)):** An algorithm that takes time proportional to the product of the size of the input and the logarithm of the size of the input raised to the power of k. -- **Superpolynomial Time (O(n^k)):** An algorithm that takes time proportional to a function that grows faster than any polynomial function of the size of the input. -- **Subexponential Time (O(2^poly(n))):** An algorithm that takes time proportional to a function that grows slower than any exponential function of the size of the input. -- **Log Factorial Time (O(log n!)):** An algorithm that takes time proportional to the logarithm of the factorial of the size of the input. -- **Exponential Factorial Time (O(2^n!)):** An algorithm that takes time proportional to an exponential function of the factorial of the size of the input. -- **Exponential Exponential Time (O(2^2^n)):** An algorithm that takes time proportional to an exponential function of an exponential function of the size of the input. -- **Exponential Factorial Exponential Time (O(2^n!^2^n)):** An algorithm that takes time proportional to an exponential function of the factorial of an exponential function of the size of the input. -- **Exponential Exponential Factorial Time (O(2^2^n!)):** An algorithm that takes time proportional to an exponential function of an exponential function of the factorial of the size of the input. - - - -## Analyzing Time Complexity - -To analyze the time complexity of an algorithm, we can follow these steps: - -1. **Count the Operations:** Count the number of elementary operations performed by the algorithm. -2. **Identify the Dominant Term:** Identify the term that grows the fastest as the size of the input grows. -3. **Express the Time Complexity:** Express the time complexity using the Big O notation. -4. **Compare with Other Algorithms:** Compare the time complexity with other algorithms to choose the most efficient one. -5. **Analyze the Best, Worst, and Average Cases:** Analyze the best-case, worst-case, and average-case time complexity of the algorithm. -6. **Optimize the Algorithm:** Optimize the algorithm to improve its time complexity if possible. -7. **Test the Algorithm:** Test the algorithm with different input sizes to verify its time complexity. -8. **Benchmark the Algorithm:** Benchmark the algorithm to measure its actual performance. -9. **Profile the Algorithm:** Profile the algorithm to identify performance bottlenecks and optimize them. -10. **Analyze the Real-World Performance:** Analyze the real-world performance of the algorithm in different environments and scenarios. -11. **Contribute:** If you have any tips to share, feel free to contribute to this section. - -## For Example - -1. Calculating sum of array elements using loop. - - - - - ```js - function sum(arr) { - let result = 0; - for (let i = 0; i < arr.length; i++) { - result += arr[i]; - } - return result; - } - const arr = [1, 2, 3, 4, 5]; - console.log(sum(arr)); // Output: 15 - ``` - - - ```py - def sum(arr): - result = 0 - for i in arr: - result += i - return result - arr = [1, 2, 3, 4, 5] - print(sum(arr)) # Output: 15 - ``` - - - ```java - class Sum { - public static void main(String args[]) { - int arr[] = {1, 2, 3, 4, 5}; - int result = 0; - for (int i = 0; i < arr.length; i++) { - result += arr[i]; - } - System.out.println(result); // Output: 15 - } - } - ``` - - - ```c - #include - int main() { - int arr[] = {1, 2, 3, 4, 5}; - int result = 0; - for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) { - result += arr[i]; - } - printf("%d\n", result); // Output: 15 - return 0; - } - ``` - - - ```go - package main - import "fmt" - func main() { - arr := []int{1, 2, 3, 4, 5} - result := 0 - for i := 0; i < len(arr); i++ { - result += arr[i] - } - fmt.Println(result) // Output: 15 - } - ``` - - - ```cpp - #include - using namespace std; - int main() { - int arr[] = {1, 2, 3, 4, 5}; - int result = 0; - for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) { - result += arr[i]; - } - cout << result << endl; // Output: 15 - return 0; - } - ``` - - - ```swift - import Foundation - let arr = [1, 2, 3, 4, 5] - var result = 0 - for i in arr { - result += i - } - print(result) // Output: 15 - ``` - - - ```kotlin - fun main() { - val arr = intArrayOf(1, 2, 3, 4, 5) - var result = 0 - for (i in arr) { - result += i - } - println(result) // Output: 15 - } - ``` - - - ```rs - fn main() { - let arr = [1, 2, 3, 4, 5]; - let mut result = 0; - for i in arr.iter() { - result += i; - } - println!("{}", result); // Output: 15 - } - ``` - - - ```php - - ``` - - - ```cs - using System; - class Sum { - static void Main() { - int[] arr = {1, 2, 3, 4, 5}; - int result = 0; - foreach (int i in arr) { - result += i; - } - Console.WriteLine(result); // Output: 15 - } - } - ``` - - - ```ts - let arr: number[] = [1, 2, 3, 4, 5]; - let result: number = 0; - for (let i of arr) { - result += i; - } - console.log(result); // Output: 15 - ``` - - - ```scala - object Sum { - def main(args: Array[String]): Unit = { - val arr = Array(1, 2, 3, 4, 5) - var result = 0 - for (i <- arr) { - result += i - } - println(result) // Output: 15 - } - } - ``` - - - ```haskell - main = do - let arr = [1, 2, 3, 4, 5] - let result = sum arr - print result -- Output: 15 - ``` - - - ```r - arr <- c(1, 2, 3, 4, 5) - result <- sum(arr) - print(result) # Output: 15 - ``` - - - ```perl - my @arr = (1, 2, 3, 4, 5); - my $result = 0; - foreach my $i (@arr) { - $result += $i; - } - print $result; # Output: 15 - ``` - - - ```lua - arr = {1, 2, 3, 4, 5} - result = 0 - for i = 1, #arr do - result = result + arr[i] - end - print(result) -- Output: 15 - ``` - - - -Each of the above code snippets has a time complexity of `O(n)` because the number of iterations in the loop is directly proportional to the size of the input array. - -**Exlpanation:** The time complexity of the given code is `O(n)` because the loop iterates through the array elements one by one, and the number of iterations is directly proportional to the size of the input array. Therefore, the time complexity is linear, i.e., `O(n)`. - - - -:::info -**Note:** The time complexity of an algorithm can be different for different programming languages, but the underlying logic and analysis remain the same. -::: - -## Conclusion - -Time Complexity is an important concept in computer science and programming. It helps us understand the efficiency of algorithms and make informed decisions about choosing the most efficient algorithm for a given problem. By analyzing the time complexity of algorithms, we can optimize them for better performance and improve the overall efficiency of our programs. \ No newline at end of file diff --git a/docs/complexity/time-space-complexity.md b/docs/complexity/time-space-complexity.md deleted file mode 100644 index e53f23efc..000000000 --- a/docs/complexity/time-space-complexity.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: time-vs-space-complexity -title: Time vs Space Complexity -sidebar_label: Time vs Space Complexity -sidebar_position: 3 -description: "Time and space complexity are two important concepts in computer science. Time complexity is the amount of time an algorithm takes to run, while space complexity is the amount of memory an algorithm uses. Both are important to consider when analyzing the efficiency of an algorithm." -tags: [time-complexity, space-complexity, time vs space complexity] ---- - -Time and space complexity are two important concepts in computer science. Time complexity is the amount of time an algorithm takes to run, while space complexity is the amount of memory an algorithm uses. Both are important to consider when analyzing the efficiency of an algorithm. - - - -## Time vs Space Complexity - -When analyzing the efficiency of an algorithm, we often consider two key factors: time complexity and space complexity. These metrics help us understand how an algorithm performs in terms of time and memory usage, respectively. - -| **No.** | **Parameter** | **Time Complexity** | **Space Complexity** | -|---------|---------------|---------------------|----------------------| -| 1. | Definition | The amount of time an algorithm takes to run. | The amount of memory an algorithm uses. | -| 2. | Notation | Typically denoted using Big O notation. | Also denoted using Big O notation. | -| 3. | Importance | Helps us understand how an algorithm scales with input size. | Helps us understand how much memory an algorithm requires. | -| 4. | Trade-offs | Often involves trade-offs with space complexity. | May involve trade-offs with time complexity. | -| 5. | Analysis | Analyzed by counting the number of operations an algorithm performs. | Analyzed by counting the memory used by an algorithm. | -| 6. | Examples | Sorting algorithms, searching algorithms, etc. | Data structures like arrays, linked lists, etc. | - -### Time Complexity - -Time complexity refers to the amount of time an algorithm takes to run as a function of the length of the input. It helps us understand how an algorithm scales with input size and provides insights into its efficiency. - -Time complexity is typically denoted using Big O notation, which describes the upper bound of an algorithm's running time in terms of the input size. For example, an algorithm with a time complexity of $O(n)$ indicates that its running time grows linearly with the input size. - -Analyzing time complexity involves counting the number of operations an algorithm performs as a function of the input size. This analysis helps us compare different algorithms and determine which one is more efficient for a given problem. - - - -### Space Complexity - -Space complexity refers to the amount of memory an algorithm uses as a function of the input size. It helps us understand how much memory an algorithm requires to perform its operations. - -Similar to time complexity, space complexity is also denoted using Big O notation, which describes the upper bound of an algorithm's memory usage in terms of the input size. For example, an algorithm with a space complexity of $O(n)$ indicates that it uses linear memory with respect to the input size. - -Analyzing space complexity involves counting the memory used by an algorithm, including variables, data structures, and other resources. Understanding the space complexity of an algorithm is crucial, especially when dealing with limited memory resources. - -### Trade-offs - -When designing algorithms, we often encounter trade-offs between time complexity and space complexity. Improving the time complexity of an algorithm may lead to increased space usage, and vice versa. Balancing these trade-offs is essential to optimize the performance of an algorithm. - -For example, consider a sorting algorithm that uses additional memory to store intermediate results. While this may increase the space complexity of the algorithm, it can lead to improved time complexity by reducing the number of comparisons or swaps required. - -Understanding the trade-offs between time and space complexity is key to designing efficient algorithms that meet the performance requirements of a given problem. - - - -## Conclusion - -Time and space complexity are essential concepts in computer science that help us analyze the efficiency of algorithms. By considering both factors, we can gain insights into how an algorithm performs in terms of time and memory usage, enabling us to make informed decisions when designing and optimizing algorithms. \ No newline at end of file diff --git a/docs/content.md b/docs/content.md deleted file mode 100644 index ff90fee54..000000000 --- a/docs/content.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: table-of-contents -sidebar_position: 2 -title: Table Of Contents -sidebar_label: Contents -description: "Explore the world of Data Structures and Algorithms (DSA) with Algo's comprehensive learning resources. From fundamental concepts to advanced topics, Algo provides a structured pathway to help you master DSA and enhance your programming skills." -tags: [dsa, data structures, algorithms] ---- - -Let's delve into the world of Data Structures and Algorithms (DSA) with Algo's comprehensive learning resources. From fundamental concepts to advanced topics, Algo provides a structured pathway to help you master DSA and enhance your programming skills. Whether you're a beginner or an experienced coder, Algo is here to guide you through the intricate world of DSA. - - - - - - ```mermaid - sequenceDiagram - participant User - participant System - - User -> System: Request to Learn Data Structures - - System -> System: Introduction to Data Structures - Note over System: What are data structures?

    Importance of data structures in programming - - System -> System: Basics of Arrays - Note over System: Basics of arrays

    Operations on arrays (insertion, deletion, searching) - - System -> System: Linked Lists - Note over System: Singly linked lists

    Doubly linked lists

    Circular linked lists - - System -> System: Stacks - Note over System: Basics of stacks

    Implementation of stacks

    Applications of stacks - - System -> System: Queues - Note over System: Basics of queues

    Implementation of queues

    Priority queues - - System -> System: Trees - Note over System: Binary trees

    Binary search trees (BST)

    AVL trees (Balanced BST) - - System -> System: Graphs - Note over System: Basics of graphs

    Graph representation (adjacency matrix, adjacency list)

    Depth-First Search (DFS) and Breadth-First Search (BFS) - - User -> System: Explore Further - - ```` - -
    - - ```mermaid - sequenceDiagram - participant User - participant System - - User -> System: Request to Learn Algorithms - - System -> System: Introduction to Algorithms - Note over System: What are algorithms?

    Time and space complexity - - System -> System: Searching Algorithms - Note over System: Linear search

    Binary search

    Hashing and hash tables - - System -> System: Sorting Algorithms - Note over System: Bubble sort

    Selection sort

    Merge sort

    Quick sort - - System -> System: Recursion - Note over System: Understanding recursion

    Recursive algorithms - - System -> System: Dynamic Programming - Note over System: Basics of dynamic programming

    Memoization and tabulation - - System -> System: Greedy Algorithms - Note over System: Basics of greedy algorithms

    Applications of greedy algorithms - - System -> System: Divide and Conquer - Note over System: Principles of divide and conquer

    Examples of divide and conquer algorithms - - System -> System: Graph Algorithms - Note over System: Shortest path algorithms (Dijkstra's, Bellman-Ford)

    Minimum Spanning Tree (Prim's, Kruskal's)

    Depth-First Search (DFS) and Breadth-First Search (BFS) for graphs - - User -> System: Explore Further - - ```` -
    - - ```mermaid - sequenceDiagram - participant User - participant System - - User -> System: Request for Practice and Applications - - System -> System: Coding Challenges - Note over System: Solve coding problems on platforms

    like LeetCode, HackerRank, and CodeSignal - - System -> System: Project Work - Note over System: Implement data structures and algorithms in small projects - - System -> System: Real-world Applications - Note over System: Explore how DSA is applied in real-world scenarios - - System -> System: Interview Preparation - Note over System: Tips for technical interviews

    Practice common DSA interview questions - - User -> System: Explore Further - - ``` -
    -
    - - - -## What Sets Algo Apart? - -### Comprehensive Learning Pathways - -Algo provides carefully curated learning pathways designed to take you from a DSA novice to a proficient coder. Our structured approach ensures a smooth learning curve, starting with the basics and gradually progressing to advanced topics. - -### Interactive Coding Challenges - -Learning by doing is at the heart of Algo. Engage in hands-on coding challenges that reinforce your understanding of key concepts. Our interactive platform allows you to apply what you've learned in a practical and engaging manner. - -### Supportive Community - -Join a vibrant community of learners, mentors, and industry experts who are passionate about DSA. Collaborate, share knowledge, and grow together as you embark on your coding journey. - -### Personalized Learning Experience - -Algo's adaptive learning platform tailors the content to your skill level and learning pace. Whether you're a beginner or an experienced coder, Algo provides a personalized learning experience that meets your unique needs. - - - -## Get Started with Algo - -Ready to dive into the world of Data Structures and Algorithms? Start your learning journey with Algo today! Explore our learning pathways, tackle coding challenges, and connect with a community of like-minded individuals who share your passion for coding. \ No newline at end of file diff --git a/docs/dsa/_category_.json b/docs/dsa/_category_.json deleted file mode 100644 index 251295d39..000000000 --- a/docs/dsa/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Data Structures Algorithms", - "position": 5, - "link": { - "type": "generated-index", - "description": "Data Structures and Algorithms are the most important concepts in programming. Learn the most important RoadMap for Basic Concepts of Data Structures and Algorithms." - } - } \ No newline at end of file diff --git a/docs/dsa/imp-of-dsa.md b/docs/dsa/imp-of-dsa.md deleted file mode 100644 index 21c6ec433..000000000 --- a/docs/dsa/imp-of-dsa.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: importance-of-dsa -sidebar_position: 2 -title: Importance of Data Structures and Algorithms -sidebar_label: Importance of DSA -description: "Data Structures and Algorithms are the building blocks of computer science. They are essential for writing efficient code and solving complex problems." -tags: [dsa, data-structures, algorithms, importance of dsa] ---- - -Data Structures and Algorithms (DSA) are the building blocks of computer science. They are essential for writing efficient code and solving complex problems. DSA is a fundamental part of computer science and software engineering. It is used in various fields such as software development, machine learning, data science, and many more. - - - -## Importance of Data Structures and Algorithms - -Data Structures and Algorithms are important for the following reasons: - -1. **Efficient Code**: DSA helps in writing efficient code. By using the right data structures and algorithms, you can optimize the performance of your code and reduce the time and space complexity. -2. **Problem Solving**: DSA provides a systematic way to solve complex problems. It helps in breaking down the problem into smaller subproblems and finding the optimal solution. -3. **Optimization**: DSA helps in optimizing the code by reducing the time and space complexity. It helps in improving the performance of the code and making it more efficient. -4. **Scalability**: DSA helps in designing scalable solutions. By using the right data structures and algorithms, you can build systems that can handle large amounts of data and scale to meet the growing demands. -5. **Interviews**: DSA is an important topic in technical interviews. Most companies ask questions related to data structures and algorithms to assess the problem-solving skills of the candidates. -6. **Competitive Programming**: DSA is essential for competitive programming. It helps in solving challenging problems in a limited amount of time. Competitive programming contests like ACM ICPC, Codeforces, and TopCoder focus on DSA. -7. **Software Development**: DSA is used in software development to design efficient algorithms and data structures. It helps in building robust and scalable software systems. -8. **Machine Learning**: DSA is used in machine learning algorithms to process and analyze large datasets. It helps in building predictive models and making data-driven decisions. -9. **Data Science**: DSA is used in data science to process, analyze, and visualize data. It helps in extracting insights from the data and making informed decisions. -10. **Research**: DSA is used in research to solve complex problems and develop new algorithms. It helps in advancing the field of computer science and technology. -11. **Problem-solving Skills**: DSA helps in developing problem-solving skills. It teaches you how to approach a problem, break it down into smaller subproblems, and find the optimal solution. -12. **Logical Thinking**: DSA helps in developing logical thinking and analytical skills. It teaches you how to analyze a problem, identify patterns, and come up with a solution. -13. **Coding Skills**: DSA helps in improving your coding skills. It teaches you how to write clean, efficient, and optimized code using the right data structures and algorithms. -14. **Algorithm Design**: DSA helps in designing efficient algorithms. It teaches you how to analyze the time and space complexity of an algorithm and optimize it for better performance. -15. **Data Handling**: DSA helps in handling and processing large amounts of data. It teaches you how to store, retrieve, and manipulate data efficiently using data structures and algorithms. -16. **Problem Classification**: DSA helps in classifying problems based on their complexity and finding the optimal solution. It teaches you how to choose the right data structures and algorithms for a given problem. -17. **Real-world Applications**: DSA is used in various real-world applications such as search engines, social networks, e-commerce websites, and many more. It helps in building efficient and scalable systems. -18. **Educational Value**: DSA has educational value. It is an essential topic in computer science and software engineering courses. It helps in understanding the core concepts of programming and problem-solving. -19. **Career Growth**: DSA is important for career growth. It is a valuable skill that is in high demand in the tech industry. By mastering DSA, you can enhance your career prospects and land better job opportunities. -20. **Innovation**: DSA helps in fostering innovation. It enables you to develop new algorithms, solve complex problems, and push the boundaries of technology. -21. **Cross-disciplinary Applications**: DSA has cross-disciplinary applications. It is used in various fields such as biology, physics, finance, and many more. It helps in solving problems across different domains. -22. **Problem Complexity**: DSA helps in understanding the complexity of problems. It teaches you how to analyze the time and space complexity of an algorithm and optimize it for better performance. -23. **Algorithmic Thinking**: DSA helps in developing algorithmic thinking. It teaches you how to think algorithmically, analyze problems, and come up with efficient solutions. -24. **Coding Interviews**: DSA is important for coding interviews. Most tech companies ask questions related to data structures and algorithms to assess the problem-solving skills of the candidates. -25. **Coding Competitions**: DSA is essential for coding competitions. It helps in solving challenging problems in a limited amount of time and competing with other programmers. -26. **Problem-solving Techniques**: DSA teaches you problem-solving techniques. It helps in breaking down a complex problem into smaller subproblems and finding the optimal solution. -27. **Coding Challenges**: DSA is used in coding challenges to test the problem-solving skills of the participants. It helps in evaluating the coding skills and logical thinking of the participants. -28. **Algorithm Analysis**: DSA helps in analyzing the time and space complexity of algorithms. It teaches you how to evaluate the performance of an algorithm and optimize it for better efficiency. -29. **Data Handling Techniques**: DSA teaches you data handling techniques. It helps in storing, retrieving, and manipulating data efficiently using data structures and algorithms. -30. **Problem-solving Strategies**: DSA teaches you problem-solving strategies. It helps in approaching a problem, breaking it down into smaller subproblems, and finding the optimal solution. -31. **Coding Standards**: DSA helps in maintaining coding standards. It teaches you how to write clean, efficient, and optimized code using the right data structures and algorithms. -32. **Software Engineering Principles**: DSA is important for software engineering principles. It helps in designing efficient algorithms and data structures for building robust and scalable software systems. -33. **Computer Science Fundamentals**: DSA is essential for computer science fundamentals. It helps in understanding the core concepts of programming, problem-solving, and algorithm design. - - - -## Conclusion - -Data Structures and Algorithms are essential for writing efficient code, solving complex problems, and building scalable systems. They are the foundation of computer science and software engineering. By mastering DSA, you can enhance your problem-solving skills, logical thinking, and coding abilities. DSA is a valuable skill that is in high demand in the tech industry. It is used in various fields such as software development, machine learning, data science, and many more. Therefore, it is important to learn and practice DSA to excel in your career and stay ahead in the competitive tech industry. \ No newline at end of file diff --git a/docs/dsa/roadmap-to-dsa.md b/docs/dsa/roadmap-to-dsa.md deleted file mode 100644 index 5f04e3774..000000000 --- a/docs/dsa/roadmap-to-dsa.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -id: roadmap-to-learning-dsa -sidebar_position: 4 -title: Roadmap to Learning DSA -description: "A structured roadmap to guide you through mastering Data Structures and Algorithms." -tags: [dsa, learning roadmap, algorithms, data-structures] ---- - -# Roadmap to Learning Data Structures and Algorithms (DSA) - -Understanding Data Structures and Algorithms (DSA) is crucial for solving complex problems efficiently. DSA forms the foundation of computer science, providing the necessary tools to manage and manipulate data effectively. This roadmap outlines a structured approach to mastering DSA, designed for both beginners and experienced programmers. - - - -## Your Learning Journey - -### Learning DSA - -Mastering DSA begins with understanding the fundamental concepts. Here’s a structured flowchart to guide your learning: - -```mermaid -flowchart TD - A[Arrays & Hashing] --> B[Two Pointers] - A --> C[Stack] - B --> D[Binary Search] - B --> E[Sliding Window] - B --> F[Linked List] - F --> G[Trees] - G --> H[Tries] - G --> I[Heap / Priority Queue] - G --> J[Backtracking] - J --> K[Graphs] - I --> L[Intervals] - I --> M[Greedy] - I --> N[Advanced Graphs] - K --> O[1-D DP] - O --> P[2-D DP] - K --> Q[Bit Manipulation] - K --> R[Math & Geometry] - Q --> R - -``` - -### Key Concepts and their Order: - -1. **Arrays & Hashing**: - - - **Why**: Arrays are a fundamental data structure used to store collections of data. Hashing adds efficient data retrieval, making it essential for solving problems quickly. - - **Next Steps**: Learning arrays and hashing prepares you for exploring patterns within data sequences. - -2. **Two Pointers and Sliding Window**: - - - **Why**: These are specific techniques for processing sequences like arrays and strings. They optimize algorithms by reducing the need for nested loops, which is useful for problems related to subarrays, substrings, or intervals. - - **Next Steps**: After grasping these techniques, you’ll be ready to tackle more structured data types, like linked lists and stacks. - -3. **Stack and Linked List**: - - - **Why**: Stacks are essential for problems involving LIFO (Last In, First Out) operations, such as evaluating expressions and handling recursive function calls. Linked lists provide a different way of storing sequences, enabling efficient insertion and deletion. - - **Next Steps**: These structures are often prerequisites for understanding hierarchical data structures like trees. - -4. **Trees and Graphs**: - - - **Why**: Trees model hierarchical relationships, and graphs represent complex networks. They are critical for understanding problems related to navigation, dependencies, and hierarchical data. - - **Next Steps**: Mastery of trees and graphs allows you to explore specialized algorithms like backtracking, dynamic programming, and advanced graph algorithms. - -5. **Tries, Backtracking, and Advanced Tree Structures**: - - - **Why**: Tries are specialized trees useful for storing and retrieving strings. Backtracking is a general problem-solving approach that involves exploring all possibilities. Both concepts deepen your understanding of trees and help solve complex recursive problems. - - **Next Steps**: With these skills, you can move on to dynamic programming and more complex graph algorithms. - -6. **Heap / Priority Queue, Intervals, and Greedy Algorithms**: - - - **Why**: Heaps are used for efficiently finding minimum or maximum elements, often required in scheduling and optimization problems. Greedy algorithms provide quick, local solutions that are globally optimal in certain cases. - - **Next Steps**: Learning these prepares you for tackling problems in optimization and scheduling and allows for a smooth transition into dynamic programming. - -7. **Dynamic Programming (1-D and 2-D DP)**: - - - **Why**: DP is used to solve optimization problems by breaking them down into overlapping subproblems. Learning 1-D and 2-D DP helps you understand how to store and reuse solutions, making your algorithms more efficient. - - **Next Steps**: Once you're comfortable with DP, you can delve into specific mathematical and geometric challenges. - -8. **Bit Manipulation, Math & Geometry**: - - **Why**: Bit manipulation is essential for low-level optimization, and math & geometry cover specialized problem-solving techniques that are useful in fields like computer graphics and cryptography. - - **Final Steps**: These advanced topics can help you tackle a wide range of problems, providing a well-rounded understanding of DSA. - -This roadmap provides a sequential approach, where each step builds on the previous concepts, giving you a solid foundation and gradually preparing you for more complex problem-solving. - -### Practice and Applications - -Once you have a firm grasp of the concepts, it’s essential to apply your knowledge practically. Here’s a flowchart that centers on the application and practice of DSA: - -```mermaid -flowchart TD - subgraph central_flowchart [ ] - direction TB - A[Start Practicing DSA] --> B[Join Coding Platforms] - B --> C[Engage in Coding Challenges] - C --> D[Implement DSA in Projects] - D --> E[Real-world Application Scenarios] - E --> F[Prepare for Technical Interviews] - F --> G[Practice Common Interview Questions] - G --> H[Participate in Competitive Programming] - H --> I[Review and Reflect on Learning] - I --> J[Seek Feedback and Improve] - J --> K[End Practice Journey] - end - style central_flowchart fill:#131727 ,stroke:##131c40 ,stroke-width:3px - - -``` - -### Conclusion - -These roadmaps provides a comprehensive guide to learning DSA, emphasizing the importance of understanding core concepts and applying them in practice. By following this path, you'll enhance your problem-solving abilities and be well-prepared for coding interviews, competitive programming, and real-world software development. - -Remember, mastering DSA is a journey that requires consistent practice and engagement. Embrace challenges and keep pushing your limits! diff --git a/docs/dsa/types-of-dsa.md b/docs/dsa/types-of-dsa.md deleted file mode 100644 index fbe90924e..000000000 --- a/docs/dsa/types-of-dsa.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: types-of-dsa -sidebar_position: 3 -title: Types of Data Structures and Algorithms -sidebar_label: Types of DSA -description: "Explore the different types of data structures and algorithms that form the foundation of problem-solving in computer science." -tags: [dsa, data structures, algorithms, types of dsa] ---- - -# Types of Data Structures and Algorithms (DSA) - -Data Structures and Algorithms (DSA) can be broadly classified into different types based on their usage and problem-solving capabilities. This guide will introduce you to the most commonly used data structures and algorithms in computer science. - - - -## Types of Data Structures - -Data structures are essential for organizing and managing data efficiently. Here's a breakdown of the most common types: - -### 1. **Linear Data Structures** - -Linear data structures store elements sequentially, with each element connected to the next one. - -- **Arrays**: Fixed-size data structures where elements are stored in contiguous memory locations. -- **Linked Lists**: A sequence of nodes where each node contains data and a pointer to the next node. -- **Stacks**: A Last-In-First-Out (LIFO) structure where elements are added or removed from the top. -- **Queues**: A First-In-First-Out (FIFO) structure where elements are added at the rear and removed from the front. - -### 2. **Non-Linear Data Structures** - -Non-linear structures store data in a hierarchical manner and can be used to represent complex relationships. - -- **Trees**: A hierarchical data structure with a root node and subtrees of children nodes (e.g., Binary Trees, Binary Search Trees). -- **Graphs**: A collection of nodes connected by edges, useful for representing networks or relationships. -- **Heaps**: A special tree-based data structure that satisfies the heap property, commonly used for priority queues. -- **Tries**: A tree-like data structure used for efficient searching, especially with strings. - -### 3. **Hash-Based Data Structures** - -These data structures use hashing to allow fast data retrieval. - -- **Hash Tables**: Data structures that store key-value pairs, enabling efficient lookups based on unique keys. -- **Sets**: A collection of unique elements that allows efficient checking for membership. -- **Maps**: Similar to hash tables, these store key-value pairs where keys are unique. - -### 4. **Advanced Data Structures** - -These are specialized structures used for complex tasks. - -- **Segment Trees**: Used for answering range queries efficiently. -- **Fenwick Trees (Binary Indexed Trees)**: Used for cumulative frequency table queries. -- **Suffix Trees**: Useful for string matching problems. - - - -## Types of Algorithms - -Algorithms are categorized based on the problems they solve and the techniques they use. Here are some important types: - -### 1. **Sorting Algorithms** - -Sorting algorithms arrange data in a specific order. - -- **Bubble Sort**: Repeatedly swaps adjacent elements if they are in the wrong order. -- **Merge Sort**: Divides the array into halves, sorts them, and merges them. -- **Quick Sort**: Selects a pivot and partitions the array into two halves. -- **Heap Sort**: Uses a heap to efficiently sort elements. - -### 2. **Searching Algorithms** - -Searching algorithms help locate specific elements in a data structure. - -- **Linear Search**: Sequentially checks each element until the target is found. -- **Binary Search**: Efficiently searches in a sorted array by repeatedly dividing the search space in half. - -### 3. **Graph Algorithms** - -Graph algorithms are designed to work with graph data structures. - -- **Breadth-First Search (BFS)**: Explores all the neighbors at the current level before moving on to the next level. -- **Depth-First Search (DFS)**: Explores as far down one branch as possible before backtracking. -- **Dijkstra’s Algorithm**: Finds the shortest path in a weighted graph. -- **Kruskal's Algorithm**: Finds the minimum spanning tree of a graph. - -### 4. **Dynamic Programming Algorithms** - -These algorithms solve complex problems by breaking them into overlapping subproblems. - -- **Fibonacci Sequence**: Calculates Fibonacci numbers using dynamic programming. -- **Knapsack Problem**: Solves optimization problems by building solutions incrementally. - -### 5. **Greedy Algorithms** - -Greedy algorithms make locally optimal choices to find a global solution. - -- **Huffman Coding**: Used for data compression. -- **Dijkstra’s Algorithm**: A greedy algorithm to find the shortest path in a graph. - -### 6. **Divide and Conquer Algorithms** - -These algorithms solve a problem by breaking it into smaller subproblems, solving them independently, and combining their solutions. - -- **Merge Sort**: Divides the array into halves, sorts them, and merges them. -- **Quicksort**: Selects a pivot and partitions the array recursively. - -### 7. **Backtracking Algorithms** - -Backtracking involves exploring all possible solutions to find the correct one by "backing up" when a solution path fails. - -- **N-Queens Problem**: Places N queens on an NxN chessboard so no two queens threaten each other. -- **Subset Sum Problem**: Finds subsets that add up to a target sum. - -### 8. **Recursion-Based Algorithms** - -Recursive algorithms call themselves to solve subproblems. - -- **Factorial Calculation**: Uses recursion to calculate the product of all positive integers up to a given number. -- **Tower of Hanoi**: A puzzle that involves moving disks between rods using recursion. - -### 9. **Machine Learning Algorithms** - -These algorithms enable computers to learn from data. - -- **Linear Regression**: Predicts a continuous value based on input features. -- **K-Nearest Neighbors (KNN)**: Classifies data based on its proximity to other points in a multi-dimensional space. - -### 10. **Optimization Algorithms** - -Optimization algorithms help in finding the best solution from a set of feasible solutions. - -- **Genetic Algorithms**: Use techniques inspired by natural evolution to find optimal solutions. -- **Simulated Annealing**: Searches for a solution by mimicking the process of annealing in metallurgy. - - - -## Conclusion - -Understanding the various types of data structures and algorithms is fundamental to mastering problem-solving in computer science. From sorting algorithms to advanced graph algorithms, knowing which to use for a particular problem is key to writing efficient and scalable code. - - diff --git a/docs/dsa/what-is-dsa.md b/docs/dsa/what-is-dsa.md deleted file mode 100644 index b72246d17..000000000 --- a/docs/dsa/what-is-dsa.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: what-is-dsa -sidebar_position: 1 -title: What is Data Structures and Algorithms (DSA)? -sidebar_label: What is DSA? -description: "Data Structures and Algorithms (DSA) form the backbone of computer science and programming. Learn what DSA is, why it's important, and how it can enhance your coding skills." -tags: [dsa, data structures, algorithms, what is dsa] ---- - -Data Structures and Algorithms (DSA) are fundamental concepts in computer science and programming. They provide a systematic way to organize and store data efficiently, as well as develop algorithms to solve complex problems. Understanding DSA is crucial for any aspiring programmer or software developer, as it forms the backbone of various applications and systems. - - - -## What Are Data Structures? - -Data structures are specialized formats for organizing, storing, and managing data in a computer system. They define the way data is stored, accessed, and manipulated, making it easier to perform operations on the data efficiently. Data structures are essential for optimizing the performance of algorithms and applications, as they determine how data is stored in memory and how it can be accessed quickly. - -### Common data structures include: - -- **Arrays**: A collection of elements stored in contiguous memory locations. -- **Linked Lists**: A sequence of elements linked together by pointers or references. -- **Stacks**: A Last-In-First-Out (LIFO) data structure that supports push and pop operations. -- **Queues**: A First-In-First-Out (FIFO) data structure that supports enqueue and dequeue operations. -- **Trees**: Hierarchical data structures with nodes connected by edges. -- **Graphs**: Non-linear data structures consisting of nodes and edges. -- **Hash Tables**: Data structures that store key-value pairs for efficient data retrieval. -- **Heaps**: Specialized tree-based data structures used for priority queue operations. -- **Tries**: Tree-like data structures used for efficient string searching and storage. -- **Sets**: Data structures that store unique elements without duplicates. -- **Maps**: Data structures that store key-value pairs with unique keys. - - - -## What Are Algorithms? - -Algorithms are step-by-step procedures or instructions for solving problems and performing tasks. They define the logic and operations required to achieve a specific goal or output. Algorithms are essential for processing and manipulating data efficiently, as they provide a systematic approach to problem-solving. - -### Common types of algorithms include: - -- **Sorting Algorithms**: Algorithms that arrange elements in a specific order (e.g., bubble sort, merge sort). -- **Searching Algorithms**: Algorithms that find a specific element in a collection of data (e.g., linear search, binary search). -- **Graph Algorithms**: Algorithms that operate on graph data structures (e.g., depth-first search, breadth-first search). -- **Dynamic Programming Algorithms**: Algorithms that break down complex problems into simpler subproblems (e.g., Fibonacci sequence). -- **Greedy Algorithms**: Algorithms that make locally optimal choices to achieve a global optimum (e.g., Dijkstra's algorithm). -- **Divide and Conquer Algorithms**: Algorithms that divide a problem into smaller subproblems and solve them independently (e.g., quicksort). -- **Backtracking Algorithms**: Algorithms that explore all possible solutions to a problem and backtrack when a solution is not feasible (e.g., N-Queens problem). -- **Recursive Algorithms**: Algorithms that call themselves to solve smaller instances of the same problem (e.g., factorial calculation). -- **Randomized Algorithms**: Algorithms that use randomization to solve problems efficiently (e.g., quicksort with random pivot selection). -- **Approximation Algorithms**: Algorithms that provide near-optimal solutions for complex optimization problems (e.g., traveling salesman problem). -- **Parallel Algorithms**: Algorithms that execute multiple operations simultaneously to improve performance (e.g., parallel matrix multiplication). -- **Machine Learning Algorithms**: Algorithms that enable computers to learn from data and make predictions or decisions (e.g., linear regression, neural networks). -- **Optimization Algorithms**: Algorithms that find the best solution from a set of feasible solutions (e.g., genetic algorithms, simulated annealing). -- **Cryptography Algorithms**: Algorithms that secure data by encrypting and decrypting information (e.g., RSA algorithm, AES algorithm). -- **Numerical Algorithms**: Algorithms that solve mathematical problems involving numerical computations (e.g., numerical integration, linear algebra operations). -- **String Matching Algorithms**: Algorithms that find occurrences of a pattern within a text (e.g., Knuth-Morris-Pratt algorithm, Rabin-Karp algorithm). -- **Geometric Algorithms**: Algorithms that solve geometric problems (e.g., convex hull, closest pair of points). - - - -## Why Are Data Structures and Algorithms Important? - -Data Structures and Algorithms are essential components of computer science and programming for the following reasons: - -1. **Efficient Data Management**: Data structures enable efficient storage, retrieval, and manipulation of data, optimizing the performance of applications and algorithms. -2. **Problem-Solving Skills**: Algorithms provide systematic approaches to problem-solving, helping programmers develop logical thinking and analytical skills. -3. **Optimized Performance**: Well-designed data structures and algorithms lead to faster execution times, reduced memory usage, and improved scalability of software applications. -4. **Code Reusability**: Understanding common data structures and algorithms allows programmers to reuse existing solutions and libraries, saving time and effort in software development. -5. **Interview Preparation**: Data structures and algorithms are frequently tested in technical interviews for software engineering roles, making them essential for job preparation and career advancement. -6. **Foundation for Advanced Topics**: DSA concepts serve as the foundation for advanced topics in computer science, such as machine learning, artificial intelligence, cryptography, and parallel computing. -7. **Industry Applications**: Data structures and algorithms are used in various industries, including finance, healthcare, e-commerce, gaming, social media, and cybersecurity, to solve complex problems and optimize processes. -8. **Competitive Programming**: Competitive programmers rely on strong DSA skills to solve challenging coding problems and participate in coding competitions, hackathons, and coding challenges. -9. **Academic Curriculum**: Data structures and algorithms are core subjects in computer science and software engineering programs, providing students with essential knowledge and skills for their academic and professional careers. -10. **Continuous Learning**: DSA concepts are constantly evolving, with new algorithms and data structures being developed to address emerging challenges and opportunities in the field of computer science. -11. **Open Source Contributions**: Understanding DSA enables programmers to contribute to open source projects, collaborate with other developers, and enhance the quality and performance of software applications. -12. **Problem Complexity Analysis**: Data structures and algorithms help programmers analyze the time and space complexity of algorithms, enabling them to evaluate the efficiency and scalability of their code. -13. **Cross-Disciplinary Applications**: DSA concepts are used in various disciplines, including mathematics, engineering, physics, biology, and social sciences, to model, analyze, and solve complex problems in diverse domains. -14. **Innovation and Creativity**: Mastering data structures and algorithms empowers programmers to innovate, create new solutions, and address real-world challenges with computational thinking and problem-solving skills. -15. **Community Support**: DSA communities, forums, and resources provide programmers with opportunities to learn, share, and collaborate on data structures and algorithms, fostering a culture of continuous improvement and knowledge sharing. - - - -## How Can Data Structures and Algorithms Enhance Your Coding Skills? - -Learning data structures and algorithms can enhance your coding skills in the following ways: - -1. **Problem-Solving Proficiency**: DSA teaches you how to break down complex problems into simpler subproblems, enabling you to solve challenging coding problems with ease. -2. **Algorithmic Thinking**: DSA cultivates your ability to think algorithmically, analyze problems logically, and design efficient solutions using algorithms and data structures. -3. **Code Optimization**: DSA helps you optimize your code by selecting the right data structures and algorithms to improve performance, reduce complexity, and enhance readability. -4. **Technical Interview Preparation**: DSA knowledge is essential for technical interviews, coding assessments, and coding challenges, allowing you to demonstrate your problem-solving skills and algorithmic expertise. -5. **Coding Competitions**: DSA skills are crucial for participating in coding competitions, hackathons, and coding challenges, where you can showcase your problem-solving abilities and compete with other programmers. -6. **Software Development**: DSA concepts are fundamental for software development, enabling you to design efficient algorithms, implement scalable solutions, and build robust applications that meet industry standards. -7. **Career Advancement**: DSA proficiency is highly valued by employers in the tech industry, as it demonstrates your ability to solve complex problems, write efficient code, and contribute to software projects effectively. -8. **Collaborative Learning**: DSA communities, study groups, and coding platforms provide opportunities for collaborative learning, mentorship, and peer support, helping you grow as a programmer and expand your knowledge base. -9. **Continuous Improvement**: DSA learning is a continuous process that allows you to refine your coding skills, explore new algorithms, and stay updated with the latest trends and developments in the field of computer science. - - - -## Conclusion - -Data Structures and Algorithms are essential components of computer science and programming that enable efficient data management, problem-solving, and code optimization. By mastering DSA concepts, you can enhance your coding skills, prepare for technical interviews, participate in coding competitions, and advance your career in the tech industry. Whether you are a beginner or an experienced programmer, learning data structures and algorithms is a valuable investment that can open up new opportunities, expand your knowledge base, and empower you to tackle complex challenges with confidence and creativity. \ No newline at end of file diff --git a/docs/dynamic-programming/Beautiful-Subgrids.md b/docs/dynamic-programming/Beautiful-Subgrids.md deleted file mode 100644 index 2e3aa6f5f..000000000 --- a/docs/dynamic-programming/Beautiful-Subgrids.md +++ /dev/null @@ -1,232 +0,0 @@ ---- -id: beautiful-subgrids -title: Beautiful Subgrids Problem - Efficient Detection -sidebar_label: Beautiful Subgrids -sidebar_position: 3 -description: "In this post, we'll explore the Beautiful Subgrids problem, an algorithmic challenge that focuses on efficiently detecting subgrids in a matrix that meet specific criteria. We'll delve into the problem's constraints, discuss the approach for finding beautiful subgrids, and provide solutions in multiple languages such as C++, Java, Python, JavaScript, and Go. By the end, you'll understand how to count beautiful subgrids in a grid efficiently." -tags: [dsa, dp, grid problems, matrix] ---- - -## Problem Definition - -The Beautiful Subgrids problem involves finding subgrids within a larger 2D grid that possess certain "beautiful" properties, such as symmetry or uniformity in values. The challenge is to efficiently count such subgrids, especially as the grid size increases. - -### Constraints - -- The dimensions of the grid can be large, potentially reaching up to $10^5$ rows and $10^5$ columns. -- The values within the grid can range between a specified set of integers. - -## Approach - -To solve the Beautiful Subgrids problem, we can use a straightforward approach that involves iterating through all possible subgrids and checking if each one meets the criteria for being beautiful. The efficiency of the algorithm is crucial, especially for large inputs. - -### Efficient Detection of Beautiful Subgrids - -1. **Iterate Through All Possible Subgrids**: For each position in the grid, consider all possible square subgrids that can originate from that position. - -2. **Check for Beauty**: For each subgrid, check if it satisfies the beautiful condition (e.g., all elements being equal). - -3. **Count Valid Subgrids**: Maintain a counter to count how many of these subgrids are considered beautiful. - -## Complexity Analysis - -- **Time Complexity**: The worst-case time complexity is $O(m^2 . n^2)$, where $\rightarrow$ $m$ is the number of rows and $\rightarrow$ $n$ is the number of columns in the grid. -- **Space Complexity**: The space complexity is $\rightarrow$ $O(1)$ for auxiliary storage, but this could increase if storing subgrids is necessary. - -## Code Implementations - -Here are implementations of the Beautiful Subgrids problem in various programming languages: - -C++: - -```cpp -#include -#include - -using namespace std; - -// Function to check if a subgrid is beautiful -bool isBeautiful(const vector>& subgrid) { - int firstValue = subgrid[0][0]; - for (const auto& row : subgrid) { - for (int cell : row) { - if (cell != firstValue) { - return false; - } - } - } - return true; // Uniform check -} - -// Function to count beautiful subgrids -int countBeautifulSubgrids(const vector>& grid) { - int m = grid.size(); - int n = grid[0].size(); - int beautifulCount = 0; - - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - for (int size = 1; size <= min(m - i, n - j); size++) { - vector> subgrid(size, vector(size)); - for (int k = 0; k < size; k++) { - for (int l = 0; l < size; l++) { - subgrid[k][l] = grid[i + k][j + l]; - } - } - if (isBeautiful(subgrid)) { - beautifulCount++; - } - } - } - } - return beautifulCount; -} -``` - -Java: - -```java -public class BeautifulSubgrids { - public static boolean isBeautiful(int[][] subgrid) { - int firstValue = subgrid[0][0]; - for (int[] row : subgrid) { - for (int cell : row) { - if (cell != firstValue) { - return false; - } - } - } - return true; // Uniform check - } - - public static int countBeautifulSubgrids(int[][] grid) { - int m = grid.length; - int n = grid[0].length; - int beautifulCount = 0; - - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - for (int size = 1; size <= Math.min(m - i, n - j); size++) { - int[][] subgrid = new int[size][size]; - for (int k = 0; k < size; k++) { - for (int l = 0; l < size; l++) { - subgrid[k][l] = grid[i + k][j + l]; - } - } - if (isBeautiful(subgrid)) { - beautifulCount++; - } - } - } - } - return beautifulCount; - } -} -``` - -Python: - -```python -def is_beautiful(subgrid): - first_value = subgrid[0][0] - for row in subgrid: - if any(cell != first_value for cell in row): - return False - return True # Uniform check - -def count_beautiful_subgrids(grid): - m, n = len(grid), len(grid[0]) - beautiful_count = 0 - - for i in range(m): - for j in range(n): - for size in range(1, min(m - i, n - j) + 1): - subgrid = [row[j:j + size] for row in grid[i:i + size]] - if is_beautiful(subgrid): - beautiful_count += 1 - - return beautiful_count -``` - -Javascript: - -```javascript -function isBeautiful(subgrid) { - const firstValue = subgrid[0][0]; - return subgrid.every(row => row.every(cell => cell === firstValue)); // Uniform check -} - -function countBeautifulSubgrids(grid) { - const m = grid.length; - const n = grid[0].length; - let beautifulCount = 0; - - for (let i = 0; i < m; i++) { - for (let j = 0; j < n; j++) { - for (let size = 1; size <= Math.min(m - i, n - j); size++) { - const subgrid = grid.slice(i, i + size).map(row => row.slice(j, j + size)); - if (isBeautiful(subgrid)) { - beautifulCount++; - } - } - } - } - return beautifulCount; -} -``` - -Go: - -```go -package main - -import "fmt" - -func isBeautiful(subgrid [][]int) bool { - firstValue := subgrid[0][0] - for _, row := range subgrid { - for _, cell := range row { - if cell != firstValue { - return false - } - } - } - return true // Uniform check -} - -func countBeautifulSubgrids(grid [][]int) int { - m := len(grid) - n := len(grid[0]) - beautifulCount := 0 - - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - for size := 1; size <= min(m-i, n-j); size++ { - subgrid := make([][]int, size) - for k := 0; k < size; k++ { - subgrid[k] = make([]int, size) - for l := 0; l < size; l++ { - subgrid[k][l] = grid[i+k][j+l] - } - } - if isBeautiful(subgrid) { - beautifulCount++ - } - } - } - } - return beautifulCount -} - -func min(a, b int) int { - if a < b { - return a - } - return b -} -``` - -## Conclusion - -The Beautiful Subgrids problem presents an interesting challenge that can be approached through a systematic enumeration of potential subgrids. By understanding the properties of beautiful subgrids and applying an efficient counting strategy, we can solve this problem effectively. This algorithm can be optimized further depending on the specific characteristics of the input grid. - diff --git a/docs/dynamic-programming/Matrix-chain-multiplication.md b/docs/dynamic-programming/Matrix-chain-multiplication.md deleted file mode 100644 index fb6480ba6..000000000 --- a/docs/dynamic-programming/Matrix-chain-multiplication.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -id: matrix-chain-multiplication -title: Matrix-chain-multiplication -sidebar_label: Matrix-chain-multiplication -description: The program finds the optimal multiplication order for a matrix chain, minimizing scalar multiplications using dynamic programming for efficiency. -tags: [Dynamic Programming,Algorithm, DSA] ---- -# SHORTEST PATH IN MULTISTAGE GRAPH -### Description -Given a chain of matrices with specified dimensions, the algorithm computes the optimal order to perform matrix multiplications, minimizing computational cost. The solution uses a dynamic programming table to store intermediate results, which avoids redundant calculations and improves efficiency. Users input the number of matrices and their respective dimensions, and the program outputs the minimum multiplication cost required to multiply the entire chain. -### Approach -The Matrix Chain Multiplication program uses dynamic programming to determine the optimal order for multiplying a sequence of matrices. It builds a 2D table where each entry stores the minimum multiplication cost for a specific subchain of matrices, avoiding redundant calculations. For each possible subchain length, the algorithm evaluates different split points to find the one that yields the lowest cost by recursively considering left and right subchains. The final result in the table provides the minimum cost for multiplying the entire matrix chain, ensuring computational efficiency and optimal performance. -### Algorithm Overview -1. **Define Subproblems**: The main problem is broken down into subchains of matrices, with the goal of minimizing the multiplication cost for each subchain. -2. **Use a DP Table**: A 2D table (`minMul[i][j]`) is created where each entry stores the minimum multiplication cost required to multiply matrices from Mi to Mj -3. **Iterate Over Chain Lengths**: For each subchain length L (from 2 to n ), the algorithm calculates the minimum multiplication cost by evaluating every possible split point k within each subchain. -4. **Retrieve Result**: The final result, `minMul[1][n-1]`, gives the minimum number of multiplications needed to multiply the entire chain of matrices. -### Example -- **Input**: - - Enter the number of matrices: `4` - - Enter the dimensions of matrices (n+1 integers where nth matrix has dimensions arr[i] x arr[i+1]): `5 10 15 20 25` -- **Output**: - - Minimum number of multiplications required for the matrices multiplication is `4750` - -### Time Complexity -- The time complexity of the Matrix Chain Multiplication algorithm is O(n^3) , where `n` is the number of matrices. This results from calculating the minimum multiplication cost for each possible subchain of matrices `O(n^2)` and evaluating each split point within these subchains `O(n)` leading to `O(n)xO(n^2)=O(n^3)`. -### C++ Implementation -```cpp -#include -#include -#include -using namespace std; -int MatrixChainMultiplication(const vector& arr, int n) { - vector> minMul(n, vector(n, 0)); - int j, q; - // L is the chain length; starting from 2 as a single matrix does not need multiplication - for (int L = 2; L < n; L++) { - for (int i = 1; i < n - L + 1; i++) { - j = i + L - 1; - minMul[i][j] = INT_MAX; - // Try every possible split point `k` to find the minimum cost for this subchain - for (int k = i; k <= j - 1; k++) { - // Cost of splitting at `k` = cost of left subchain + right subchain + cost of multiplication - q = minMul[i][k] + minMul[k + 1][j] + arr[i - 1] * arr[k] * arr[j]; - if (q < minMul[i][j]) - minMul[i][j] = q; - } - } - } - return minMul[1][n - 1]; -} -int main() { - int n; - cout << "Enter the number of matrices: "; - cin >> n; - vector arr(n + 1); - cout << "Enter the dimensions of matrices (n+1 integers where nth matrix has dimensions arr[i] x arr[i+1]): "; - for (int i = 0; i < n + 1; i++) - cin >> arr[i]; - cout << "Minimum number of multiplications required for the matrices multiplication is " - << MatrixChainMultiplication(arr, n + 1) << endl; - return 0; -} -``` diff --git a/docs/dynamic-programming/Multistage-graph.md b/docs/dynamic-programming/Multistage-graph.md deleted file mode 100644 index 17eb64c43..000000000 --- a/docs/dynamic-programming/Multistage-graph.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -id: multistage-graph -title: MULTISTAGE GRAPH -sidebar_label: SHORTEST PATH IN MULTISTAGE GRAPH -tags: [Dynamic Programming,Graph, DSA] -description: The multistage graph problem is finding the path with minimum cost from source to sink. ---- - -# SHORTEST PATH IN MULTISTAGE GRAPH - -### Description -This program calculates the shortest path from a given source node to a target node in a directed graph using a dynamic programming approach. The graph is represented as an adjacency matrix, where the user provides input for the number of vertices and the adjacency matrix values. -### Problem Definition -- **Input**: The adjacency Cost Matrix. -- **Output**: Minimum cost path and Minimum Cost. - -### Example -- **Input**: - - Enter the number of vertices in the graph: 12 - Enter the adjacency matrix (use 99 for INF): - 99 9 7 3 2 99 99 99 99 99 99 99 - 99 99 99 99 99 4 2 1 99 99 99 99 - 99 99 99 99 99 2 7 99 99 99 99 99 - 99 99 99 99 99 99 99 11 99 99 99 99 - 99 99 99 99 99 99 11 8 99 99 99 99 - 99 99 99 99 99 99 99 99 6 5 99 99 - 99 99 99 99 99 99 99 99 4 3 99 99 - 99 99 99 99 99 99 99 99 99 5 6 99 - 99 99 99 99 99 99 99 99 99 99 99 4 - 99 99 99 99 99 99 99 99 99 99 99 2 - 99 99 99 99 99 99 99 99 99 99 99 5 - 99 99 99 99 99 99 99 99 99 99 99 0 - - Enter the source node: 1 - Enter the target node: 12 - -- **Output**: - - The shortest path distance from node 1 to node 12 is: 16 - Path: 1 -> 2 -> 7 -> 10 -> 12. -### Diagrammatic represntation of the above example - ![Screenshot 2024-10-22 184618](https://github.com/user-attachments/assets/b4a70ddf-332e-4885-b367-38b20362d31f) - -### Algorithm Overview -1. **Initialization:** - The distance array `dist[]` is initialized with INF for all nodes except the target node, which has a distance of `0`. This array will store the shortest known distances from each node to the target. - The path array `path[]` is initialized to store the next node on the shortest path for each node. -2. **Dynamic Programming Loop:** - The function iterates from the target node backward to the source, evaluating each node's potential distance to the target by checking its connection to subsequent nodes. - If the current distance from node `i` to the target is greater than the distance from node `i` to `j` plus `dist[j]` (where j is a neighboring node), it updates `dist[i]` and sets `path[i]` to `j`. -3. **Path Construction:** - If a valid path exists, the function prints the shortest distance from the source to the target. - It then traces the path from the source to the target using the `path[]` array and prints each node in the order they are visited. - -### Time Complexity -- O(n^2) - where `n` is the total number of nodes in the multistage graph - -### C++ Implementation - -```cpp -#include -#include -#include - -#define INF 99 - -void shortestDist(const std::vector>& graph, int n, int source, int target) { - std::vector dist(n + 1, INF), path(n + 1, -1); - - dist[target] = 0; - path[target] = target; - - for (int i = target - 1; i >= 1; i--) { - for (int j = i + 1; j <= n; j++) { - if (graph[i][j] != INF && dist[i] > graph[i][j] + dist[j]) { - dist[i] = graph[i][j] + dist[j]; - path[i] = j; - } - } - } - - if (dist[source] == INF) { - std::cout << "There is no path from node " << source << " to node " << target << "\n"; - return; - } - - std::cout << "The shortest path distance from node " << source << " to node " << target << " is: " << dist[source] << "\n"; - - std::cout << "Path: " << source; - int current = source; - while (current != target) { - current = path[current]; - std::cout << " -> " << current; - } - std::cout << "\n"; -} - -int main() { - int n, source, target; - - std::cout << "Enter the number of vertices in the graph: "; - std::cin >> n; - - std::vector> graph(n + 1, std::vector(n + 1)); - - std::cout << "Enter the adjacency matrix (use " << INF << " for INF):\n"; - for (int i = 1; i <= n; i++) { - for (int j = 1; j <= n; j++) { - std::cin >> graph[i][j]; - } - } - - std::cout << "Enter the source node: "; - std::cin >> source; - std::cout << "Enter the target node: "; - std::cin >> target; - - shortestDist(graph, n, source, target); - - return 0; -} -``` diff --git a/docs/dynamic-programming/Two-City-Scheduling-3D-DP.md b/docs/dynamic-programming/Two-City-Scheduling-3D-DP.md deleted file mode 100644 index d6253cdfa..000000000 --- a/docs/dynamic-programming/Two-City-Scheduling-3D-DP.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -id: two-city-scheduling-dp -title: Two City Scheduling Problem - 3D Dynamic Programming -sidebar_label: Two City Scheduling -sidebar_position: 2 -description: "In this post, we'll explore the Two City Scheduling problem, a classic algorithmic challenge that can be solved efficiently using 3D Dynamic Programming. We'll delve into the problem's constraints, discuss the dynamic programming approach, and provide solutions in multiple languages such as C++, Java, Python, JavaScript, and Go. By the end, you'll understand how to use DP to minimize the total travel costs for sending an equal number of people to two different cities." -tags: [dsa, dynamic programming, scheduling] ---- - -## Problem Statement -You are given two cities, `A` and `B`, and a list of people, where each person has a cost associated with flying to either city. Your goal is to find the optimal way to send `N` people to city `A` and `N` people to city `B` such that the total cost is minimized. - -The input consists of an array `costs` where `costs[i] = [aCost, bCost]`, which represents the cost of flying the `i-th` person to city `A` and city `B`. - -### Objective -- Return the minimum total cost to send `N` people to each city. - -### Example -```plaintext -Input: costs = [[10,20],[30,200],[50,30],[200,500]] -Output: 370 -``` - - -### Constraints -- `2 * n == costs.length` -- `2 <= costs.length <= 100` -- `costs.length` is even. -- `1 <= aCosti, bCosti <= 1000` - -## Solution -This solution employs a dynamic programming approach to solve the Two City Scheduling problem. - -### Dynamic Programming Approach - -**DP Array Initialization:** - -We initialize a 3D DP array `dp[i][wA][wB]`, where: -- `i` represents the first `i` people considered. -- `wA` represents the number of people sent to city `A`. -- `wB` represents the number of people sent to city `B`. - -**Base Case:** - -For `0` people, the total cost is `0` (no one is sent). - -**Transition:** - -For each person, we can choose to send them to either city `A` or city `B`, updating our DP table accordingly: -- If a person is sent to city `A`, we reduce the count of people going to city `A` and add the cost of sending them there. -- Similarly, if sent to city `B`, we reduce the count of people going to city `B` and add the respective cost. - -**Final Calculation:** - -The minimum total cost will be found in `dp[2 * N][N][N]`. - -### Time and Space Complexity -- **Time Complexity:** O(N³), where N is half the size of the costs array. -- **Space Complexity:** O(N³) due to the 3D DP array. - -### Code Implementation - -C++: -```cpp -class Solution { -public: - int twoCitySchedCost(vector>& costs) { - int N = costs.size() / 2; - int dp[2 * N + 1][N + 1][N + 1]; - for (int i = 0; i <= N; ++i) { - for (int j = 0; j <= N; ++j) { - dp[0][i][j] = 0; - } - } - for (int i = 1; i <= 2 * N; ++i) { - for (int wA = 1; wA <= N; ++wA) { - if (dp[i - 1][wA - 1][0] == INT_MAX) { - dp[i][wA][0] = INT_MAX; - } else { - dp[i][wA][0] = costs[i - 1][0] + dp[i - 1][wA - 1][0]; - } - } - for (int wB = 1; wB <= N; ++wB) { - if (dp[i - 1][0][wB - 1] == INT_MAX) { - dp[i][0][wB] = INT_MAX; - } else { - dp[i][0][wB] = costs[i - 1][1] + dp[i - 1][0][wB - 1]; - } - } - dp[i][0][0] = INT_MAX; - } - - for (int i = 1; i <= 2 * N; ++i) { - for (int wA = 1; wA <= N; ++wA) { - for (int wB = 1; wB <= N; ++wB) { - if (dp[i - 1][wA - 1][wB] == INT_MAX) { - dp[i][wA][wB] = costs[i - 1][1]; - } else if (dp[i - 1][wA][wB - 1] == INT_MAX) { - dp[i][wA][wB] = costs[i - 1][0]; - } else { - dp[i][wA][wB] = min(costs[i - 1][0] + dp[i - 1][wA - 1][wB], - costs[i - 1][1] + dp[i - 1][wA][wB - 1]); - } - } - } - } - return dp[2 * N][N][N]; - } -}; -``` - -Java: -```java -class Solution { - public int twoCitySchedCost(int[][] costs) { - int N = costs.length / 2; - int[][][] dp = new int[2 * N + 1][N + 1][N + 1]; - - for (int i = 0; i <= N; i++) { - for (int j = 0; j <= N; j++) { - dp[0][i][j] = 0; - } - } - - for (int i = 1; i <= 2 * N; i++) { - for (int wA = 1; wA <= N; wA++) { - if (dp[i - 1][wA - 1][0] == Integer.MAX_VALUE) { - dp[i][wA][0] = Integer.MAX_VALUE; - } else { - dp[i][wA][0] = costs[i - 1][0] + dp[i - 1][wA - 1][0]; - } - } - for (int wB = 1; wB <= N; wB++) { - if (dp[i - 1][0][wB - 1] == Integer.MAX_VALUE) { - dp[i][0][wB] = Integer.MAX_VALUE; - } else { - dp[i][0][wB] = costs[i - 1][1] + dp[i - 1][0][wB - 1]; - } - } - dp[i][0][0] = Integer.MAX_VALUE; - } - - for (int i = 1; i <= 2 * N; i++) { - for (int wA = 1; wA <= N; wA++) { - for (int wB = 1; wB <= N; wB++) { - if (dp[i - 1][wA - 1][wB] == Integer.MAX_VALUE) { - dp[i][wA][wB] = costs[i - 1][1]; - } else if (dp[i - 1][wA][wB - 1] == Integer.MAX_VALUE) { - dp[i][wA][wB] = costs[i - 1][0]; - } else { - dp[i][wA][wB] = Math.min(costs[i - 1][0] + dp[i - 1][wA - 1][wB], - costs[i - 1][1] + dp[i - 1][wA][wB - 1]); - } - } - } - } - - return dp[2 * N][N][N]; - } -} -``` - -Python: -```python -class Solution: - def twoCitySchedCost(self, costs: List[List[int]]) -> int: - N = len(costs) // 2 - dp = [[[0] * (N + 1) for _ in range(N + 1)] for _ in range(2 * N + 1)] - - for i in range(1, 2 * N + 1): - for wA in range(1, N + 1): - if dp[i - 1][wA - 1][0] == float('inf'): - dp[i][wA][0] = float('inf') - else: - dp[i][wA][0] = costs[i - 1][0] + dp[i - 1][wA - 1][0] - - for wB in range(1, N + 1): - if dp[i - 1][0][wB - 1] == float('inf'): - dp[i][0][wB] = float('inf') - else: - dp[i][0][wB] = costs[i - 1][1] + dp[i - 1][0][wB - 1] - - dp[i][0][0] = float('inf') - - for i in range(1, 2 * N + 1): - for wA in range(1, N + 1): - for wB in range(1, N + 1): - if dp[i - 1][wA - 1][wB] == float('inf'): - dp[i][wA][wB] = costs[i - 1][1] - elif dp[i - 1][wA][wB - 1] == float('inf'): - dp[i][wA][wB] = costs[i - 1][0] - else: - dp[i][wA][wB] = min(costs[i - 1][0] + dp[i - 1][wA - 1][wB], - costs[i - 1][1] + dp[i - 1][wA][wB - 1]) - - return dp[2 * N][N][N] -``` - -Javascript: -```javascript -class Solution { - twoCitySchedCost(costs) { - const N = costs.length / 2; - const dp = Array.from({ length: 2 * N + 1 }, () => - Array.from({ length: N + 1 }, () => Array(N + 1).fill(0)) - ); - - for (let i = 0; i <= N; i++) { - for (let j = 0; j <= N; j++) { - dp[0][i][j] = 0; - } - } - - for (let i = 1; i <= 2 * N; i++) { - for (let wA = 1; wA <= N; wA++) { - dp[i][wA][0] = dp[i - 1][wA - 1][0] === Infinity ? Infinity : costs[i - 1][0] + dp[i - 1][wA - 1][0]; - } - for (let wB = 1; wB <= N; wB++) { - dp[i][0][wB] = dp[i - 1][0][wB - 1] === Infinity ? Infinity : costs[i - 1][1] + dp[i - 1][0][wB - 1]; - } - dp[i][0][0] = Infinity; - } - - for (let i = 1; i <= 2 * N; i++) { - for (let wA = 1; wA <= N; wA++) { - for (let wB = 1; wB <= N; wB++) { - if (dp[i - 1][wA - 1][wB] === Infinity) { - dp[i][wA][wB] = costs[i - 1][1]; - } else if (dp[i - 1][wA][wB - 1] === Infinity) { - dp[i][wA][wB] = costs[i - 1][0]; - } else { - dp[i][wA][wB] = Math.min(costs[i - 1][0] + dp[i - 1][wA - 1][wB], - costs[i - 1][1] + dp[i - 1][wA][wB - 1]); - } - } - } - } - - return dp[2 * N][N][N]; - } -} -``` - -Go: -```go -package main - -import ( - "math" -) - -func twoCitySchedCost(costs [][]int) int { - N := len(costs) / 2 - dp := make([][][]int, 2*N+1) - for i := range dp { - dp[i] = make([][]int, N+1) - for j := range dp[i] { - dp[i][j] = make([]int, N+1) - } - } - - for i := 0; i <= N; i++ { - for j := 0; j <= N; j++ { - dp[0][i][j] = 0 - } - } - - for i := 1; i <= 2*N; i++ { - for wA := 1; wA <= N; wA++ { - if dp[i-1][wA-1][0] == math.MaxInt { - dp[i][wA][0] = math.MaxInt - } else { - dp[i][wA][0] = costs[i-1][0] + dp[i-1][wA-1][0] - } - } - for wB := 1; wB <= N; wB++ { - if dp[i-1][0][wB-1] == math.MaxInt { - dp[i][0][wB] = math.MaxInt - } else { - dp[i][0][wB] = costs[i-1][1] + dp[i-1][0][wB-1] - } - } - dp[i][0][0] = math.MaxInt - } - - for i := 1; i <= 2*N; i++ { - for wA := 1; wA <= N; wA++ { - for wB := 1; wB <= N; wB++ { - if dp[i-1][wA-1][wB] == math.MaxInt { - dp[i][wA][wB] = costs[i-1][1] - } else if dp[i-1][wA][wB-1] == math.MaxInt { - dp[i][wA][wB] = costs[i-1][0] - } else { - dp[i][wA][wB] = min(costs[i-1][0]+dp[i-1][wA-1][wB], - costs[i-1][1]+dp[i-1][wA][wB-1]) - } - } - } - } - - return dp[2*N][N][N] -} - -func min(a, b int) int { - if a < b { - return a - } - return b -} -``` - -### Conclusion -This solution effectively utilizes dynamic programming to optimize the process of scheduling flights to two cities, significantly reducing the computational complexity compared to a brute-force approach. By leveraging a 3D DP array, we ensure that we only compute each state once, leading to an efficient solution. \ No newline at end of file diff --git a/docs/dynamic-programming/_category_.json b/docs/dynamic-programming/_category_.json deleted file mode 100644 index 6fb4152b4..000000000 --- a/docs/dynamic-programming/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Dynamic Programming", - "position": 12, - "link": { - "type": "generated-index", - "description": "Learn the most important Concepts of Dynamic Programming." - } - } \ No newline at end of file diff --git a/docs/dynamic-programming/approaches.md b/docs/dynamic-programming/approaches.md deleted file mode 100644 index 266352108..000000000 --- a/docs/dynamic-programming/approaches.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -id: dynamic-programming-approaches -title: Approaches in Dynamic Programming -sidebar_label: Approaches in Dynamic Programming -description: "In this blog post, we'll explore the approaches used in Dynamic Programming (DP), a powerful technique for solving complex problems by breaking them down into simpler subproblems. You'll learn about the two main approaches—Top-Down and Bottom-Up—how they work, their pros and cons, and examples to illustrate their application." -tags: [dsa, algorithms, dynamic-programming] ---- - -## Approaches in Dynamic Programming -There are two main approaches to solving DP problems: - -- ## Top-Down Approach (Memoization): - - In this approach, you start with the main problem and recursively break it down into subproblems. When you solve a subproblem, you store its result in a data structure (usually an array or hash table) so that the next time you need to solve the same subproblem, you can retrieve the stored result instead of recalculating it. - - - **Pros**: Easier to implement, especially for problems where the recursive structure is clear. - - **Cons**: Can have higher space complexity due to the recursion stack, and there might be overhead from recursive calls. - - **Example**: Fibonacci sequence calculation using memoization. - - -- ## Bottom-Up Approach (Tabulation): - - In this approach, you solve all possible subproblems first, typically in a tabular format. You start with the smallest subproblems and work your way up to the main problem, filling in a table (usually an array) with the solutions to subproblems. - - - **Pros**: Generally more space-efficient and avoids the overhead of recursive calls. - - **Cons**: Can be less intuitive to implement for some problems compared to the top-down approach. - - **Example**: Solving the 0/1 Knapsack problem using tabulation. diff --git a/docs/dynamic-programming/dynamic-programming-optimizations.md b/docs/dynamic-programming/dynamic-programming-optimizations.md deleted file mode 100644 index a60e79d49..000000000 --- a/docs/dynamic-programming/dynamic-programming-optimizations.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -id: dynamic-programming-optimizations -title: Dynamic Programming Optimizations -sidebar_label: Dynamic Programming -sidebar_position: 1 -description: "In this blog post, we'll explore Dynamic Programming (DP) Optimizations, a powerful technique used in algorithmic problem-solving. We'll cover optimizations such as Memoization, Tabulation, and State Space Reduction, and discuss their applications in solving complex problems efficiently. We'll also tackle classic DP problems like the Knapsack Problem, Longest Increasing Subsequence, and Matrix Chain Multiplication, providing Python code examples along the way. By the end, you'll understand how to implement DP solutions effectively and enhance their performance." -tags: [dsa, dynamic programming, optimizations] ---- - -Dynamic Programming (DP) is a technique used to solve problems by breaking them down into simpler subproblems. DP Optimizations like Memoization, Tabulation, and State Space Reduction help improve efficiency and performance in solving complex problems. - -## 1. What is Dynamic Programming? - -Dynamic Programming is an optimization approach that solves problems by storing solutions to subproblems to avoid redundant calculations. Common techniques include: - -- **Memoization**: Storing results of expensive function calls and reusing them when the same inputs occur again. -- **Tabulation**: Iteratively building a table of results for subproblems, starting from the smallest subproblems. -- **State Space Reduction**: Reducing the amount of memory required by storing only necessary states. - -## 2. Common DP Problems - -### a. Knapsack Problem - -Maximize the total value of items in a knapsack given weight constraints. - -### b. Longest Increasing Subsequence - -Find the longest subsequence of a sequence such that all elements are sorted in increasing order. - -### c. Matrix Chain Multiplication - -Determine the optimal order for multiplying a chain of matrices to minimize the number of operations. - -## 3. Best Practices for DP - -- Identify overlapping subproblems to utilize memoization or tabulation. -- Convert recursive solutions to iterative tabulation for better space efficiency. -- Avoid redundant calculations by carefully managing stored states. - -## 4. Performance Analysis - -- **Time Complexity**: Generally O(n^2) or O(n \* m) based on the problem and optimization used. -- **Space Complexity**: Can often be reduced to O(n) or even O(1) using state space reduction. - -## 5. Advanced Variations - -### a. Sparse Table - -Useful for answering range queries on immutable arrays. - -### b. Divide and Conquer DP Optimization - -Combines divide-and-conquer with DP, useful in problems like Convex Hull Optimization. - -## 6. Conclusion - -Dynamic Programming is a powerful approach for solving complex problems by breaking them down into simpler overlapping subproblems. By leveraging memoization, tabulation, and state space reduction, you can efficiently solve problems such as the Knapsack Problem and Matrix Chain Multiplication. - ---- - -## References - -- [Dynamic Programming - GeeksforGeeks](https://www.geeksforgeeks.org/dynamic-programming/) -- [MIT OCW - Dynamic Programming](https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/lecture-notes/) -- [TopCoder - DP Optimization](https://www.topcoder.com/community/competitive-programming/tutorials/dynamic-programming-from-novice-to-advanced/) diff --git a/docs/dynamic-programming/fence-painting.md b/docs/dynamic-programming/fence-painting.md deleted file mode 100644 index 26ba3c206..000000000 --- a/docs/dynamic-programming/fence-painting.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -id: fence-painting -sidebar_position: 12 -title: Fence Painting Problem -sidebar_label: Fence Painting -description: "In this blog post, we'll explore the fence painting problem and calculate the number of ways to paint the fence using dynamic programming." -tags: [dsa, dynamic programming, algorithms] ---- - -## Introduction -The fence painting problem is a classic example of combinatorial problems in dynamic programming. Given a number of fence posts and a set of colors, the challenge is to determine the number of ways to paint the fence such that no two adjacent posts have the same color. - -## Problem Statement -Given: -- `n`: The number of fence posts. -- `k`: The number of colors available. - -The goal is to calculate the total number of ways to paint the fence. - -## Dynamic Programming Approach -To solve this problem efficiently, we use dynamic programming. We maintain two variables: -- **same:** The number of ways to paint the current post the same color as the previous post. -- **diff:** The number of ways to paint the current post a different color from the previous post. - -### Base Cases -1. If there is only one post, there are `k` ways to paint it. -2. If there are two posts, we can paint the first post in `k` ways and the second post in `k` ways, resulting in `k * k` ways. - -### Recursive Relation -For `n > 2`, the relations are: -- The current post painted the same color as the previous: `same = diff`. -- The current post painted a different color: `diff = total * (k - 1)`, where `total = same + diff`. - -### Implementation -Here’s how you can implement this in C++: - -```cpp -#include - -// Function to calculate the number of ways to paint the fence -int countWays(int n, int k) { - // If there's only one post, there are 'k' ways to paint it - if (n == 1) - return k; - - // If there are two posts: - // For the first post, we have 'k' options. - // For the second post, we can either paint it the same as the first or different. - // There are 'k' ways to paint the first post, and for the second: - // - If it's the same, there are 'k' options. - // - If it's different, there are 'k * (k - 1)' options. - if (n == 2) - return k * k; - - // For more than two posts, we use dynamic programming - int same = k; // Ways to paint the first 2 posts the same - int diff = k * (k - 1); // Ways to paint the first 2 posts differently - int total = same + diff; - - // Loop through the remaining posts - for (int i = 3; i <= n; i++) { - same = diff; // The current post has to be different from the previous one - diff = total * (k - 1); // All 'k-1' color options for painting differently - total = same + diff; // Total ways to paint up to current post - } - - return total; -} - -// Driver program to test the function -int main() { - int n = 3; // Number of fence posts - int k = 2; // Number of colors - - printf("Number of ways to paint the fence: %d\n", countWays(n, k)); - - return 0; -} - -``` - diff --git a/docs/dynamic-programming/house-robber.md b/docs/dynamic-programming/house-robber.md deleted file mode 100644 index 59e7c1b03..000000000 --- a/docs/dynamic-programming/house-robber.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -id: house-robber -title: House Robber -sidebar_label: "House Robber" -sidebar_position: 5 -description: In this blog post, we explore the House Robber problem, a classic dynamic programming challenge that determines the maximum amount of money you can rob from a series of houses arranged in a line. -tags: [DP, House Robber] ---- - -# House Robber - -## Introduction - -The **House Robber** problem is a popular dynamic programming problem that illustrates how to make optimal decisions while adhering to constraints. In this problem, you must decide how much money to rob from a series of houses lined up in a row, ensuring that no two adjacent houses are robbed to avoid detection. - -### Example - -Consider the following amounts in houses: -- House values: `[2, 7, 9, 3, 1]` - -The maximum amount you can rob without alerting the police is `12`, which can be achieved by robbing the houses with values `2`, `9`, and `1`. - -## Problem Definition - -Given an array of non-negative integers representing the amount of money at each house, the objective is to calculate the maximum amount of money you can rob without robbing two adjacent houses. - -## Dynamic Programming Approach - -To solve the House Robber problem, we can use dynamic programming by maintaining a `dp` array where `dp[i]` represents the maximum amount of money that can be robbed up to the i-th house. - -### Recurrence Relation - -1. For each house `i`, we have two choices: - - Rob the current house `i`, adding its value to the maximum amount robbed from houses up to `i - 2`: - $$ - dp[i] = nums[i] + dp[i - 2] - $$ - - Skip the current house and take the maximum amount robbed from the previous house: - $$ - dp[i] = dp[i - 1] - $$ -2. The state transition is: - $$ - dp[i] = \max(dp[i - 1], nums[i] + (i > 1 ? dp[i - 2] : 0)) - $$ - -### Base Case - -- If there are no houses, the maximum amount is `0`: `dp[0] = 0`. -- If there is one house, the maximum amount is its value: `dp[1] = nums[0]`. - -## Code Implementation in C++ - -Here’s a C++ implementation of the House Robber problem: - -```cpp -#include -#include - -using namespace std; - -int rob(vector& nums) { - int n = nums.size(); - if (n == 0) return 0; - if (n == 1) return nums[0]; - - // Create a dp array to store the maximum amounts - vector dp(n, 0); - dp[0] = nums[0]; - dp[1] = max(nums[0], nums[1]); - - // Fill the dp array - for (int i = 2; i < n; i++) { - dp[i] = max(dp[i - 1], nums[i] + dp[i - 2]); - } - - // The maximum amount is found at dp[n-1] - return dp[n - 1]; -} - -int main() { - vector houses = {2, 7, 9, 3, 1}; - cout << "Maximum amount of money that can be robbed: " << rob(houses) << endl; // Output: 12 - - // Additional test cases - vector houses1 = {1, 2, 3, 1}; - cout << "Maximum amount (1, 2, 3, 1): " << rob(houses1) << endl; // Output: 4 - - vector houses2 = {2, 1, 1, 2}; - cout << "Maximum amount (2, 1, 1, 2): " << rob(houses2) << endl; // Output: 4 - - return 0; -} - -``` -## Explanation of the Code - -1. **Initial Setup:** - - - We first determine the number of houses `n` and create a `dp` vector of size `n + 1`, initializing all elements to 0. - - The `dp[i]` represents the maximum amount of money that can be robbed up to the i-th house. - -2. **Filling the DP Array:** - - - We start from the first house and iteratively calculate the maximum money that can be robbed at each house. - - For each house `i`, we have two choices: - - Rob the current house and add its value to the maximum amount robbed from houses up to `i - 2` (i.e., `dp[i - 2] + nums[i]`). - - Skip the current house and take the maximum amount robbed from the previous house (i.e., `dp[i - 1]`). - - We take the maximum of these two choices and store it in `dp[i]`. - -3. **Returning the Result:** - - - Once the DP array is completely filled, the last element `dp[n]` contains the maximum amount of money that can be robbed from all houses. - -## Time and Space Complexity - -- **Time Complexity:** The time complexity is $O(n)$ since we iterate through the list of houses once. -- **Space Complexity:** The space complexity is $O(n)$ due to the `dp` array used for storing intermediate results. - -## Conclusion - -The House Robber problem is a classic example of dynamic programming that demonstrates how to make optimal decisions at each step to maximize the overall outcome. The approach described here allows for an efficient solution while maintaining clarity and simplicity in code structure. diff --git a/docs/dynamic-programming/how-to-identify.md b/docs/dynamic-programming/how-to-identify.md deleted file mode 100644 index a43b4ff8c..000000000 --- a/docs/dynamic-programming/how-to-identify.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -id: identifying-dynamic-programming-problem -title: Identifying a Dynamic Programming Problem -sidebar_label: Identifying a Dynamic Programming Problem -description: "In this blog post, we'll explore how to identify problems that can be effectively solved using Dynamic Programming (DP) techniques, focusing on the key properties of optimal substructure and overlapping subproblems." -tags: [dsa, algorithms, dynamic programming] ---- - -To identify whether a problem can be solved using Dynamic Programming (DP), you typically look for two key properties: - -### Optimal Substructure: - -- A problem exhibits optimal substructure if an optimal solution to the problem can be constructed from optimal solutions to its subproblems. In other words, if you can solve a problem by combining the solutions of smaller instances of the same problem, it likely has optimal substructure. - -### Overlapping Subproblems: - -- A problem has overlapping subproblems if the same subproblems are solved multiple times during the computation of the solution. DP is useful when the same calculations are needed multiple times, and it allows you to store and reuse these solutions to avoid redundant work. diff --git a/docs/dynamic-programming/longest-zig-zag-subsequence.md b/docs/dynamic-programming/longest-zig-zag-subsequence.md deleted file mode 100644 index f7f808ee3..000000000 --- a/docs/dynamic-programming/longest-zig-zag-subsequence.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: longest-zig-zag-subsequence -title: "Longest Zig-Zag Subsequence - Dynamic Programming" -sidebar_label: "Longest Zig-Zag Subsequence" -description: "In this post, we'll explore the Longest Zig-Zag-Subsequence problem, which aims to find the longest subsequence where elements alternate between increasing and decreasing." -tags: [dsa, dynammic programming] ---- - -The **Longest Zig-Zag-Subsequence** problem is an extension of the longest increasing subsequence problem but requires more thinking for finding optimal substructure property in this. -We will solve this problem by dynamic Programming method. - -## Problem Statement - -Given an array nums of n positive integers. The task is to find the longest Zig-Zag subsequence problem such that all elements of this are alternating (`numsi-1 < numsi > numsi+1` or `numsi-1 > numsi < numsi+1`). - -The input consists of an array where nums = `{a,b,c}`. - -## Objective -- The objective of the longest zigzag subsequence problem is to find the longest subsequence within a given sequence of numbers that alternates between increasing and decreasing. - -### Example -You are given an integer array arr of length n. A zigzag subsequence is a subsequence where the difference between consecutive elements alternates between positive and negative. Your task is to find the length of the longest zigzag subsequence in arr. - -## Input -An integer array arr of length n (`1 ≤ n ≤ 1000`) -Each element in arr is an integer (`1 ≤ arr[i] ≤ 10,000`) - -## Output -A single integer representing the length of the longest zigzag subsequence. - -## Constraints -- `1 ≤ n ≤ 1000` — This allows an $𝑂(𝑛^2)$ dynamic programming solution to run efficiently within time limits. -- `1 ≤ arr[i] ≤ 10,000` — Positive integers allow straightforward comparisons. - -## Approach -1. Initialize two arrays, up and down, with 1s (each element itself is a subsequence of length 1). -2. For each element at index i, check all previous elements at index j: -If `arr[i] > arr[j]`, update `up[i] = max(up[i], down[j] + 1)`. -If `arr[i] < arr[j]`, update `down[i] = max(down[i], up[j] + 1)`. -3. The final answer is the maximum value in up and down arrays. - -## Solution - -To solve this, we use dynamic programming. We maintain two arrays, up and down: - -- `up[i]`: Stores the length of the longest zigzag subsequence ending at index i where the last element forms an "up" (increase). -- `down[i]`: Stores the length of the longest zigzag subsequence ending at index i where the last element forms a "down" (decrease). - -## Code Implementation in C++ - -```cpp -#include -#include -#include -using namespace std; - -int longestZigzagSubsequence(const vector& arr) { - int n = arr.size(); - if (n == 0) return 0; - - // Initialize DP arrays - vector up(n, 1); // up[i] means the longest zigzag ending with an "up" at i - vector down(n, 1); // down[i] means the longest zigzag ending with a "down" at i - - // Build the up and down arrays - for (int i = 1; i < n; ++i) { - for (int j = 0; j < i; ++j) { - if (arr[i] > arr[j]) { - up[i] = max(up[i], down[j] + 1); - } else if (arr[i] < arr[j]) { - down[i] = max(down[i], up[j] + 1); - } - } - } - - // Find the maximum value in both arrays - int maxLength = max(*max_element(up.begin(), up.end()), *max_element(down.begin(), down.end())); - return maxLength; -} - -int main() { - vector arr = {1, 7, 4, 9, 2, 5}; - cout << "Length of the longest zigzag subsequence: " << longestZigzagSubsequence(arr) << endl; - return 0; -} -``` - -## Explanation of Code - -We iterate over each i and, for each i, check every j (where `j < i`). - -up[i] is updated when `arr[i] > arr[j]`, meaning we’re continuing a zigzag sequence with an increase. - -down[i] is updated when `arr[i] < arr[j]`, continuing a zigzag sequence with a decrease. - -Finally, `max(max(up), max(down))` gives the length of the longest zigzag subsequence. - -## Complexity Analysis -- **Time Complexity:** $𝑂(𝑛^2)$ due to the nested loops over i and j. - -- **Space Complexity:** $𝑂(𝑛)$ for storing the up and down arrays. - -## Conclusion -The Longest Zigzag Subsequence problem is a classic example of a dynamic programming problem. It requires us to identify the longest subsequence in which elements alternate between increasing and decreasing. By leveraging two dynamic programming arrays, up and down, we efficiently track the length of valid zigzag patterns as we progress through the array. diff --git a/docs/dynamic-programming/longest_common_subsequence.md b/docs/dynamic-programming/longest_common_subsequence.md deleted file mode 100644 index e62958c0f..000000000 --- a/docs/dynamic-programming/longest_common_subsequence.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -id: longest-common-subsequence -title: Longest Common Subsequence -sidebar_label: "Longest Common Subsequence" -sidebar_position: 4 -description: Longest Common Subsequence (LCS) is a dynamic programming technique that finds the longest subsequence common to two strings. It’s widely used in text comparison, bioinformatics, and file differencing tools. -tags: [DP, Longest common subsequence ] ---- -# Longest Common Subsequence (LCS) - -## Introduction - -The **Longest Common Subsequence (LCS)** is a fundamental problem in computer science, particularly in the field of dynamic programming. It helps in finding the longest subsequence that is common to two sequences (strings or arrays). A **subsequence** is a sequence that appears in the same relative order but not necessarily contiguously within the original sequence. - -### Example - -For example, consider the two strings: -- String X: `ABCBDAB` -- String Y: `BDCAB` - -The longest common subsequence (LCS) between these two strings is `"BCAB"`, which has a length of 4. - -## Problem Definition - -Given two sequences (X and Y), the goal is to find the length of the longest subsequence that is common to both sequences. - -## Dynamic Programming Approach - -To solve the LCS problem, we can utilize dynamic programming by creating a 2D table where `dp[i][j]` represents the length of the LCS of the first `i` characters of string X and the first `j` characters of string Y. - -### Recurrence Relation - -1. If the characters of X and Y match (i.e., `X[i-1] == Y[j-1]`), then: - $$ - dp[i][j] = dp[i-1][j-1] + 1 - $$ -2. If the characters do not match, we take the maximum value from either ignoring the current character from X or Y: - $$ - dp[i][j] = \max(dp[i-1][j], dp[i][j-1]) - $$ - -### Base Case - -- If either string is empty, then `dp[i][0] = 0` and `dp[0][j] = 0` since there can be no common subsequence. - -## Code Implementation in C++ - -Here’s a C++ implementation of the LCS problem: - -```cpp -#include -#include -#include - -using namespace std; - -int lcs(string X, string Y) { - int m = X.length(); - int n = Y.length(); - - // Create a 2D dp table to store lengths of LCS - vector> dp(m + 1, vector(n + 1, 0)); - - // Fill dp table in bottom-up manner - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (X[i - 1] == Y[j - 1]) { - dp[i][j] = dp[i - 1][j - 1] + 1; // Characters match - } else { - dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); // Characters do not match - } - } - } - - // The length of LCS is found at dp[m][n] - return dp[m][n]; -} - -int main() { - string X = "ABCBDAB"; - string Y = "BDCAB"; - cout << "Length of LCS: " << lcs(X, Y) << endl; // Output: 4 - - // Additional test cases - string X1 = "AGGTAB"; - string Y1 = "GXTXAYB"; - cout << "Length of LCS (AGGTAB, GXTXAYB): " << lcs(X1, Y1) << endl; // Output: 4 - - string X2 = "AA"; - string Y2 = "AB"; - cout << "Length of LCS (AA, AB): " << lcs(X2, Y2) << endl; // Output: 1 - - string X3 = "ABC"; - string Y3 = "DEF"; - cout << "Length of LCS (ABC, DEF): " << lcs(X3, Y3) << endl; // Output: 0 - - string X4 = "AAB"; - string Y4 = "AAAB"; - cout << "Length of LCS (AAB, AAAB): " << lcs(X4, Y4) << endl; // Output: 2 - - return 0; -} -``` -## Explanation of the Code - -1. **Initial Setup:** - - - We first determine the lengths of the input strings X and Y using `length()`. - - We create a 2D vector `dp` of size `(m + 1) x (n + 1)`, initializing all elements to 0. -2. **Filling the Table:** - - - We iterate through each character of both strings X and Y using nested loops. - - If `X[i - 1]` is equal to `Y[j - 1]`, we set `dp[i][j]` to `dp[i - 1][j - 1] + 1`, indicating that we've found a matching character. - - If the characters do not match, we set `dp[i][j]` to the maximum of the values from the cell above (`dp[i - 1][j]`) and the cell to the left (`dp[i][j - 1]`). -3. **Returning the Result:** - - - Once the table is completely filled, the value at `dp[m][n]` contains the length of the longest common subsequence. - - - -## Time and Space Complexity - -- **Time Complexity:** The time complexity is $O(m \times n)$ because we fill up a table of size `(m + 1) x (n + 1)` in nested loops. -- **Space Complexity:** The space complexity is also $O(m \times n)$ due to the 2D table used for storing intermediate results. - -## Conclusion - -The Longest Common Subsequence (LCS) is a key problem in dynamic programming with various applications, including file comparison and DNA sequence analysis. The approach described here utilizes a 2D table to efficiently solve the problem, allowing for easy retrieval of the LCS length. \ No newline at end of file diff --git a/docs/dynamic-programming/minimum_flips_to_zero_matrix.md b/docs/dynamic-programming/minimum_flips_to_zero_matrix.md deleted file mode 100644 index 78114897f..000000000 --- a/docs/dynamic-programming/minimum_flips_to_zero_matrix.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -id: min-flips-binary-matrix -title: Minimum Number of Flips to Convert Binary Matrix to Zero Matrix -sidebar_label: Minimum Flips Binary Matrix -tags: [Binary Matrix, Dynamic Programming, Matrix Manipulation, DSA] -description: Given a binary matrix, determine the minimum number of flips required to convert the matrix to all zeroes by flipping any single cell, row, or column. ---- - -# Minimum Number of Flips to Convert Binary Matrix to Zero Matrix - -## Description -Given a binary matrix, the goal is to find the minimum number of flips required to convert the entire matrix to zeroes. You can flip any single cell or any row/column. - -## Problem Definition -- **Input**: A binary matrix `matrix`. -- **Output**: Return the minimum number of flips required to convert the matrix to all zeroes. - -## Example -- **Input**: - - `matrix = [[0,0,1],[1,0,0],[0,1,0]]` - -- **Output**: - - `3` (flip the first row, second column, and third column). - -## Algorithm Overview -1. Iterate through the matrix and for each cell, determine if it contributes to the overall count of flips. -2. Use dynamic programming to keep track of flips needed for each row and column. -3. Return the total number of flips required. - -## Time Complexity -- O(m*n) - where `m` is the number of rows and `n` is the number of columns in the matrix. - -## C++ Implementation - -```cpp -#include -#include -using namespace std; - -int minFlipsToZeroMatrix(vector>& matrix) { - int m = matrix.size(); - int n = matrix[0].size(); - int flips = 0; - - // Count the number of 1's in the matrix - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - flips += matrix[i][j]; - } - } - - // The number of flips required is equal to the number of 1's - return flips; -} - -int main() { - vector> matrix = {{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}; - cout << "Minimum flips required: " << minFlipsToZeroMatrix(matrix) << endl; - return 0; -} -``` \ No newline at end of file diff --git a/docs/dynamic-programming/palindrome_partitioning_IV.md b/docs/dynamic-programming/palindrome_partitioning_IV.md deleted file mode 100644 index 1bd23bca9..000000000 --- a/docs/dynamic-programming/palindrome_partitioning_IV.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -id: palindrome-partitioning-iv -title: Palindrome Partitioning IV -sidebar_label: Palindrome Partitioning IV -tags: [Palindrome, String Manipulation, Dynamic Programming, DSA] -description: Determine if a string can be partitioned into palindromic substrings with at most k changes. ---- - -# Palindrome Partitioning IV - -### Description -The problem is to determine if a given string can be partitioned into substrings such that every substring is a palindrome, and you are allowed to perform at most `k` changes to the characters of the string. - -### Problem Definition -- **Input**: A string `s` and an integer `k`. -- **Output**: Return `true` if the string can be partitioned into palindromes with at most `k` changes; otherwise, return `false`. - -### Example -- **Input**: - - `s = "abc"`, `k = 1` - -- **Output**: - - `true` (the substring "a" can remain as is, and "b" can be changed to "c" to form "aca"). - -### Algorithm Overview -1. Use a two-pointer approach to check for palindromes. -2. Count the number of characters that need to be changed for each substring to make it a palindrome. -3. If the total changes exceed `k`, return false; otherwise, return true. - -### Time Complexity -- O(n^2) - where `n` is the length of the string. - -### C++ Implementation - -```cpp -#include -#include -using namespace std; - -bool isPalindrome(string& s, int left, int right) { - while (left < right) { - if (s[left++] != s[right--]) return false; - } - return true; -} - -bool canPartitionWithKChanges(string s, int k) { - int n = s.size(); - vector> dp(n + 1, vector(k + 1, INT_MAX)); - dp[0][0] = 0; - - for (int i = 1; i <= n; i++) { - for (int j = 0; j < i; j++) { - if (isPalindrome(s, j, i - 1)) { - for (int changes = 0; changes <= k; changes++) { - dp[i][changes] = min(dp[i][changes], dp[j][changes]); - } - } - } - for (int changes = 1; changes <= k; changes++) { - dp[i][changes] = min(dp[i][changes], dp[i - 1][changes - 1] + 1); - } - } - - return dp[n][k] <= k; -} - -int main() { - string s = "abc"; - int k = 1; - cout << (canPartitionWithKChanges(s, k) ? "True" : "False") << endl; - return 0; -} -``` \ No newline at end of file diff --git a/docs/dynamic-programming/practice-problems-different-patterns.md b/docs/dynamic-programming/practice-problems-different-patterns.md deleted file mode 100644 index a942c5fb2..000000000 --- a/docs/dynamic-programming/practice-problems-different-patterns.md +++ /dev/null @@ -1,61 +0,0 @@ -### Linear DP - -- [Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) -- [Climbing Stairs II](https://www.geeksforgeeks.org/problems/geek-jump/1) -- [House robber](https://leetcode.com/problems/house-robber/) -- [Coin Change](https://leetcode.com/problems/coin-change/) -- [Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) -- [Word Break](https://leetcode.com/problems/word-break/) -- [Frog Jump with K distance](https://www.geeksforgeeks.org/problems/minimal-cost/1) - -### String DP - -- [Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) -- [Longest Common Substring](https://www.geeksforgeeks.org/problems/longest-common-substring1452/1) -- [Longest Palindromic Subsequence](https://leetcode.com/problems/longest-palindromic-subsequence/) -- [Minimum Insertion Steps to Make a String Palindrome](https://leetcode.com/problems/minimum-insertion-steps-to-make-a-string-palindrome/) -- [Palindromic Partitioning](https://leetcode.com/problems/palindrome-partitioning/) -- [Wildcard Matching](https://leetcode.com/problems/wildcard-matching/) - -### Knapsack based DP - -- [Target Sum](https://leetcode.com/problems/target-sum/) -- [House Robber II](https://leetcode.com/problems/house-robber-ii/) -- [0/1 Knapsack Problem](https://leetcode.com/problems/0-1-knapsack-problem/) -- [Knapsack with Duplicate Items](https://www.geeksforgeeks.org/problems/knapsack-with-duplicate-items4201/1) -- [Coin Change II](https://leetcode.com/problems/coin-change-ii/) -- [Minimum Subset Sum Difference](https://leetcode.com/problems/minimum-subset-sum-difference/) - -### Grid based DP - -- [Unique Paths](https://leetcode.com/problems/unique-paths/) -- [Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) -- [Coin Path](https://leetcode.com/problems/coin-path/) -- [Number of Islands](https://leetcode.com/problems/number-of-islands/) -- [Word Search](https://leetcode.com/problems/word-search/) -- [Longest Increasing Path in a Matrix](https://leetcode.com/problems/longest-increasing-path-in-a-matrix/) -- [Best Time to Buy and Sell Stock III](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) -- [2D DP - Frog Jump](https://leetcode.com/problems/frog-jump/) -- [2D DP - Russian Doll Envelopes](https://leetcode.com/problems/russian-doll-envelopes/description/) -- [2D DP - Egg Dropping Puzzle](https://www.geeksforgeeks.org/problems/egg-dropping-puzzle-1587115620/1) - -### DP on Subsequence Problems - -- [Assign Cookies](https://leetcode.com/problems/assign-cookies/) -- [Subset Sum Equal to Target](https://www.geeksforgeeks.org/problems/subset-sum-problem-1611555638/1) -- [Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/) -- [Partition Set Into 2 Subsets With Min Absolute Sum Diff](https://leetcode.com/problems/partition-array-into-two-arrays-to-minimize-sum-difference/) -- [Count Subsets with Sum K](https://www.geeksforgeeks.org/problems/perfect-sum-problem5633/1) -- [Rod cutting](https://www.geeksforgeeks.org/problems/rod-cutting0840/1) - -### DP on intervals(Partition DP) - -- [Matrix Chain Multiplication](https://www.geeksforgeeks.org/problems/matrix-chain-multiplication0303/1) -- [Minimum Cost to Cut Stick](https://leetcode.com/problems/minimum-cost-to-cut-a-stick/) -- [Burst Balloons](https://leetcode.com/problems/burst-balloons/) -- [Palindrome Partitioning II](https://leetcode.com/problems/palindrome-partitioning-ii/) -- [Largest Divisible Subset](https://leetcode.com/problems/largest-divisible-subset/) -- [Parse a Boolean Expression Represented as String](https://leetcode.com/problems/parsing-a-boolean-expression/) -- [Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) -- [Partition array for maximum sum](https://leetcode.com/problems/partition-array-for-maximum-sum/) -- [Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) diff --git a/docs/dynamic-programming/trapped-rainwater.md b/docs/dynamic-programming/trapped-rainwater.md deleted file mode 100644 index cdedb7d16..000000000 --- a/docs/dynamic-programming/trapped-rainwater.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: trapped-rainwater -title: Trapped Rainwater -sidebar_label: Trapped Rainwater -description: "In this post, we'll explore a solution to the Trapped Rainwater problem, calculating how much rainwater can be held within a terrain represented by an elevation map using a dynamic programming approach." -tags: [dsa, algorithms, dynamic programming, rainwater, arrays] ---- - -### Definition: -The **Trapped Rainwater problem** involves finding the amount of water that can be trapped after rainfall between bars of different heights, represented by an array. Each bar's width is assumed to be 1, and rainwater is trapped in the valleys between bars. - -### Characteristics: -- **Dynamic Programming**: - - This solution uses dynamic programming to calculate the maximum heights to the left and right of each bar, allowing us to determine the trapped water efficiently. - -- **Height Arrays**: - - Two arrays are used to store the left and right maximum heights up to each bar, helping to find the trapped water at each position by calculating the minimum of these heights minus the bar's height. - -- **Efficient Calculation**: - - The algorithm runs in **O(N)** time complexity and uses **O(N)** additional space for the left and right maximum arrays, making it efficient for large input sizes. - -### Python Implementation: -```python - -""" -Calculate the total amount of rainwater that can be trapped given an elevation map. -Example: heights = (0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1), Output: 6 -""" - -def trapped_rainwater(heights: tuple[int, ...]) -> int: - """ - Calculates the total rainwater that can be trapped above the bars. - Uses a dynamic programming approach with left and right max heights. - - >>> trapped_rainwater((0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1)) - 6 - >>> trapped_rainwater((7, 1, 5, 3, 6, 4)) - 9 - >>> trapped_rainwater((7, 1, 5, 3, 6, -1)) - Traceback (most recent call last): - ... - ValueError: No height can be negative - """ - if not heights: - return 0 - if any(h < 0 for h in heights): - raise ValueError("No height can be negative") - - length = len(heights) - - # Calculate left max heights - left_max = [0] * length - left_max[0] = heights[0] - for i in range(1, length): - left_max[i] = max(heights[i], left_max[i - 1]) - - # Calculate right max heights - right_max = [0] * length - right_max[-1] = heights[-1] - for i in range(length - 2, -1, -1): - right_max[i] = max(heights[i], right_max[i + 1]) - - # Calculate trapped water - return sum( - min(left, right) - height - for left, right, height in zip(left_max, right_max, heights) - ) - - -if __name__ == "__main__": - import doctest - - doctest.testmod() - print(f"{trapped_rainwater((0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1)) = }") - print(f"{trapped_rainwater((7, 1, 5, 3, 6, 4)) = }") - -``` - -### Time Complexity: -- **Time Complexity: O(N)** -The algorithm iterates through the heights array twice to fill the left and right maximum arrays and then once more to calculate the trapped water. -### Space Complexity: -- **Space Complexity: O(N)** -The space complexity is O(N) due to the additional arrays storing the left and right maximum heights for each bar. - -### Summary: -The Trapped Rainwater solution efficiently calculates the amount of water that can be trapped between bars using dynamic programming. By precomputing the maximum heights on both sides for each bar, the algorithm quickly determines the trapped water at each position. This approach is optimal for large data sets and commonly used in data structure and algorithm problems. diff --git a/docs/fundamentals/Conditional Statement.md b/docs/fundamentals/Conditional Statement.md deleted file mode 100644 index 43927dc85..000000000 --- a/docs/fundamentals/Conditional Statement.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -id: coditional-statement -title: Coditional Statement -sidebar_label: Coditional Statement -description: "This blog post explains various types of Coditional Statement used in programming with examples in C++." -tags: [programming, Coditional Statement, conditions, c++] ---- -# Conditional Statements - -Conditional statements allow a program to make decisions based on certain conditions. They help control the flow of execution by executing different blocks of code depending on whether a condition is true or false. - ---- - -## Types of Conditional Statements - -### 1. **if Statement** -The `if` statement executes a block of code if the specified condition evaluates to `true`. - -**Syntax:** -```cpp -if (condition) { - // Code to execute if condition is true -} -``` -**Example:** -``` -int age = 18; -if (age >= 18) { - cout << "You are eligible to vote." << endl; -} -``` - -### 2. **if-else Statement** -The `if-else` statement provides an alternative block of code to execute if the condition is `false`. - -**Syntax:** -```cpp -if (condition) { - // Code to execute if condition is true -} else { - // Code to execute if condition is false -} - -``` -**Example:** -``` -int age = 16; -if (age >= 18) { - cout << "You are eligible to vote." << endl; -} else { - cout << "You are not eligible to vote." << endl; -} - -``` - -### 3. **if-else if-else Ladder** -This structure allows you to test multiple conditions sequentially. The first `true` condition will be executed. - - -**Syntax:** -```cpp -if (condition1) { - // Code for condition1 -} else if (condition2) { - // Code for condition2 -} else { - // Code if none of the conditions are true -} - -``` -**Example:** -``` -int marks = 75; -if (marks >= 90) { - cout << "Grade: A" << endl; -} else if (marks >= 75) { - cout << "Grade: B" << endl; -} else { - cout << "Grade: C" << endl; -} -``` - - -### 4. **Nested if Statement** -An `if` statement inside another `if` statement. This is useful for checking multiple related conditions. - - -**Syntax:** -```cpp -if (condition1) { - if (condition2) { - // Code if both conditions are true - } -} - -``` -**Example:** -``` -int age = 20; -bool hasID = true; -if (age >= 18) { - if (hasID) { - cout << "You are allowed entry." << endl; - } -} - -``` -### 5. **switch Statement** -The `switch` statement is used when you have multiple conditions based on a single variable. - -**Syntax:** -```cpp -switch (expression) { - case value1: - // Code for value1 - break; - case value2: - // Code for value2 - break; - default: - // Code if no case matches -} - -``` -**Example:** -``` -int day = 3; -switch (day) { - case 1: - cout << "Monday" << endl; - break; - case 2: - cout << "Tuesday" << endl; - break; - case 3: - cout << "Wednesday" << endl; - break; - default: - cout << "Invalid day" << endl; -} - -``` - -## When to Use Each Conditional Statement - -- **if Statement:** When you need to check a single condition. -- **if-else Statement:** When there are two possibilities (true/false). -- **if-else if-else Ladder:** When there are multiple conditions to evaluate sequentially. -- **Nested if:** When conditions depend on each other. -- **switch Statement:** When you have multiple values for a single variable. - ---- - -## Conclusion - -Conditional statements are essential for controlling the flow of a program. Understanding when and how to use each type of conditional statement is crucial for writing efficient and logical code. diff --git a/docs/fundamentals/Functions/Function Call.md b/docs/fundamentals/Functions/Function Call.md deleted file mode 100644 index 33be1c026..000000000 --- a/docs/fundamentals/Functions/Function Call.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -id: function-call -title: Function Call -sidebar_label: Function Call -sidebar_position: 2 -description: Learn how to invoke functions in various programming languages. -tags: [functions, programming, programming fundamental, syntax] ---- - - -## Overview -A **function call** is the process of invoking a function in a program. When a function is called, the control of the program is passed to the function, its statements are executed, and the result (if any) is returned to the calling location. Function calls are an essential part of modular programming, allowing the reuse of code blocks across various parts of the program. - - -## Syntax -### C++ -```c++ -// Function call -function_name(argument1, argument2, ...); -``` - -## Example -### C++ Example -```c++ -// Function declaration -int add(int a, int b); - -// Function call -int result = add(3, 5); // Calls the 'add' function with arguments 3 and 5 -``` - -```c++ -// Definition -int add(int a, int b) { - return a + b; -} -``` - - -## Syntax -### Python -Python does not separate function declarations from function definitions. The function is defined and declared in one step. - -```py -# Function definition (Python inherently defines and declares in one step) -def function_name(parameter1, parameter2): - # function body -``` - -## Example -### Python Example -```py -# Function definition -def add(a, b): - return a + b - -# Function call -result = add(3, 5) # Calls the 'add' function with arguments 3 and 5 -``` - - -## Key Points: -1. Function calls transfer control from the calling point to the function, where its logic is executed. -2. In a function call, arguments are passed to the function to be processed as parameters. -3. In languages like C++ and Python, the return value of the function (if any) can be stored in a variable or used directly in an expression. -4. Function calls can be made within other function calls or expressions to build more complex logic. -5. Recursive function calls occur when a function calls itself, enabling the solution of problems that can be broken down into simpler subproblems. - - diff --git a/docs/fundamentals/Functions/Function Closures.md b/docs/fundamentals/Functions/Function Closures.md deleted file mode 100644 index f0659b0d0..000000000 --- a/docs/fundamentals/Functions/Function Closures.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -id: function-closures -title: Function Closures -sidebar_label: Function Closures -sidebar_position: 8 -description: Understand the concept of closures in programming and their usage. -tags: [functions, fundamental, programming fundamentals, closures] ---- - -## Overview -**Function closures** are a powerful feature in many programming languages that allow a function to retain access to its lexical scope, even when the function is executed outside that scope. This means a closure can remember the environment in which it was created, enabling it to access variables that are no longer in the current scope. Closures are commonly used for data encapsulation, callback functions, and maintaining state in asynchronous programming. - -## Syntax -### JavaScript -```javascript -// Closure Syntax Example -function outerFunction() { - let outerVariable = 'I am from outer scope'; - - function innerFunction() { - console.log(outerVariable); // Accessing the outer variable - } - - return innerFunction; // Returning the inner function -} - -``` - -## Example -### JavaScript Example -```JavaScript -// Using Closure in JavaScript -function createCounter() { - let count = 0; // Private variable - - return function() { - count += 1; // Incrementing the count - return count; // Returning the current count - }; -} - -const counter = createCounter(); -console.log(counter()); // Output: 1 -console.log(counter()); // Output: 2 - -``` - - - -## Syntax -### Python -```py -# Closure Syntax Example -def outer_function(): - outer_variable = 'I am from outer scope' - - def inner_function(): - print(outer_variable) # Accessing the outer variable - - return inner_function # Returning the inner function - -``` - -## Example -### Python Example -```py -# Using Closure in Python -def create_counter(): - count = 0 # Private variable - - def counter(): - nonlocal count # Accessing the outer variable - count += 1 - return count # Returning the current count - - return counter # Returning the inner function - -counter = create_counter() -print(counter()) # Output: 1 -print(counter()) # Output: 2 - -``` - - -## Key Points: -1. Lexical Scope: Closures allow a function to access variables from its lexical scope, even when invoked outside that scope. -2. Data Encapsulation: Closures can be used to create private variables, encapsulating the state of the function. -3. Memory Management: Closures maintain references to the variables in the scope they were created in, which can lead to increased memory usage if not managed properly. -4. Use in Callbacks: Closures are commonly used in asynchronous programming and callbacks, allowing functions to maintain state between calls. -5. Non-local Variables: In languages like Python, the nonlocal keyword is used to declare that a variable refers to a variable in the nearest enclosing scope that is not global. - diff --git a/docs/fundamentals/Functions/Function Composition.md b/docs/fundamentals/Functions/Function Composition.md deleted file mode 100644 index 65c4e7d59..000000000 --- a/docs/fundamentals/Functions/Function Composition.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: function-composition -title: Function Composition -sidebar_label: Function Composition -sidebar_position: 10 -description: Learn about function composition and how to combine multiple functions into one in C++ and Python. -tags: [functions, fundamental, programming fundamentals, composition, c++, python] ---- - -## Overview -**Function composition** is a programming technique where two or more functions are combined to create a new function. This new function takes the output of one function as the input for another, allowing for more complex operations to be constructed from simpler ones. Function composition enhances modularity, reusability, and readability of code. - -## Syntax -### C++ -```cpp -#include -#include - -// Function Composition Syntax Example -template -std::function compose(std::function f, std::function g) { - return [=](T x) { - return f(g(x)); - }; -} - -``` - -## Example -### C++ Example -```c++ -#include -#include - -// Function to double a number -int doubleValue(int x) { - return x * 2; -} - -// Function to increment a number -int increment(int x) { - return x + 1; -} - -// Function to compose two functions -template -std::function compose(std::function f, std::function g) { - return [=](T x) { - return f(g(x)); - }; -} - -int main() { - auto composedFunction = compose(doubleValue, increment); - std::cout << composedFunction(3) << std::endl; // Output: 8 - return 0; -} - - -``` - - - -## Syntax -### Python -```py -# Function Composition Syntax Example -def compose(f, g): - return lambda x: f(g(x)) - -``` - -## Example -### Python Example -```py -# Function to double a number -def double(x): - return x * 2 - -# Function to increment a number -def increment(x): - return x + 1 - -# Composing the functions -increment_and_double = compose(double, increment) - -# Using the composed function -result = increment_and_double(3) -print(result) # Output: 8 - - -``` - - -## Key Points: -1. Combining Functions: Function composition allows for the creation of new functions by combining existing ones, which enhances reusability and modularity. -2. Order of Execution: The order in which functions are composed is significant; the output of the inner function becomes the input for the outer function. -3. Higher-Order Functions: Function composition typically involves higher-order functions, which take other functions as arguments or return them. -4. Functional Programming: This technique is a key aspect of functional programming paradigms, emphasizing immutability and pure functions. -5. Improved Code Clarity: By breaking down complex logic into smaller, composable functions, the overall clarity and maintainability of the code are improved. - - diff --git a/docs/fundamentals/Functions/Function Currying.md b/docs/fundamentals/Functions/Function Currying.md deleted file mode 100644 index 850a9d871..000000000 --- a/docs/fundamentals/Functions/Function Currying.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -id: function-currying -title: Function Currying -sidebar_label: Function Currying -sidebar_position: 9 -description: Learn about function currying and how it enables the transformation of functions for better modularity and reusability. -tags: [functions, fundamental, programming fundamentals, currying] ---- - -## Overview -**Function currying** is a technique in functional programming where a function with multiple arguments is transformed into a sequence of functions, each taking a single argument. This approach allows partial application of functions, making them more modular and reusable. Currying helps in creating specialized functions by fixing some of the parameters of a function, leading to more expressive and concise code. - -## Syntax -### JavaScript -```javascript -// Currying Syntax Example -function add(a) { - return function(b) { - return a + b; - }; -} - -``` - -## Example -### JavaScript Example -```JavaScript -// Using Currying in JavaScript -function multiply(x) { - return function(y) { - return x * y; - }; -} - -const multiplyByTwo = multiply(2); -console.log(multiplyByTwo(5)); // Output: 10 - - -``` - - - -## Syntax -### Python -```py -# Currying Syntax Example -def add(a): - def inner(b): - return a + b - return inner - -``` - -## Example -### Python Example -```py -# Using Currying in Python -def multiply(x): - def inner(y): - return x * y - return inner - -multiply_by_three = multiply(3) -print(multiply_by_three(4)) # Output: 12 - -``` - -## C++ -Function currying is not a built-in feature of C++, as it is in some functional programming languages like JavaScript or Python. However, you can achieve a similar effect using function objects or lambda expressions. - -## Key Points: -1. Partial Application: Currying allows you to fix a number of arguments and create a new function that takes the remaining arguments. -2. Higher-Order Functions: Currying transforms a function into a higher-order function, enabling the creation of more flexible and reusable code. -3. Enhanced Readability: By breaking down functions into smaller, single-argument functions, currying can improve the readability and maintainability of code. -4. Functional Composition: Currying facilitates functional composition, allowing functions to be easily combined and reused. -5. Compatibility: Currying is a common practice in languages that support first-class functions, such as JavaScript and Python, but can also be implemented in other languages. - diff --git a/docs/fundamentals/Functions/Function Declaration.md b/docs/fundamentals/Functions/Function Declaration.md deleted file mode 100644 index 46aa04d0f..000000000 --- a/docs/fundamentals/Functions/Function Declaration.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -id: function-declaration -title: Function Declaration -sidebar_label: Function Declaration -sidebar_position: 1 -description: Learn about how functions are declared in various programming languages. -tags: [functions, fundamental, programming fundamentals, syntax] ---- - -## Overview -A **function declaration** introduces the function to the program, specifying its **name**, **return type**, and **parameters** without including the function body. This is different from the **function definition**, which also includes the function’s logic (body). Function declarations are typically used in languages where the compiler needs to know about a function before it's called in the code. - -## Syntax -### C++ -```c++ -// Function declaration (without body) -return_type function_name(parameter1_type parameter1, parameter2_type parameter2); -``` - - -## Example -### C++ Example -```c++ -// Declaration -int add(int a, int b); -``` - -```c++ -// Definition -int add(int a, int b) { - return a + b; -} -``` - - - -## Syntax -### Python -// Python does not separate function declarations from function definitions. The function is defined and declared in one step. - -```py -// Function definition (Python inherently defines and declares in one step) -def function_name(parameter1, parameter2): - # function body -``` - -## Example -### Python Example -```py -// In Python, declaration and definition occur together -def add(a, b): - return a + b -``` - -## Key Points: -1. Function declaration tells the compiler or interpreter about the function's name, parameters, and return type, without implementing the function body. -2. In languages like C++, function declarations allow function prototypes to be written in one place, while the actual implementation can be defined later. -3. Function definition includes the function body and specifies what the function does. -4. In some languages (like Python), there's no need to declare a function separately from its definition. -5. Declarations are often written in header files (C++) or at the beginning of the program before any function calls. - - diff --git a/docs/fundamentals/Functions/Function Memoization.md b/docs/fundamentals/Functions/Function Memoization.md deleted file mode 100644 index e94515410..000000000 --- a/docs/fundamentals/Functions/Function Memoization.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: function-memoization -title: Function Memoization -sidebar_label: Function Memoization -sidebar_position: 11 -description: Learn about function memoization, a technique to optimize performance by caching results of expensive function calls. -tags: [functions, fundamental, programming fundamentals, optimization, caching] ---- - -## Overview -**Function memoization** is an optimization technique used to improve the performance of functions by storing the results of expensive function calls and returning the cached result when the same inputs occur again. This technique is particularly useful in scenarios involving recursive functions or functions that perform expensive computations. - -## Syntax -### C++ -```cpp -#include -#include - -// Memoization Syntax Example -std::unordered_map cache; - -int fibonacci(int n) { - if (n <= 1) return n; - if (cache.find(n) != cache.end()) return cache[n]; // Check cache - cache[n] = fibonacci(n - 1) + fibonacci(n - 2); // Store result - return cache[n]; -} - -``` - -## Example -### C++ Example -```c++ -#include -#include - -std::unordered_map cache; - -int fibonacci(int n) { - if (n <= 1) return n; - if (cache.find(n) != cache.end()) return cache[n]; // Check cache - cache[n] = fibonacci(n - 1) + fibonacci(n - 2); // Store result - return cache[n]; -} - -int main() { - std::cout << "Fibonacci of 10: " << fibonacci(10) << std::endl; // Output: 55 - return 0; -} - - -``` - - - -## Syntax -### Python -```py -# Memoization Syntax Example -cache = {} - -def fibonacci(n): - if n <= 1: - return n - if n in cache: # Check cache - return cache[n] - cache[n] = fibonacci(n - 1) + fibonacci(n - 2) # Store result - return cache[n] - - -``` - -## Example -### Python Example -```py -cache = {} - -def fibonacci(n): - if n <= 1: - return n - if n in cache: # Check cache - return cache[n] - cache[n] = fibonacci(n - 1) + fibonacci(n - 2) # Store result - return cache[n] - -result = fibonacci(10) -print("Fibonacci of 10:", result) # Output: 55 - - -``` - - -## Key Points: -1. Performance Improvement: Memoization significantly improves performance by reducing the number of function calls and avoiding redundant calculations. -2. Cache Utilization: The results of function calls are stored in a cache (often a dictionary or hash map) for quick retrieval. -3. Recursive Functions: Memoization is particularly effective with recursive functions, such as calculating Fibonacci numbers, where many calls with the same inputs can occur. -4. Trade-off: While memoization can improve time complexity, it may increase space complexity due to the storage of results. -5. Dynamic Programming: Memoization is often a key component in dynamic programming approaches, where overlapping subproblems are solved efficiently. diff --git a/docs/fundamentals/Functions/Function Overloading.md b/docs/fundamentals/Functions/Function Overloading.md deleted file mode 100644 index c8eb83d8b..000000000 --- a/docs/fundamentals/Functions/Function Overloading.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: function-overloading -title: Function Overloading -sidebar_label: Function Overloading -sidebar_position: 6 -description: Understand the concept of function overloading in various programming languages. -tags: [functions, fundamental, programming fundamentals, overloading] ---- - -## Overview -**Function overloading** is a feature in many programming languages that allows multiple functions to have the same name but different parameter lists (types, number, or both). This enables functions to perform similar operations on different types of data, enhancing code readability and reusability. - -## Syntax -### C++ -```c++ -// Function Overloading Example -void display(int value); -void display(double value); -void display(string value); - -``` - -## Example -### C++ Example -```c++ -// Function Overloading in C++ -#include -using namespace std; - -// Function declarations -void display(int value) { - cout << "Integer: " << value << endl; -} - -void display(double value) { - cout << "Double: " << value << endl; -} - -void display(string value) { - cout << "String: " << value << endl; -} - -int main() { - display(10); // Calls display(int) - display(10.5); // Calls display(double) - display("Hello"); // Calls display(string) - return 0; -} - - -``` - - - -## Syntax -### Python -```py -# Python does not support function overloading directly, -# but you can use default arguments or variable-length arguments. - -def display(value): - print(value) - -``` - -## Example -### Python Example -```py -# Function Overloading in Python -def display(value): - print(value) - -display(10) # Calls display -display(10.5) # Calls display -display("Hello") # Calls display - - -``` - - -## Key Points: -1. Function Signature: Overloading is determined by the function signature, which includes the function name and the type and number of its parameters. -2. Compile-Time Polymorphism: Function overloading is a form of compile-time polymorphism, allowing the correct function to be called based on the arguments passed. -3. Default Parameters: In languages like Python, function overloading can be mimicked using default arguments or variable-length argument lists. -4. Readability: Function overloading enhances code readability by allowing functions that perform similar tasks to share the same name, reducing the need for different names for similar operations. -5. Limitations: Overloading is based on parameter types and counts; two functions with the same name and parameters will result in a compilation error. - diff --git a/docs/fundamentals/Functions/Function Parameters.md b/docs/fundamentals/Functions/Function Parameters.md deleted file mode 100644 index a3ee97cef..000000000 --- a/docs/fundamentals/Functions/Function Parameters.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -id: function-parameters -title: Function Parameters -sidebar_label: Function Parameters -sidebar_position: 3 -description: Learn about how function parameters work in various programming languages. -tags: [functions, fundamentals, programming fundamentals, parameters] ---- - -## Overview -**Function parameters** are variables listed in the function declaration that allow the function to accept input values when it is called. These inputs are called **arguments**, and they are passed to the function during the function call. Parameters help make functions more flexible and reusable by allowing different inputs to be processed without changing the function's code. - -## Syntax -### C++ -```c++ -// Function with parameters -return_type function_name(parameter1_type parameter1, parameter2_type parameter2); -``` - -## Example -### C++ Example -```c++ -// Function declaration with parameters -int add(int a, int b); - -// Function definition -int add(int a, int b) { - return a + b; -} - -// Function call with arguments -int result = add(10, 20); // Calls 'add' with arguments 10 and 20 - -``` - - - -## Syntax -### Python -```py -# Function with parameters -def function_name(parameter1, parameter2): - # function body - -``` - -## Example -### Python Example -```py -# Function definition with parameters -def add(a, b): - return a + b - -# Function call with arguments -result = add(10, 20) # Calls 'add' with arguments 10 and 20 - -``` - - -## Key Points: -1. Parameters are placeholders defined in the function declaration that allow it to accept input values (arguments) during function calls. -2. In C++, each parameter must have a type specified, while Python allows for dynamic typing. -3. Functions can have multiple parameters, separated by commas, to accept multiple inputs. -4. In some languages, like Python, parameters can have default values that are used if no argument is provided for that parameter during the function call. -5. Parameters increase the flexibility of functions by allowing the same function to handle a variety of inputs without modifying its code. - - diff --git a/docs/fundamentals/Functions/Function Recursion.md b/docs/fundamentals/Functions/Function Recursion.md deleted file mode 100644 index d338f51f8..000000000 --- a/docs/fundamentals/Functions/Function Recursion.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -id: function-recursion -title: Function Recursion -sidebar_label: Function Recursion -sidebar_position: 7 -description: Understand the concept of recursion in programming functions. -tags: [functions, fundamental, programming fundamentals, function-recursion] ---- - -## Overview -**Function recursion** is a programming technique where a function calls itself to solve a problem. This approach is useful for breaking down complex problems into simpler sub-problems. Each recursive call processes a portion of the problem until a base condition is met, at which point the recursion stops. - -## Syntax -### C++ -```c++ -// Recursive Function Syntax -return_type function_name(parameters) { - if (base_condition) { - return base_case_value; // Base condition to stop recursion - } - return function_name(modified_parameters); // Recursive call -} - -``` - -## Example -### C++ Example -```c++ -// Factorial using Recursion in C++ -#include -using namespace std; - -int factorial(int n) { - if (n <= 1) { - return 1; // Base condition - } - return n * factorial(n - 1); // Recursive call -} - -int main() { - int number = 5; - cout << "Factorial of " << number << " is " << factorial(number) << endl; // Output: 120 - return 0; -} - -``` - - - -## Syntax -### Python -```py -# Recursive Function Syntax -def function_name(parameters): - if base_condition: - return base_case_value # Base condition to stop recursion - return function_name(modified_parameters) # Recursive call - -``` - -## Example -### Python Example -```py -# Factorial using Recursion in Python -def factorial(n): - if n <= 1: - return 1 # Base condition - return n * factorial(n - 1) # Recursive call - -number = 5 -print(f"Factorial of {number} is {factorial(number)}") # Output: 120 - - -``` - - -## Key Points: -1. Base Condition: Every recursive function must have a base condition to prevent infinite recursion, which leads to stack overflow errors. -2. Recursive Case: The part of the function that includes the recursive call, which breaks the problem into smaller sub-problems. -3. Stack Overflow: Recursion uses the call stack to keep track of function calls; excessive recursion depth can lead to stack overflow. -4. Tail Recursion: A specific type of recursion where the recursive call is the last operation in the function, allowing some languages to optimize it and avoid increasing the call stack. -5. Use Cases: Recursion is commonly used in algorithms that require a divide-and-conquer approach, such as sorting algorithms (e.g., quicksort, mergesort), tree traversals, and combinatorial problems. - diff --git a/docs/fundamentals/Functions/Function Return.md b/docs/fundamentals/Functions/Function Return.md deleted file mode 100644 index f3fa1748a..000000000 --- a/docs/fundamentals/Functions/Function Return.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -id: function-return -title: Function Return -sidebar_label: Function Return -sidebar_position: 4 -description: Learn about how functions return values in various programming languages. -tags: [functions, fundamentals, programming fundamentals, return_values] ---- - -## Overview -A **function return** specifies the value or result that a function sends back to the part of the program that called it. The return value is used to pass a result from the function execution to its caller. If no return value is specified, some languages return a default value (such as `void` in C++ or `None` in Python). - - -## Syntax -### C++ -```c++ -// Function returning a value -return_type function_name(parameter1_type parameter1) { - // function body - return value; -} -``` - -## Example -### C++ Example -```c++ -// Function returning an integer -int add(int a, int b) { - return a + b; -} - -// Function call and storing the return value -int result = add(10, 20); // result is now 30 -``` - - - -## Syntax -### Python -```py -# Function returning a value -def function_name(parameter1): - # function body - return value - -``` - -## Example -### Python Example -```py -# Function returning a value -def add(a, b): - return a + b - -# Function call and storing the return value -result = add(10, 20) # result is now 30 -``` - - - - -## Key Points: -1. Return value is the result that a function sends back to the caller after its execution. -2. In C++, the return type is declared in the function signature (e.g., int for returning integers, void for no return value). -3. Python functions return None if no explicit return statement is provided. -4. The return keyword is used in both C++ and Python to send a value back to the caller. -5. Multiple values can be returned from a function in some languages (e.g., using tuples in Python). - - diff --git a/docs/fundamentals/Functions/Function Scope.md b/docs/fundamentals/Functions/Function Scope.md deleted file mode 100644 index 99de5c079..000000000 --- a/docs/fundamentals/Functions/Function Scope.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -id: function-scope -title: Function Scope -sidebar_label: Function Scope -sidebar_position: 5 -description: Learn about variable scope within functions and how it affects accessibility. -tags: [functions, fundamental, programming fundamentals, scope, variables] ---- - -## Overview -**Function scope** refers to the accessibility or visibility of variables within a function. Variables declared inside a function are **local** to that function, meaning they cannot be accessed outside of it. Similarly, variables outside the function are generally **global** and can be accessed by the function depending on the language's scope rules. - -## Syntax -### C++ -```c++ -// Local scope example -void function_name() { - int local_variable = 10; // This variable is only accessible inside the function -} - -``` - -## Example -### C++ Example -```c++ -// Global and local scope -int global_var = 20; - -void display() { - int local_var = 10; - std::cout << "Local Variable: " << local_var << std::endl; // Accessible - std::cout << "Global Variable: " << global_var << std::endl; // Accessible -} - -std::cout << local_var; // Error: local_var is not accessible here -``` - - - -## Syntax -### Python -```py -# Local scope example -def function_name(): - local_variable = 10 # This variable is only accessible inside the function - - -``` - -## Example -### Python Example -```py -# Global and local scope -global_var = 20 - -def display(): - local_var = 10 - print(f"Local Variable: {local_var}") # Accessible - print(f"Global Variable: {global_var}") # Accessible - -print(local_var) # Error: local_var is not accessible here - -``` - - - - -## Key Points: -1. Local scope: Variables declared inside a function are only accessible within that function. -2. Global scope: Variables declared outside of all functions are accessible by all functions unless shadowed by a local variable of the same name. -3. Lifetime: Local variables are created when the function is called and destroyed when it exits, whereas global variables exist throughout the program's execution. -4. Nested scopes: Some languages (like Python) support nested function scopes, where inner functions can access variables from outer functions. -5. Scope resolution: In C++, the :: operator allows access to global variables when a local variable shadows a global one. - diff --git a/docs/fundamentals/Loops.md b/docs/fundamentals/Loops.md deleted file mode 100644 index 0eab3ceaf..000000000 --- a/docs/fundamentals/Loops.md +++ /dev/null @@ -1,215 +0,0 @@ ---- -id: loops-in-programming -title: Loops in Programming -sidebar_label: Loops -description: "This blog post explains various types of loops used in programming with examples in C++." -tags: [programming, loops, iteration, c++] ---- - -# Loops in Programming - -In programming, **loops** are used to execute a block of code repeatedly until a specific condition is met. Loops are essential for scenarios where you need to perform repetitive tasks, such as traversing arrays, generating patterns, or processing data structures. - ---- - -## Types of Loops - -### 1. **For Loop** -A `for` loop is used when the number of iterations is known. It consists of three parts: initialization, condition, and increment/decrement. - -#### Syntax: -```cpp -for (initialization; condition; increment/decrement) { - // Code to execute -} -``` -#### Example: -``` -#include -using namespace std; - -int main() { - for (int i = 1; i <= 5; i++) { - cout << "Iteration " << i << endl; - } - return 0; -} -``` -#### Output: -``` -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 -Iteration 5 -``` - -### 2. **While Loop** - -A `while` loop keeps executing as long as the given condition is `true`. It is used when the number of iterations is not known in advance. - -#### Syntax: -``` -while (condition) { - // Code to execute -} -``` -#### Example: -``` -#include -using namespace std; - -int main() { - int i = 1; - while (i <= 5) { - cout << "Iteration " << i << endl; - i++; - } - return 0; -} -``` -#### Output: -``` -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 -Iteration 5 -``` - -### 3. **Do-While Loop** -A `do-while` loop is similar to a `while` loop, but it guarantees that the code inside the loop will run at least once, even if the condition is false initially. - -#### Syntax: -``` -do { - // Code to execute -} while (condition); -``` -#### Example: -``` -#include -using namespace std; - -int main() { - int i = 1; - do { - cout << "Iteration " << i << endl; - i++; - } while (i <= 5); - return 0; -} -``` -#### Output: -``` -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 -Iteration 5 -``` - -### 4. **Nested Loops** -A nested loop is a loop inside another loop. It is commonly used for tasks like generating patterns or processing 2D arrays. - -#### Example: -``` -#include -using namespace std; - -int main() { - for (int i = 1; i <= 3; i++) { - for (int j = 1; j <= 2; j++) { - cout << "i = " << i << ", j = " << j << endl; - } - } - return 0; -} - -``` -#### Output: -``` -i = 1, j = 1 -i = 1, j = 2 -i = 2, j = 1 -i = 2, j = 2 -i = 3, j = 1 -i = 3, j = 2 - -``` - -### 5. **Infinite Loops** -An infinite loop is a loop that runs indefinitely because the condition never becomes false. - -#### Example: -``` -#include -using namespace std; - -int main() { - while (true) { - cout << "This is an infinite loop!" << endl; - break; // Add this to avoid an infinite loop - } - return 0; -} - -``` -#### Output: -``` -i = 1, j = 1 -i = 1, j = 2 -i = 2, j = 1 -i = 2, j = 2 -i = 3, j = 1 -i = 3, j = 2 - -``` - - -## Loop Control Statements - -### 1. **Break Statement** -The break statement is used to exit a loop prematurely. - -#### Example: -``` -for (int i = 1; i <= 10; i++) { - if (i == 5) break; - cout << i << " "; -} -``` -#### Output: -``` -1 2 3 4 -``` - -### 1. **Continue Statement** -The `continue` statement is used to skip the current iteration and move to the next iteration of the loop. - -#### Example: -``` -for (int i = 1; i <= 5; i++) { - if (i == 3) continue; - cout << i << " "; -} -``` -#### Output: -``` -1 2 4 5 -``` - -## Time Complexity -For, While, Do-While Loops: Each iteration typically takes `O(1)` time, so the total time complexity is proportional to the number of iterations, i.e., `O(n)`for `n` iterations. - - -## When to Use Each Loop - -- **For Loop:** When the number of iterations is known beforehand. -- **While Loop:** When the number of iterations is not known and depends on a condition. -- **Do-While Loop:** When you need to ensure the loop runs at least once. - - -## Conclusion - -Loops are a fundamental concept in programming, allowing us to perform repetitive tasks efficiently. Knowing which type of loop to use and how to control it with statements like `break` and `continue` is essential for writing clean, efficient code. diff --git a/docs/game-Theory/gameTheory.md b/docs/game-Theory/gameTheory.md deleted file mode 100644 index bd6f14879..000000000 --- a/docs/game-Theory/gameTheory.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -id: Game-Theory-theory -title: Game theory -sidebar_label: Game Theory -description: "is a mathematical framework used to study decision-making in situations where multiple players interact." -tags: [dsa, algorithms, game theory algorithms] ---- - -# Game Theory - -**Game Theory** is a mathematical framework used to study decision-making in situations where multiple players (or agents) interact. Each player’s outcome depends not only on their own actions but also on the actions of other players. Game theory helps in analyzing strategies and predicting outcomes in competitive situations. - -## Key Concepts - -### 1. **Game** -A game in game theory consists of: -- **Players**: The decision-makers in the game. -- **Strategies**: The available choices or plans of action for each player. -- **Payoffs**: The outcome each player receives based on the combination of chosen strategies by all players. - -### 2. **Types of Games** -- **Cooperative vs Non-cooperative**: - - **Cooperative games**: Players can form alliances or coalitions and negotiate collective strategies. - - **Non-cooperative games**: No collaboration is allowed, and each player acts independently. - -- **Zero-sum vs Non-zero-sum**: - - **Zero-sum games**: The gain of one player is exactly the loss of the other (e.g., chess). - - **Non-zero-sum games**: The total payoff can vary, and one player's gain is not necessarily the other player's loss (e.g., trade negotiations). - -- **Simultaneous vs Sequential**: - - **Simultaneous games**: Players choose their strategies at the same time, without knowing the strategies of other players. - - **Sequential games**: Players take turns choosing their strategies, with each player observing previous moves before making their choice. - -### 3. **Strategy Types** -- **Pure Strategy**: A strategy where a player consistently chooses the same action. -- **Mixed Strategy**: A strategy where a player assigns probabilities to different actions and makes a random choice based on those probabilities. - -### 4. **Nash Equilibrium** -A **Nash Equilibrium** occurs when each player chooses the best possible strategy, given the strategies chosen by the other players. No player has an incentive to change their strategy unilaterally. - -Example: In the **Prisoner's Dilemma**, both players confess because it is the Nash Equilibrium, even though staying silent would have been a better outcome for both if they cooperated. - -### 5. **Dominant Strategy** -A strategy is dominant if it always results in a better outcome for the player, regardless of what the other players do. - -### 6. **Payoff Matrix** -In a **Payoff Matrix**, each player’s payoffs are listed based on the strategies chosen by all players. This is used to visualize outcomes in simultaneous games. - -Example of a **Payoff Matrix** for two players: - -| Player 2 | Strategy A | Strategy B | -|----------|------------|------------| -| **Player 1: Strategy X** | (3, 2) | (1, 1) | -| **Player 1: Strategy Y** | (2, 3) | (4, 4) | - -In this matrix, each cell represents the payoffs for Player 1 and Player 2 for a given combination of strategies. - -### 7. **Minimax Theorem** -In zero-sum games, the **Minimax Theorem** states that players should minimize the possible maximum loss. The idea is to choose a strategy that has the best worst-case outcome. - -### 8. **Examples of Games in Game Theory** - -- **Prisoner’s Dilemma**: A classic example of a non-zero-sum game where rational decision-making leads to a suboptimal outcome. -- **Battle of the Sexes**: A coordination game where two players prefer different outcomes but want to be together. -- **Stag Hunt**: A game that examines trust and collaboration, where two hunters must decide whether to cooperate or hunt alone. - -## Applications of Game Theory -Game theory is widely used in various fields, such as: -- **Economics**: To analyze markets and strategic interactions between firms. -- **Political Science**: For understanding conflicts, elections, and voting behavior. -- **Computer Science**: In algorithms, AI, and network design. -- **Biology**: In studying evolutionary strategies and animal behavior. - -## Conclusion -Game theory provides a powerful framework to analyze situations where individuals or groups make decisions that affect each other. It helps in finding optimal strategies and predicting the outcomes of complex interactions in competitive environments. diff --git a/docs/game-Theory/gameTheoryExamples.md b/docs/game-Theory/gameTheoryExamples.md deleted file mode 100644 index 0015a8688..000000000 --- a/docs/game-Theory/gameTheoryExamples.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: Game-Theory-examples -title: Game theory Problem -sidebar_label: Game Theory -description: "is a mathematical framework used to study decision-making in situations where multiple players interact." -tags: [dsa, algorithms, game theory algorithms] ---- - - -## 1. Prisoner's Dilemma -In this example, we simulate a simple Prisoner's Dilemma game where two players either confess or stay silent. - -```cpp -Copy code -#include -using namespace std; - -void prisonerDilemma() { - int playerA, playerB; - // 0 = Stay Silent, 1 = Confess - - cout << "Player A: Enter 0 to Stay Silent, 1 to Confess: "; - cin >> playerA; - cout << "Player B: Enter 0 to Stay Silent, 1 to Confess: "; - cin >> playerB; - - if (playerA == 0 && playerB == 0) { - cout << "Both stay silent: (1 year, 1 year)" << endl; - } else if (playerA == 1 && playerB == 1) { - cout << "Both confess: (3 years, 3 years)" << endl; - } else if (playerA == 0 && playerB == 1) { - cout << "Player A stays silent, Player B confesses: (5 years, goes free)" << endl; - } else if (playerA == 1 && playerB == 0) { - cout << "Player A confesses, Player B stays silent: (goes free, 5 years)" << endl; - } -} - -int main() { - prisonerDilemma(); - return 0; -} -``` -## 2. Matching Pennies -The Matching Pennies game simulates two players choosing heads or tails. The game checks whether the players' choices match. - -```cpp -Copy code -#include -using namespace std; - -void matchingPennies() { - int playerA, playerB; - // 0 = Heads, 1 = Tails - - cout << "Player A: Enter 0 for Heads, 1 for Tails: "; - cin >> playerA; - cout << "Player B: Enter 0 for Heads, 1 for Tails: "; - cin >> playerB; - - if (playerA == playerB) { - cout << "Player A wins!" << endl; - } else { - cout << "Player B wins!" << endl; - } -} - -int main() { - matchingPennies(); - return 0; -} -``` -## 3. Stag Hunt -In this example, two hunters choose whether to hunt a Stag together or hunt a Rabbit alone. The game outputs their payoffs based on their choices. - -```cpp -Copy code -#include -using namespace std; - -void stagHunt() { - int hunterA, hunterB; - // 0 = Hunt Rabbit, 1 = Hunt Stag - - cout << "Hunter A: Enter 0 to Hunt Rabbit, 1 to Hunt Stag: "; - cin >> hunterA; - cout << "Hunter B: Enter 0 to Hunt Rabbit, 1 to Hunt Stag: "; - cin >> hunterB; - - if (hunterA == 1 && hunterB == 1) { - cout << "Both hunt the stag: (10, 10)" << endl; - } else if (hunterA == 0 && hunterB == 0) { - cout << "Both hunt rabbits: (2, 2)" << endl; - } else if (hunterA == 1 && hunterB == 0) { - cout << "Hunter A hunts stag, Hunter B hunts rabbit: (0, 2)" << endl; - } else if (hunterA == 0 && hunterB == 1) { - cout << "Hunter A hunts rabbit, Hunter B hunts stag: (2, 0)" << endl; - } -} - -int main() { - stagHunt(); - return 0; -} -``` \ No newline at end of file diff --git a/docs/graphs/Adjacency-Matrix.md b/docs/graphs/Adjacency-Matrix.md deleted file mode 100644 index 7376e9f67..000000000 --- a/docs/graphs/Adjacency-Matrix.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -id: adjacency-matrix -title: Adjacency matrix -sidebar_label: Adjacency matrix -description: "An adjacency matrix is a 2D array used to represent a graph, where each cell (i, j) is set to 1 if there's an edge from node i to node j, and 0 otherwise." -tags: [Graph,Algorithm, DSA] ---- -# Adjacency Matrix -## Problem Statement -Write a program in to create adjacency matrix of a given graph. If a graph has n vertices, we use n x n matrix to represent the graph.Let's assume the n x n matrix as adj[n][n]. -- if there is an edge from vertex i to j, mark adj[i][j] as 1. i.e. adj[i][j] == 1 -- if there is no edge from vertex i to j, mark adj[i][j] as 0. i.e. adj[i][j] == 0 - -## Approach: -The approach constructs a graph using an adjacency matrix, initialized to 0, where each user-specified neighbor for a node sets the corresponding matrix entry to 1, visually representing edges between nodes when displayed. - -## Algorithm Overview - -1. **Input the Number of Nodes**: Prompt the user to input the number of nodes in the graph. Initialize an adjacency matrix of size `V x V` with all entries set to zero. - -2. **Create the Adjacency Matrix**: - - For each node, ask the user for the number of neighbors. - - For each neighbor, set the corresponding matrix entry to 1 to indicate an edge between the nodes. - -3. **Display the Adjacency Matrix**: - - Print a formatted adjacency matrix that shows connections between nodes, with rows and columns representing nodes and entries indicating edges. - -4. **User Interaction**: - - The program takes user input for each node’s neighbors, allowing dynamic graph construction based on user-defined connections. - -## Example - -### Sample Input: - -Enter the number of nodes in G: 5 - -Enter the number of neighbors of 0: 2 -Enter the neighbors of 0 (0-based indices): 1 2 - -Enter the number of neighbors of 1: 2 -Enter the neighbors of 1 (0-based indices): 0 3 - -Enter the number of neighbors of 2: 2 -Enter the neighbors of 2 (0-based indices): 0 3 - -Enter the number of neighbors of 3: 3 -Enter the neighbors of 3 (0-based indices): 2 1 4 - -Enter the number of neighbors of 4: 1 -Enter the neighbors of 4 (0-based indices): 3 - -``` - 0 ---- 1 - | | - 2 ---- 1 --- 4 -``` - -### Sample Output: - -The adjacency matrix is: - - v1 v2 v3 v4 v5 - v1 0 1 1 0 0 - v2 1 0 0 1 0 - v3 1 0 0 1 0 - v4 0 1 1 0 1 - v5 0 0 0 1 0 - - -### Time Complexity -- The time complexity of the code is `O(V^2)` for both creating and displaying the graph, where `V` is the number of nodes. - -### C++ Implementation -```cpp -#include -#include - -void createGraph(std::vector>& Adj, int no_of_nodes) { - int val; - for (int i = 0; i < no_of_nodes; i++) { - std::cout << "\nEnter the number of neighbors of " << i << ": "; - std::cin >> val; - std::cout << "\nEnter the neighbors of " << i << " (0-based indices): "; - std::fill(Adj[i].begin(), Adj[i].end(), 0); - for (int j = 0; j < val; j++) { - int neighbor; - std::cin >> neighbor; - Adj[i][neighbor] = 1; - } - } -} - -void displayGraph(const std::vector>& Adj, int no_of_nodes) { - std::cout << "\nThe adjacency matrix is:\n"; - std::cout << "\t"; - for (int i = 0; i < no_of_nodes; i++) { - std::cout << "v" << i + 1 << "\t"; - } - std::cout << "\n"; - for (int i = 0; i < no_of_nodes; i++) { - std::cout << "v" << i + 1 << "\t"; - for (int j = 0; j < no_of_nodes; j++) { - std::cout << Adj[i][j] << "\t"; - } - std::cout << "\n"; - } -} - -int main() { - int no_of_nodes; - std::cout << "\nEnter the number of nodes in G: "; - std::cin >> no_of_nodes; - std::vector> Adj(no_of_nodes, std::vector(no_of_nodes, 0)); - createGraph(Adj, no_of_nodes); - displayGraph(Adj, no_of_nodes); - return 0; -} -``` diff --git a/docs/graphs/Disjoint Set Union.md b/docs/graphs/Disjoint Set Union.md deleted file mode 100644 index 78b46c448..000000000 --- a/docs/graphs/Disjoint Set Union.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: disjoint-set-union -title: Disjoint Set Union (DSU) -sidebar_label: Introduction to Disjoint Set Union -description: 'The Disjoint Set Union (DSU) algorithm efficiently manages dynamic connectivity and union-find operations.' -tags: [dsa, data-structures, DSU, C language] ---- - -### Solutions: - - -## C++ - -```c -#include -using namespace std; - -class DisjointSetUnion { -public: - vector parent, rank; - - // Constructor to initialize the DSU - DisjointSetUnion(int n) { - parent.resize(n); - rank.resize(n, 1); - for (int i = 0; i < n; i++) { - parent[i] = i; - } - } - - // Find function with path compression - int find(int u) { - if (parent[u] != u) { - parent[u] = find(parent[u]); // Path compression - } - return parent[u]; - } - - // Union function with union by rank - void unionSets(int u, int v) { - int rootU = find(u); - int rootV = find(v); - - if (rootU != rootV) { - if (rank[rootU] > rank[rootV]) { - parent[rootV] = rootU; - } else if (rank[rootU] < rank[rootV]) { - parent[rootU] = rootV; - } else { - parent[rootV] = rootU; - rank[rootU]++; - } - } - } -}; - -// Example Usage -int main() { - DisjointSetUnion dsu(5); // Create 5 disjoint sets - dsu.unionSets(0, 1); - dsu.unionSets(1, 2); - cout << dsu.find(0) << endl; // Output: 0 - cout << dsu.find(1) << endl; // Output: 0 (due to union) - return 0; -} -``` - -## Java - -```java -public class DisjointSetUnion { - private int[] parent; - private int[] rank; - - // Constructor to initialize the DSU - public DisjointSetUnion(int n) { - parent = new int[n]; - rank = new int[n]; - for (int i = 0; i < n; i++) { - parent[i] = i; - rank[i] = 1; - } - } - - // Find function with path compression - public int find(int u) { - if (parent[u] != u) { - parent[u] = find(parent[u]); // Path compression - } - return parent[u]; - } - - // Union function with union by rank - public void union(int u, int v) { - int rootU = find(u); - int rootV = find(v); - - if (rootU != rootV) { - if (rank[rootU] > rank[rootV]) { - parent[rootV] = rootU; - } else if (rank[rootU] < rank[rootV]) { - parent[rootU] = rootV; - } else { - parent[rootV] = rootU; - rank[rootU]++; - } - } - } - - // Example Usage - public static void main(String[] args) { - DisjointSetUnion dsu = new DisjointSetUnion(5); // Create 5 disjoint sets - dsu.union(0, 1); - dsu.union(1, 2); - System.out.println(dsu.find(0)); // Output: 0 - System.out.println(dsu.find(1)); // Output: 0 (due to union) - } -} -``` - -## Python - -```python -class DisjointSetUnion: - def __init__(self, n): - self.parent = list(range(n)) - self.rank = [1] * n - - # Find function with path compression - def find(self, u): - if self.parent[u] != u: - self.parent[u] = self.find(self.parent[u]) # Path compression - return self.parent[u] - - # Union function with union by rank - def union(self, u, v): - rootU = self.find(u) - rootV = self.find(v) - - if rootU != rootV: - if self.rank[rootU] > self.rank[rootV]: - self.parent[rootV] = rootU - elif self.rank[rootU] < self.rank[rootV]: - self.parent[rootU] = rootV - else: - self.parent[rootV] = rootU - self.rank[rootU] += 1 - -# Example Usage -dsu = DisjointSetUnion(5) # Create 5 disjoint sets -dsu.union(0, 1) -dsu.union(1, 2) -print(dsu.find(0)) # Output: 0 -print(dsu.find(1)) # Output: 0 (due to union) - -``` - - - -## Key Concepts: - -➢ Path Compression: When performing the find operation, we make all nodes - point directly to the root, flattening the structure and speeding up future operations. -➢ Union by Rank: The smaller tree is attached under the root of the larger - tree to keep the tree as flat as possible, improving the efficiency of find operations. - - - -All three implementations support efficient find and union operations with a time complexity of nearly O(1) due to path compression and union by rank. \ No newline at end of file diff --git a/docs/graphs/Longest-path-in-DAG.md b/docs/graphs/Longest-path-in-DAG.md deleted file mode 100644 index 5604186e1..000000000 --- a/docs/graphs/Longest-path-in-DAG.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: longest-path-in-dag -title: Longest Path in DAG -sidebar_label: Longest Path in DAG -description: "Calculating the longest path from a given source in a Directed Acyclic Graph (DAG) with weighted edges." -tags: [dsa, algorithms, graph] ---- - -## Definition: -This program finds the longest path from a given source vertex in a Directed Acyclic Graph (DAG) with weighted edges. It accomplishes this by performing a topological sort on the vertices and then using dynamic programming to calculate the longest path distances. - -## Problem Statement: -Given a weighted directed acyclic graph (DAG) and a source vertex, find the cost of the longest path from the source vertex to all other vertices present in the graph. If the vertex can’t be reached from the given source vertex, print its distance as infinity. - -## Algorithm to Find the Longest Path in a Directed Acyclic Graph (DAG) - -1. **Topological Sort** - Perform a topological sort of the DAG. This will allow us to process each vertex in a linear order, ensuring that each vertex is processed after all its dependencies. - -2. **Initialize Distances** - Create a distance array to store the longest path distances from the source. Set the distance of the source vertex to 0 and all other vertices to negative infinity (`-∞`), representing unvisited vertices. - -3. **Process Vertices in Topological Order** - For each vertex in the topologically sorted order: - - If the vertex has been visited (its distance is not `-∞`), update the distances of its adjacent vertices. - - For each adjacent vertex, calculate the potential new distance, and if it's greater than the current distance, update it. - -4. **Update Distances of Adjacent Vertices** - For each adjacent vertex of the current vertex, calculate the longest path distance from the source. If this new distance is greater than the current distance of the adjacent vertex, update it. - -5. **Output the Longest Path Distances** - Print the longest distance to each vertex from the source. If a vertex's distance remains `-∞`, it means the vertex is unreachable from the source. - -## Time Complexity: -- The time complexity of this program is `O(V + E)`, where `V` is the number of vertices and `E` is the number of edges. This is achieved by first performing a topological sort using Depth-First Search (DFS), which takes `O(V + E)` time, and then processing each vertex in topological order to update the distances of its adjacent vertices, also in `O(V + E)` time. - -## Example - -### Sample Input: -addEdge(adj, 0, 1, 3); -addEdge(adj, 0, 2, 10); -addEdge(adj, 0, 3, 14); -addEdge(adj, 1, 3, 7); -addEdge(adj, 1, 4, 51); -addEdge(adj, 2, 3, 5); -addEdge(adj, 3, 4, 11); - -### Sample Output: -Longest distances from source vertex 0: -Vertex 0 - Distance: 0 -Vertex 1 - Distance: 3 -Vertex 2 - Distance: 10 -Vertex 3 - Distance: 15 -Vertex 4 - Distance: 54 - -### Explanation of Sample: -![DAG](https://github.com/user-attachments/assets/4e3f9cd9-e56a-461d-b824-5e8889b54eb7) - -The maximum distance from the source node 0 to each node is as follows: - -- **Node 0**: The maximum distance from node 0 to itself is 0. - _(The distance of a node from itself is always 0)._ - -- **Node 1**: The maximum distance from node 0 to node 1 is 3, achieved via the path `0 -> 1`. - -- **Node 2**: The maximum distance from node 0 to node 2 is 10, achieved via the path `0 -> 2`. - -- **Node 3**: The maximum distance from node 0 to node 3 is 15, achieved via the path `0 -> 2 -> 3`. - -- **Node 4**: The maximum distance from node 0 to node 4 is 54, achieved via the path `0 -> 1 -> 4`. - -Thus, we should print the distances in order as follows: **0 3 10 15 54**. - -## C++ Implementation: -```cpp -#include -#include -#include -#include - -using namespace std; -// A utility function to add an edge to the graph -void addEdge(vector> adj[], int u, int v, int weight) { - adj[u].push_back({v, weight}); -} - -// A utility function to perform topological sort using DFS -void topologicalSortUtil(int v, vector& visited, stack& Stack, const vector> adj[]) { - visited[v] = true; - - // Visit all the adjacent vertices of v - for (auto& i : adj[v]) { - int u = i.first; - if (!visited[u]) { - topologicalSortUtil(u, visited, Stack, adj); - } - } - // Push current vertex to the stack that stores the topological sort - Stack.push(v); -} - -// Function to find the longest path from a given source in a DAG -void longestPath(vector> adj[], int V, int src) { - // Step 1: Perform topological sort - stack Stack; - vector visited(V, false); - - // Call the helper function to store topological sort of all vertices - for (int i = 0; i < V; i++) { - if (!visited[i]) { - topologicalSortUtil(i, visited, Stack, adj); - } - } - - // Step 2: Initialize distances to all vertices as minus infinity - vector dist(V, INT_MIN); - dist[src] = 0; - - // Step 3: Process vertices in topological order - while (!Stack.empty()) { - int u = Stack.top(); - Stack.pop(); - - // Update distances of all adjacent vertices - if (dist[u] != INT_MIN) { - for (auto& i : adj[u]) { - int v = i.first; - int weight = i.second; - if (dist[v] < dist[u] + weight) { - dist[v] = dist[u] + weight; - } - } - } - } - - // Print the calculated longest distances - cout << "Longest distances from source vertex " << src << ":\n"; - for (int i = 0; i < V; i++) { - if (dist[i] == INT_MIN) { - cout << "Vertex " << i << " is unreachable from source, Distance: -Infinity\n"; - } else { - cout << "Vertex " << i << " - Distance: " << dist[i] << "\n"; - } - } -} - -int main() { - int V = 5; // Number of vertices - vector> adj[V]; - - // Adding edges to the DAG (u -> v with weight w) - addEdge(adj, 0, 1, 3); - addEdge(adj, 0, 2, 10); - addEdge(adj, 0, 3, 14); - addEdge(adj, 1, 3, 7); - addEdge(adj, 1, 4, 51); - addEdge(adj, 2, 3, 5); - addEdge(adj, 3, 4, 11); - int source = 0; - longestPath(adj, V, source); - return 0; -} -``` diff --git a/docs/graphs/Page-Rank-Algorithm.md b/docs/graphs/Page-Rank-Algorithm.md deleted file mode 100644 index 0c00dfb46..000000000 --- a/docs/graphs/Page-Rank-Algorithm.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: page-rank-algorithm -title: PageRank Algorithm -sidebar_label: PageRank Algorithm -description: "In this blog post, we'll explore the PageRank algorithm, a method used to rank web pages based on their link structure." -tags: [dsa, algorithms, graphs, page rank] ---- - -### Definition: - -The **PageRank algorithm** is a **link analysis algorithm** developed by Larry Page and Sergey Brin, which is used to determine the importance of web pages based on their link structure. The algorithm assigns a numerical value (PageRank score) to each page, indicating its relative importance, with higher scores indicating more important pages. - -### Characteristics: - -- **Graph-Based Algorithm**: - - The PageRank algorithm treats the web as a directed graph where nodes represent web pages and directed edges represent hyperlinks between them. - -- **Random Surfer Model**: - - The algorithm is based on the concept of a random surfer who randomly clicks on links. The likelihood of landing on a page is influenced by the number and quality of inbound links to that page. - -- **Damping Factor**: - - A damping factor (usually set to around 0.85) is used to model the probability that a user continues clicking on links, with a chance of jumping to a random page. This prevents the score from being skewed by a small number of highly connected pages. - -- **Iterative Calculation**: - - The PageRank scores are calculated iteratively, updating the scores based on the ranks of inbound pages until convergence is achieved. - -### Time Complexity: - -- **Time Complexity: O(N * I)** - The time complexity of the PageRank algorithm is O(N * I), where N is the number of nodes (pages) and I is the number of iterations until convergence. - -### Space Complexity: - -- **Space Complexity: O(N)** - The algorithm requires additional space for storing PageRank scores and adjacency information, leading to a space complexity of O(N). - -### Python Implementation: - -```python -# Adjacency matrix representation of the graph -adjacency_matrix = [[0, 1, 1], [0, 0, 1], [1, 0, 0]] - - -class Node: - def __init__(self, name): - self.name = name # Name of the node - self.inbound_nodes = [] # Links coming to this node - self.outbound_nodes = [] # Links going from this node - - def add_inbound(self, node): - """Add a node to the inbound list.""" - self.inbound_nodes.append(node) - - def add_outbound(self, node): - """Add a node to the outbound list.""" - self.outbound_nodes.append(node) - - def __repr__(self): - """Return a string representation of the node.""" - return f"" - - -def page_rank(nodes, iterations=3, damping_factor=0.85): - """ - Calculate the PageRank of each node in the graph. - """ - ranks = {node.name: 1 for node in nodes} # Initialize ranks - - outbound_count = {node.name: len(node.outbound_nodes) for node in nodes} # Count of outbound links - - for i in range(iterations): - print(f"======= Iteration {i + 1} =======") - for node in nodes: - # Calculate new rank based on inbound nodes - rank_sum = sum(ranks[inbound_node] / outbound_count[inbound_node] for inbound_node in node.inbound_nodes) - ranks[node.name] = (1 - damping_factor) + damping_factor * rank_sum - print(f"Current Ranks: {ranks}") # Print current rank values - - -def main(): - # Prompt user for node names - node_names = input("Enter Names of the Nodes (space-separated): ").split() - - nodes = [Node(name) for name in node_names] # Create Node objects - - # Establish inbound and outbound relationships based on the adjacency matrix - for row_index, row in enumerate(adjacency_matrix): - for col_index, value in enumerate(row): - if value == 1: # If there is a link - nodes[col_index].add_inbound(node_names[row_index]) - nodes[row_index].add_outbound(node_names[col_index]) - - print("======= Nodes =======") - for node in nodes: - print(node) - - # Calculate and display PageRank values - page_rank(nodes) - - -if __name__ == "__main__": - main() -``` - -### Summary: - -The PageRank algorithm is an essential tool for determining the importance of web pages based on their link structure. By modeling the browsing behavior of users and using a damping factor, the algorithm effectively ranks pages while minimizing the impact of less relevant pages. It has numerous applications in search engines and network analysis, making it a foundational algorithm in the field of data science and information retrieval. diff --git a/docs/graphs/Practice Problems.md b/docs/graphs/Practice Problems.md deleted file mode 100644 index 488f98f63..000000000 --- a/docs/graphs/Practice Problems.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -id: practice-problems-on-graphs -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 16 -Description: Here are some practice problems for Graph Data Structure divided into topic-wise and difficulty wise. -tags: [DSA, algorithms,Graph, dsa] ---- - -### 1. Easy Level - - [Find Center of Star Graph](https://leetcode.com/problems/find-center-of-star-graph/description/) - - [Find if Path Exists in Graph](https://leetcode.com/problems/find-if-path-exists-in-graph/description/) - - [Find the Town Judge](https://leetcode.com/problems/find-the-town-judge/description/) - ---- - -### 2. Medium Level - - - [Number of Islands](https://leetcode.com/problems/number-of-islands/description/) - - [Surrounded Regions](https://leetcode.com/problems/surrounded-regions/description/) - - [Clone Graph](https://leetcode.com/problems/clone-graph/description/) - - [Evaluate Division](https://leetcode.com/problems/evaluate-division/description/) - - [Course Schedule](https://leetcode.com/problems/course-schedule/description/) - - [Course Schedule II](https://leetcode.com/problems/course-schedule-ii/description/) - - [Snakes and Ladders](https://leetcode.com/problems/snakes-and-ladders/description/) - - [Minimum Genetic Mutation](https://leetcode.com/problems/minimum-genetic-mutation/description/) - - [Keys and Rooms]( https://leetcode.com/problems/keys-and-rooms/description/) - - [Number of Provinces](https://leetcode.com/problems/number-of-provinces/description/) - - [Reorder Routes to Make All Paths Lead to the City Zero]( https://leetcode.com/problems/reorder-routes-to-make-all-paths-lead-to-the-city-zero/description/) -- [Nearest Exit from Entrance in Maze](https://leetcode.com/problems/nearest-exit-from-entrance-in-maze/description/) -- [Rotting Oranges]( https://leetcode.com/problems/rotting-oranges/description/) - ---- - -### 3. Hard Level - - - [Word Ladder](https://leetcode.com/problems/word-ladder/description) - - [Count Visited Nodes in a Directed Graph](https://leetcode.com/problems/count-visited-nodes-in-a-directed-graph/description/) - - [Shortest Cycle in a Graph](https://leetcode.com/problems/shortest-cycle-in-a-graph/description/) ---- diff --git a/docs/graphs/_category_.json b/docs/graphs/_category_.json deleted file mode 100644 index d224d4df1..000000000 --- a/docs/graphs/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Graphs", - "position": 11, - "link": { - "type": "generated-index", - "description": "Learn the most important concepts of Graph." - } - } \ No newline at end of file diff --git a/docs/graphs/ant-colony-optimization-tsp.md b/docs/graphs/ant-colony-optimization-tsp.md deleted file mode 100644 index 3d2457a1d..000000000 --- a/docs/graphs/ant-colony-optimization-tsp.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -id: ant-colony-optimization-tsp -title: Ant Colony Optimization for TSP -sidebar_label: Ant Colony Optimization -description: "In this post, we'll explore the Ant Colony Optimization (ACO) algorithm, applied to solving the Travelling Salesman Problem (TSP) using a probabilistic and pheromone-based approach." -tags: [dsa, algorithms, TSP, ant colony, graphs] ---- - -### Definition: -The **Ant Colony Optimization (ACO) algorithm** is a **probabilistic optimization algorithm** inspired by the foraging behavior of ants. It is widely applied to solve combinatorial optimization problems such as the Travelling Salesman Problem (TSP), where the goal is to find the shortest possible route that visits each city exactly once and returns to the origin city. - -### Characteristics: -- **Swarm Intelligence**: - - ACO is based on the collective behavior of ants that deposit pheromones on paths as they search for food, guiding other ants toward shorter paths over time. - -- **Pheromone Trails**: - - The algorithm uses pheromone trails to mark paths between cities. The amount of pheromone on a path reflects its desirability, guiding subsequent choices for other ants. - -- **Heuristic Information**: - - In addition to pheromone levels, ants consider a heuristic measure (e.g., distance) to select paths, striking a balance between exploration and exploitation. - -- **Parameter Tuning**: - - Parameters such as **alpha** (influence of pheromone), **beta** (influence of distance), and **evaporation rate** control the algorithm’s convergence speed and solution quality. - -### Python Implementation: -```python - -import copy -import random - -cities = { - 0: [0, 0], - 1: [0, 5], - 2: [3, 8], - 3: [8, 10], - 4: [12, 8], - 5: [12, 4], - 6: [8, 0], - 7: [6, 2], -} - - -def main( - cities: dict[int, list[int]], - ants_num: int, - iterations_num: int, - pheromone_evaporation: float, - alpha: float, - beta: float, - q: float, # Pheromone system constant -) -> tuple[list[int], float]: - """Ant colony optimization main function for TSP.""" - cities_num = len(cities) - pheromone = [[1.0] * cities_num] * cities_num - - best_path: list[int] = [] - best_distance = float("inf") - for _ in range(iterations_num): - ants_route = [] - for _ in range(ants_num): - unvisited_cities = copy.deepcopy(cities) - current_city = {next(iter(cities.keys())): next(iter(cities.values()))} - del unvisited_cities[next(iter(current_city.keys()))] - ant_route = [next(iter(current_city.keys()))] - while unvisited_cities: - current_city, unvisited_cities = city_select( - pheromone, current_city, unvisited_cities, alpha, beta - ) - ant_route.append(next(iter(current_city.keys()))) - ant_route.append(0) - ants_route.append(ant_route) - - pheromone, best_path, best_distance = pheromone_update( - pheromone, - cities, - pheromone_evaporation, - ants_route, - q, - best_path, - best_distance, - ) - return best_path, best_distance - - -def distance(city1: list[int], city2: list[int]) -> float: - """Calculate the Euclidean distance between two cities.""" - return (((city1[0] - city2[0]) ** 2) + ((city1[1] - city2[1]) ** 2)) ** 0.5 - - -def pheromone_update( - pheromone: list[list[float]], - cities: dict[int, list[int]], - pheromone_evaporation: float, - ants_route: list[list[int]], - q: float, - best_path: list[int], - best_distance: float, -) -> tuple[list[list[float]], list[int], float]: - """Update pheromones on routes and determine the best route.""" - for a in range(len(cities)): - for b in range(len(cities)): - pheromone[a][b] *= pheromone_evaporation - for ant_route in ants_route: - total_distance = 0.0 - for i in range(len(ant_route) - 1): - total_distance += distance(cities[ant_route[i]], cities[ant_route[i + 1]]) - delta_pheromone = q / total_distance - for i in range(len(ant_route) - 1): - pheromone[ant_route[i]][ant_route[i + 1]] += delta_pheromone - pheromone[ant_route[i + 1]][ant_route[i]] = pheromone[ant_route[i]][ - ant_route[i + 1] - ] - - if total_distance < best_distance: - best_path = ant_route - best_distance = total_distance - - return pheromone, best_path, best_distance - - -def city_select( - pheromone: list[list[float]], - current_city: dict[int, list[int]], - unvisited_cities: dict[int, list[int]], - alpha: float, - beta: float, -) -> tuple[dict[int, list[int]], dict[int, list[int]]]: - """Select the next city based on pheromone levels and distances.""" - probabilities = [] - for city in unvisited_cities: - city_distance = distance( - unvisited_cities[city], next(iter(current_city.values())) - ) - probability = (pheromone[city][next(iter(current_city.keys()))] ** alpha) * ( - (1 / city_distance) ** beta - ) - probabilities.append(probability) - - chosen_city_i = random.choices( - list(unvisited_cities.keys()), weights=probabilities - )[0] - chosen_city = {chosen_city_i: unvisited_cities[chosen_city_i]} - del unvisited_cities[next(iter(chosen_city.keys()))] - return chosen_city, unvisited_cities - - -if __name__ == "__main__": - best_path, best_distance = main( - cities=cities, - ants_num=10, - iterations_num=20, - pheromone_evaporation=0.7, - alpha=1.0, - beta=5.0, - q=10, - ) - - print(f"{best_path = }") - print(f"{best_distance = }") - -``` - -### Time Complexity: -- **Time Complexity: O(N * ants_num * iterations_num)** - The time complexity depends on the number of cities (N), the number of ants (ants_num), and the number of iterations (iterations_num). - -### Space Complexity: -- **Space Complexity: O(N^2)** - The algorithm requires storage for pheromone levels on all paths, resulting in a space complexity of O(N^2) for a fully connected graph. - -### Summary: -The Ant Colony Optimization (ACO) algorithm effectively tackles the Travelling Salesman Problem by simulating ant behavior with pheromone trails to find the shortest path. By balancing pheromone influence and heuristic distance measures, the algorithm iteratively improves routes, offering a practical solution for complex optimization challenges. This approach is highly valuable in network routing, scheduling, and various other optimization domains. diff --git a/docs/graphs/bfs.md b/docs/graphs/bfs.md deleted file mode 100644 index 7f8abf224..000000000 --- a/docs/graphs/bfs.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -id: bfs -title: Breadth-First Search (BFS) -sidebar_label: Breadth-First Search -description: "In this blog post, we'll explore Breadth-First Search (BFS), a graph traversal algorithm used to explore vertices and edges level by level in a graph." -tags: [dsa, algorithms, graph, traversal] ---- - -### Definition: - -Breadth-First Search (BFS) is a **graph traversal algorithm** that explores vertices level by level. Starting from a source vertex, BFS explores all its direct neighbors before moving to the next level of neighbors. It is useful for traversing or searching graph data structures and can be applied to both directed and undirected graphs. - -### Characteristics: - -- **Level-Order Traversal**: - - BFS visits nodes in a level-wise manner. Starting from the source node, it explores all the direct neighbors before moving to the next level. - -- **Queue-Based Approach**: - - BFS uses a **queue** data structure to keep track of nodes that need to be explored. The queue ensures that nodes are processed in the correct order, with nodes at the current level being processed before nodes at the next level. - -- **Shortest Path in Unweighted Graphs**: - - BFS can find the shortest path between two nodes in an unweighted graph. Since BFS explores paths in increasing order of their lengths, the first time a node is reached is through the shortest path. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(V + E)$** - Where `V` is the number of vertices and `E` is the number of edges in the graph. BFS explores each vertex and edge exactly once. - -### Space Complexity: - -- **Space Complexity: $O(V)$** - BFS requires space to store the visited vertices, the queue for traversal, and the adjacency list for the graph. - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -void bfs(int start, vector>& adj_list, int n) { - vector visited(n, false); - queue q; - - visited[start] = true; - q.push(start); - - while (!q.empty()) { - int node = q.front(); - q.pop(); - cout << node << " "; - - for (int neighbor : adj_list[node]) { - if (!visited[neighbor]) { - visited[neighbor] = true; - q.push(neighbor); - } - } - } -} - -int main() { - int n = 5; // number of nodes - vector> adj_list(n); - - adj_list[0] = {1, 2}; - adj_list[1] = {0, 3, 4}; - adj_list[2] = {0}; - adj_list[3] = {1}; - adj_list[4] = {1}; - - int start_node = 0; - cout << "BFS traversal starting from node " << start_node << ": "; - bfs(start_node, adj_list, n); - cout << endl; - - return 0; -} -``` -### JAVA Implementation: - -```java -import java.util.*; - -public class Main { - public static void bfs(int start, List> adjList, int n) { - boolean[] visited = new boolean[n]; - Queue queue = new LinkedList<>(); - - visited[start] = true; - queue.add(start); - - while (!queue.isEmpty()) { - int node = queue.poll(); - System.out.print(node + " "); - - for (int neighbor : adjList.get(node)) { - if (!visited[neighbor]) { - visited[neighbor] = true; - queue.add(neighbor); - } - } - } - } - - public static void main(String[] args) { - int n = 5; // number of nodes - List> adjList = new ArrayList<>(); - - // Initialize adjacency list - for (int i = 0; i < n; i++) { - adjList.add(new ArrayList<>()); - } - - adjList.get(0).addAll(Arrays.asList(1, 2)); - adjList.get(1).addAll(Arrays.asList(0, 3, 4)); - adjList.get(2).add(0); - adjList.get(3).add(1); - adjList.get(4).add(1); - - int startNode = 0; - System.out.print("BFS traversal starting from node " + startNode + ": "); - bfs(startNode, adjList, n); - System.out.println(); - } -} - -``` - -### Conclusion: - -Breadth-First Search (BFS) is a fundamental graph traversal algorithm that explores vertices level by level. It is widely used in various applications, such as finding the shortest path in unweighted graphs, analyzing network connectivity, and solving puzzles. By leveraging the queue data structure, BFS ensures that nodes are visited in the correct order, making it an essential tool for graph exploration and search. diff --git a/docs/graphs/bipartite-graph.md b/docs/graphs/bipartite-graph.md deleted file mode 100644 index ad2a43f82..000000000 --- a/docs/graphs/bipartite-graph.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: bipartite-graph -title: Bipartite-graph -sidebar_label: Bipartite-graph -description: "A bipartite graph is a graph whose vertices can be divided into two disjoint sets such that no two vertices within the same set are adjacent." -tags: [dsa, algorithms, graph] ---- - -## Problem Statement: -Given an adjacency list / matrix representing a graph with V vertices indexed from 0, the task is to determine whether the graph is bipartite or not. You can use queue data structure to check the graph. - -## Definition: -A bipartite graph is a type of graph where the set of vertices can be divided into two distinct sets such that no two vertices within the same set are adjacent. In other words, if you were to color the graph using two colors, it would be possible to color it in such a way that no two connected vertices have the same color. This property makes bipartite graphs useful in various applications, including matching problems, scheduling, and network flow analysis, as they can represent relationships where entities can be classified into two categories. - -## Approach -The approach to check if a graph is bipartite involves using BFS or DFS to color the graph with two colors, ensuring that no two adjacent vertices share the same color. - -## Algorithm Steps to Check if a Graph is Bipartite: - -1. **Initialize Colors**: Create an array `color` of size V (number of vertices) and initialize all elements to -1, indicating that no vertices have been colored. - -2. **BFS for Each Component**: For each vertex `start` from 0 to V-1: - - If `color[start]` is not -1, continue to the next vertex (this vertex is already colored). - -3. **Start BFS**: - - Initialize a queue and push the `start` vertex into it. - - Color `start` with color 0. - -4. **Process the Queue**: - - While the queue is not empty, dequeue a vertex and check its neighbors: - - Color uncolored neighbors with the opposite color. - - If a neighbor has the same color as the current vertex, return false (the graph is not bipartite). - -5. **Completion**: If all vertices are processed without conflicts, return true (the graph is bipartite). - - -## Time Complexity: -- The bipartite graph checking algorithm has a time complexity of `O(V^2)` with an adjacency matrix, where `V` is the number of vertices. If an adjacency list is used, the complexity is `O(V + E)`, with `E` being the number of edges. - -## Example: - -### Sample Input: - -Enter the number of vertices: 5 -Enter the adjacency matrix: -0 1 1 0 0 -1 0 0 1 0 -1 0 0 1 0 -0 1 1 0 1 -0 0 0 1 0 - -### Sample Output: - -The graph is bipartite. - -## Explainataion of Sample: - -**Diagrammatic representation of the above input:** - -``` - 0 ---- 1 - | | - 2 ---- 1 --- 4 -``` - -To determine if the graph is bipartite, we can attempt to color the vertices using two colors. The following coloring can be used: - -- Color Vertex 0 with color 0. -- Color Vertex 1 and Vertex 2 with color 1 (neighbors of Vertex 0). -- Color Vertex 3 with color 0 (neighbor of Vertices 1 and 2). -- Color Vertex 4 with color 1 (neighbor of Vertex 3). - -Since we can assign colors such that no two adjacent vertices share the same color, the graph is confirmed to be bipartite. - - -## C++ Implementation: - -```cpp - -#include -#include -#include -using namespace std; - -bool isBipartite(const vector>& adjMatrix, int V) { - // Initialize colors array with -1 (uncolored) - vector color(V, -1); - // Process each component of the graph - for (int start = 0; start < V; ++start) { - // If the vertex is already colored, skip it - if (color[start] != -1) continue; - // Start BFS from this node - queue q; - q.push(start); - color[start] = 0; // Color the starting vertex with 0 - while (!q.empty()) { - int node = q.front(); - q.pop(); - // Check all adjacent vertices - for (int neighbor = 0; neighbor < V; ++neighbor) { - // Check if there's an edge between node and neighbor - if (adjMatrix[node][neighbor] == 1) { - // If the neighbor hasn't been colored, color it with the opposite color - if (color[neighbor] == -1) { - color[neighbor] = 1 - color[node]; - q.push(neighbor); - } - // If the neighbor has the same color as the current node, the graph is not bipartite - else if (color[neighbor] == color[node]) { - return false; - } - } - } - } - } - // If we successfully colored the graph, it's bipartite - return true; -} - -int main() { - int V; - cout << "Enter the number of vertices: "; - cin >> V; - vector> adjMatrix(V, vector(V, 0)); - cout << "Enter the adjacency matrix:\n"; - for (int i = 0; i < V; ++i) { - for (int j = 0; j < V; ++j) { - cin >> adjMatrix[i][j]; - } - } - if (isBipartite(adjMatrix, V)) { - cout << "The graph is bipartite.\n"; - } else { - cout << "The graph is not bipartite.\n"; - } - return 0; -} - -``` diff --git a/docs/graphs/dfs.md b/docs/graphs/dfs.md deleted file mode 100644 index 7783da945..000000000 --- a/docs/graphs/dfs.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -id: dfs -title: Depth-First Search (DFS) -sidebar_label: Depth-First Search -description: "In this blog post, we'll explore Depth-First Search (DFS), a graph traversal algorithm used to explore vertices and edges by going as deep as possible before backtracking." -tags: [dsa, algorithms, graph, traversal] ---- - -### Definition: - -Depth-First Search (DFS) is a **graph traversal algorithm** that explores as far as possible along each branch before backtracking. DFS starts from a source vertex and explores each branch or path before moving to a new one. It is commonly used for traversing or searching tree or graph data structures. - -### Characteristics: - -- **Recursive or Stack-Based Traversal**: - - DFS can be implemented using recursion or a stack data structure. It explores a node, then recursively explores its neighbors before backtracking to explore other branches. - -- **Preorder Traversal**: - - DFS naturally performs a preorder traversal of the graph, visiting a node before any of its neighbors. This makes it useful for tasks like topological sorting, detecting cycles, or pathfinding in specific types of graphs. - -- **Backtracking**: - - DFS backtracks when it reaches a node with no unvisited neighbors. It then returns to previous nodes to explore unvisited paths. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(V + E)$** - Where `V` is the number of vertices and `E` is the number of edges. DFS explores every vertex and edge exactly once. - -### Space Complexity: - -- **Space Complexity: $O(V)$** - In the worst case, DFS requires space proportional to the number of vertices, either due to the recursion stack or an explicit stack used for the traversal. - -### C++ Implementation: - -```cpp -#include -#include -using namespace std; - -void dfs(int node, vector>& adj_list, vector& visited) { - visited[node] = true; - cout << node << " "; - - for (int neighbor : adj_list[node]) { - if (!visited[neighbor]) { - dfs(neighbor, adj_list, visited); - } - } -} - -int main() { - int n = 5; // number of nodes - vector> adj_list(n); - - adj_list[0] = {1, 2}; - adj_list[1] = {0, 3, 4}; - adj_list[2] = {0}; - adj_list[3] = {1}; - adj_list[4] = {1}; - - vector visited(n, false); - int start_node = 0; - cout << "DFS traversal starting from node " << start_node << ": "; - dfs(start_node, adj_list, visited); - cout << endl; - - return 0; -} -``` \ No newline at end of file diff --git a/docs/graphs/dfs_java.md b/docs/graphs/dfs_java.md deleted file mode 100644 index 0c0fae590..000000000 --- a/docs/graphs/dfs_java.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: javadfs -title: Depth-First Search (DFS) Using Java -sidebar_label: Depth-First Search (DFS) Using Java -description: "In this blog post, we'll explore Depth-First Search (DFS) using Java, a graph traversal algorithm used to explore vertices and edges by going as deep as possible before backtracking." -tags: [dsa, algorithms, graph, traversal] ---- - -### Definition: - -Depth-First Search (DFS) is a graph traversal algorithm used to explore vertices and edges in a depthward motion, meaning it goes as deep as possible into a graph before backtracking. DFS starts from a source node and follows paths until there are no unvisited nodes left in that path. Once it reaches a dead-end (i.e., no more unvisited neighbors), it backtracks to explore other paths. It is widely applied in graph-related problems like pathfinding, cycle detection, and solving mazes. - -### Characteristics: - -- **Recursive or Stack-Based Traversal**: - - DFS can be implemented recursively using a function call stack or iteratively using an explicit stack. At each node, it marks the node as visited and explores all its unvisited neighbors before backtracking. - -- **Preorder Traversal**: - - DFS visits a node before its neighbors, which can resemble preorder traversal in trees. This makes it useful in applications such as topological sorting or checking the existence of cycles in directed graphs. - -- **Backtracking**: - - DFS naturally involves backtracking. After fully exploring all paths from the current node, DFS backtracks to previously visited nodes to explore any remaining unvisited neighbors. - -### Time Complexity: - -- **Best, Average, and Worst Case: $O(V + E)$** -Here, V represents the number of vertices, and E represents the number of edges. The algorithm visits each vertex and edge exactly once in the worst-case scenario. - -### Space Complexity: - -- **Space Complexity: $O(V)$** - In the worst case, DFS may use space proportional to the number of vertices due to either the recursion stack or an explicit stack used during traversal. - -### Java Implementation: - -```java -import java.util.*; - -public class DepthFirstSearch { - - // Function to perform DFS traversal - public static void dfs(int node, List> adjList, boolean[] visited) { - visited[node] = true; - System.out.print(node + " "); - - for (int neighbor : adjList.get(node)) { - if (!visited[neighbor]) { - dfs(neighbor, adjList, visited); - } - } - } - - public static void main(String[] args) { - int n = 5; // number of nodes - List> adjList = new ArrayList<>(); - for (int i = 0; i < n; i++) { - adjList.add(new ArrayList<>()); - } - - // Adding edges to the adjacency list - adjList.get(0).add(1); - adjList.get(0).add(2); - adjList.get(1).add(0); - adjList.get(1).add(3); - adjList.get(1).add(4); - adjList.get(2).add(0); - adjList.get(3).add(1); - adjList.get(4).add(1); - - // Mark all vertices as unvisited - boolean[] visited = new boolean[n]; - int startNode = 0; - - System.out.println("DFS traversal starting from node " + startNode + ": "); - dfs(startNode, adjList, visited); - System.out.println(); - } -} - -``` \ No newline at end of file diff --git a/docs/graphs/eulerian-graphs.md b/docs/graphs/eulerian-graphs.md deleted file mode 100644 index 4ebffb87d..000000000 --- a/docs/graphs/eulerian-graphs.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -id: eulerian-graphs -title: Eulerian Graphs -sidebar_label: Eulerian Graphs -description: "This post explores Eulerian graphs, their properties, and algorithms for detecting and constructing Eulerian paths and circuits." -tags: [dsa, graph-theory, algorithms, eulerian-graphs] ---- - -### Definition - -An **Eulerian Graph** is a graph in which we can traverse every edge exactly once and return to the starting vertex. There are two concepts related to Eulerian graphs: - -1. **Eulerian Circuit (Cycle)**: A path in a graph that visits every edge exactly once and ends at the starting vertex. -2. **Eulerian Path**: A path that visits every edge exactly once but doesn't necessarily return to the starting vertex. - -### Conditions for Eulerian Path and Circuit - -- **Eulerian Circuit**: - - A graph has an Eulerian circuit if and only if **every vertex** has an even degree, and the graph is connected (except isolated vertices). - -- **Eulerian Path**: - - A graph has an Eulerian path if and only if **exactly two vertices** have an odd degree, and the graph is connected. - -### Characteristics - -- **Eulerian Circuit**: - - Every vertex has an **even degree**. - - The graph must be connected (ignoring isolated vertices). - -- **Eulerian Path**: - - Exactly **two vertices** have an **odd degree**, and the graph must be connected. - -- **Non-Eulerian**: - - If more than two vertices have an odd degree, the graph cannot have an Eulerian path or circuit. - -### Time Complexity - -The complexity of finding an Eulerian path or circuit is `O(E)` where `E` is the number of edges in the graph, assuming the graph is represented using an adjacency list. - -### Space Complexity - -The space complexity is `O(V + E)` where `V` is the number of vertices and `E` is the number of edges. - -### Algorithm Steps - -1. **Check Degrees**: First, check the degree of every vertex in the graph. - - If every vertex has an even degree, then it has an Eulerian circuit. - - If exactly two vertices have an odd degree, then it has an Eulerian path. - - If more than two vertices have an odd degree, the graph is not Eulerian. - -2. **Fleury’s Algorithm** (for finding an Eulerian Path or Circuit): - - Choose a starting vertex. - - Follow edges one by one. - - Always choose a non-bridge edge if possible until all edges are traversed. - -3. **Hierholzer's Algorithm** (for finding an Eulerian Circuit): - - Start from any vertex with non-zero degree and follow edges to form a circuit. - - When the circuit is complete, repeat the process for any vertex that has edges remaining. - -### Example Problem - -Consider the following graph: - -Vertices: {0, 1, 2, 3, 4} - -Edges: -- (0, 1) -- (1, 2) -- (2, 0) -- (1, 3) -- (3, 4) -- (4, 1) - -- Check degrees: - - Vertex 0: Degree 2 (even) - - Vertex 1: Degree 4 (even) - - Vertex 2: Degree 2 (even) - - Vertex 3: Degree 2 (even) - - Vertex 4: Degree 2 (even) - -Since all vertices have even degrees and the graph is connected, this graph has an **Eulerian Circuit**. - -### Example Problem 2 - -Consider a graph: - -Vertices: {0, 1, 2, 3} - -Edges: -- (0, 1) -- (1, 2) -- (2, 3) -- (3, 0) -- (0, 2) - -- Check degrees: - - Vertex 0: Degree 3 (odd) - - Vertex 1: Degree 2 (even) - - Vertex 2: Degree 3 (odd) - - Vertex 3: Degree 2 (even) - -Since two vertices (0 and 2) have odd degrees, this graph has an **Eulerian Path** but no Eulerian Circuit. - -### Related Problems - -Here are some related problems on Eulerian graphs that can be solved: - -1. **Euler Circuit in an Undirected Graph** (Classic Problem) - - Problem: Check if a given undirected graph has an Eulerian circuit. - - Difficulty: Medium - - [Problem Link](https://www.geeksforgeeks.org/eulerian-path-and-circuit/) - -2. **Hierholzer's Algorithm Implementation** (Find Eulerian Circuit) - - Problem: Given a graph, find an Eulerian circuit if it exists. - - Difficulty: Hard - - [Problem Link](https://www.geeksforgeeks.org/hierholzers-algorithm-directed-graph/) - -3. **Fleury’s Algorithm for Eulerian Path** - - Problem: Find the Eulerian path in an undirected graph. - - Difficulty: Medium - - [Problem Link](https://www.geeksforgeeks.org/fleurys-algorithm-for-printing-eulerian-path/) - -### Java Implementation: Eulerian Circuit and Path - -```java -import java.util.*; - -public class EulerianGraph { - private int V; // Number of vertices - private LinkedList adj[]; // Adjacency List Representation - - // Constructor - EulerianGraph(int v) { - V = v; - adj = new LinkedList[v]; - for (int i = 0; i < v; ++i) - adj[i] = new LinkedList(); - } - - // Function to add an edge into the graph - void addEdge(int v, int w) { - adj[v].add(w); - adj[w].add(v); // Graph is undirected - } - - // A function to perform DFS traversal - void DFSUtil(int v, boolean visited[]) { - visited[v] = true; - for (int n : adj[v]) { - if (!visited[n]) - DFSUtil(n, visited); - } - } - - // Check if all non-zero degree vertices are connected - boolean isConnected() { - boolean visited[] = new boolean[V]; - int i; - for (i = 0; i < V; i++) - if (adj[i].size() != 0) - break; - - if (i == V) - return true; - - DFSUtil(i, visited); - - for (i = 0; i < V; i++) - if (visited[i] == false && adj[i].size() > 0) - return false; - - return true; - } - - // Check if the graph has Eulerian Path or Circuit - int isEulerian() { - if (isConnected() == false) - return 0; - - int odd = 0; - for (int i = 0; i < V; i++) - if (adj[i].size() % 2 != 0) - odd++; - - if (odd > 2) - return 0; - - return (odd == 2) ? 1 : 2; - } - - // Function to print result - void testEulerian() { - int res = isEulerian(); - if (res == 0) - System.out.println("Graph is not Eulerian"); - else if (res == 1) - System.out.println("Graph has an Eulerian Path"); - else - System.out.println("Graph has an Eulerian Circuit"); - } - - public static void main(String args[]) { - EulerianGraph g1 = new EulerianGraph(5); - g1.addEdge(0, 1); - g1.addEdge(1, 2); - g1.addEdge(2, 0); - g1.addEdge(0, 3); - g1.addEdge(3, 4); - g1.testEulerian(); - - EulerianGraph g2 = new EulerianGraph(3); - g2.addEdge(0, 1); - g2.addEdge(1, 2); - g2.addEdge(2, 0); - g2.testEulerian(); - } -} -``` \ No newline at end of file diff --git a/docs/graphs/flood-fill.md b/docs/graphs/flood-fill.md deleted file mode 100644 index 514bcb48b..000000000 --- a/docs/graphs/flood-fill.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -id: flood-fill -title: Flood Fill Algorithm -sidebar_label: Flood Fill Algorithm -description: "In this blog post, we'll explore the Flood Fill Algorithm, a popular technique used in computer graphics for determining connected regions, such as filling areas in images and solving puzzles like the paint bucket tool in graphics editing software." -tags: [dsa, algorithms, graphics, connected components] ---- -# Flood Fill Algorithm - -## Introduction - -The **Flood Fill Algorithm** is a method used in computer graphics to determine connected regions in a two-dimensional array (or grid) of pixels. It is commonly utilized for tasks such as filling areas in images, similar to the paint bucket tool in graphics editing software. The algorithm can also be applied in game development for tasks like determining the area of influence for a character or object. - -## How Flood Fill Works - -Flood fill operates by exploring adjacent pixels (or nodes) that share the same color or value as the starting pixel. The process can be performed using either a **recursive** or **iterative** approach. - -### Steps of the Algorithm: - -1. **Select a Starting Pixel**: Choose a pixel (or node) as the starting point for the fill operation. -2. **Check Color**: Compare the color of the current pixel with the target color (the color you want to fill). -3. **Fill Color**: If the current pixel matches the target color, change its color to the new color. -4. **Explore Neighbors**: Recursively (or iteratively) apply the same process to the neighboring pixels (up, down, left, right). -5. **Termination**: The algorithm stops when all connected pixels that match the target color have been filled. - -## Variants of Flood Fill - -There are two primary implementations of the Flood Fill algorithm: - -### 1. Recursive Flood Fill - -In the recursive version, the algorithm calls itself for each neighboring pixel. While this method is straightforward, it can lead to a stack overflow if the area to fill is too large due to deep recursion. - -#### Recursive Implementation in C++: - -```cpp -#include -#include -#include - -using namespace std; - -// Recursive Flood Fill Function -void floodFillRecursive(int x, int y, int targetColor, int newColor, vector>& image) { - // Out of bounds check - if (x < 0 || x >= image.size() || y < 0 || y >= image[0].size()) return; - // Color doesn't match - if (image[x][y] != targetColor) return; - - image[x][y] = newColor; // Fill the color - - // Recursively fill the neighboring pixels - floodFillRecursive(x + 1, y, targetColor, newColor, image); // Down - floodFillRecursive(x - 1, y, targetColor, newColor, image); // Up - floodFillRecursive(x, y + 1, targetColor, newColor, image); // Right - floodFillRecursive(x, y - 1, targetColor, newColor, image); // Left -} - -// Iterative Flood Fill Function -void floodFillIterative(int x, int y, int targetColor, int newColor, vector>& image) { - // Out of bounds check - if (image[x][y] != targetColor) return; // Color doesn't match - - int rows = image.size(); - int cols = image[0].size(); - queue> q; - q.push({x, y}); - - while (!q.empty()) { - auto [curX, curY] = q.front(); - q.pop(); - image[curX][curY] = newColor; // Fill the color - - // Explore neighbors - if (curX + 1 < rows && image[curX + 1][curY] == targetColor) q.push({curX + 1, curY}); // Down - if (curX - 1 >= 0 && image[curX - 1][curY] == targetColor) q.push({curX - 1, curY}); // Up - if (curY + 1 < cols && image[curX][curY + 1] == targetColor) q.push({curX, curY + 1}); // Right - if (curY - 1 >= 0 && image[curX][curY - 1] == targetColor) q.push({curX, curY - 1}); // Left - } -} - -// Function to print the image -void printImage(const vector>& image) { - for (const auto& row : image) { - for (const auto& pixel : row) { - cout << pixel << " "; - } - cout << endl; - } -} - -// Main function to demonstrate Flood Fill -int main() { - vector> image = { - {1, 1, 1, 1, 0}, - {1, 1, 0, 1, 1}, - {1, 1, 1, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 1, 1, 1} - }; - - int x = 1, y = 1; // Starting point - int newColor = 2; // New color to fill - int targetColor = image[x][y]; // Color to replace - - cout << "Original Image:" << endl; - printImage(image); - - // Using Recursive Flood Fill - floodFillRecursive(x, y, targetColor, newColor, image); - cout << "\nImage after Recursive Flood Fill:" << endl; - printImage(image); - - // Reset the image for Iterative Flood Fill demonstration - image = { - {1, 1, 1, 1, 0}, - {1, 1, 0, 1, 1}, - {1, 1, 1, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 1, 1, 1} - }; - - // Using Iterative Flood Fill - floodFillIterative(x, y, targetColor, newColor, image); - cout << "\nImage after Iterative Flood Fill:" << endl; - printImage(image); - - return 0; -} -``` -### 2. Iterative Flood Fill -The iterative version uses a queue (or stack) to keep track of the pixels that need to be processed. This approach is more memory-efficient for larger areas as it avoids deep recursion. - -### Iterative Implementation in C++: -```cpp - -void floodFillIterative(int x, int y, int targetColor, int newColor, vector>& image) { - if (image[x][y] != targetColor) return; // Color doesn't match - - int rows = image.size(); - int cols = image[0].size(); - queue> q; - q.push({x, y}); - - while (!q.empty()) { - auto [curX, curY] = q.front(); - q.pop(); - image[curX][curY] = newColor; // Fill the color - - // Explore neighbors - if (curX + 1 < rows && image[curX + 1][curY] == targetColor) q.push({curX + 1, curY}); // Down - if (curX - 1 >= 0 && image[curX - 1][curY] == targetColor) q.push({curX - 1, curY}); // Up - if (curY + 1 < cols && image[curX][curY + 1] == targetColor) q.push({curX, curY + 1}); // Right - if (curY - 1 >= 0 && image[curX][curY - 1] == targetColor) q.push({curX, curY - 1}); // Left - } -} -``` -### Applications of Flood Fill -Image Editing: Filling contiguous areas with color, as seen in paint applications. -Game Development: Used for detecting and filling areas of influence or terrain. -Pathfinding: Determining reachable areas in grid-based maps. -Geographical Mapping: Filling regions in geographical information systems (GIS). - -### Complexity Analysis - -### Time Complexity: O(N), where N is the number of pixels in the area to be filled. Each pixel is visited once. -### Space Complexity: -Recursive: O(H), where H is the maximum height of the recursion stack. -Iterative: O(N) in the worst case, if all pixels are connected. - -### Conclusion -The Flood Fill Algorithm is a fundamental technique in computer graphics and various other fields. Understanding its implementation and applications allows developers to efficiently solve problems related to connected regions, making it a valuable tool in both graphics programming and algorithm design. diff --git a/docs/graphs/floyd-algorithm.md b/docs/graphs/floyd-algorithm.md deleted file mode 100644 index 6dfab378c..000000000 --- a/docs/graphs/floyd-algorithm.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -id: flyod-algo -title: Floyd's-Algorithm -sidebar_label: Floyd's-Algorithm -description: "In this blog post, we'll explore the Floyd's-Algorithm, an efficient method to implement all pair shortest paths" -tags: [dsa, algorithms,all pair shortest paths] ---- - -# Floyd's Algorithm (Floyd-Warshall Algorithm) - -Floyd's algorithm, also known as the **Floyd-Warshall algorithm**, is a dynamic programming technique used to find the shortest paths between all pairs of vertices in a weighted graph. This algorithm works on both directed and undirected graphs, and it can handle graphs with negative edge weights (as long as there are no negative weight cycles). - -The algorithm iteratively improves the solution by checking if a path between two vertices can be improved by going through an intermediate vertex. It uses a 2D matrix to store the shortest path distances between every pair of vertices. - -## Key Features: -- **Time Complexity**: O(V³), where V is the number of vertices. -- **Space Complexity**: O(V²), as it stores the distances in a 2D array. -- Suitable for dense graphs due to its cubic time complexity. - -## Applications: -- Shortest path discovery in road networks. -- Network routing algorithms. -- Solving the transitive closure of a graph. - - - -# Code in C - -```c -#include -#include -int min(int v1, int v2) { - return (v1 >= v2) ? v2 : v1; - } - -int main() -{ - int W[10][10], D[10][10], n, i, j, k; - printf("Enter the number of Vertices: "); - scanf("%d", &n); - printf("Enter the Weight matrix of the given graph row-wise:\n"); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - scanf("%d", &W[i][j]); - D[i][j] = W[i][j]; - } - } - for (k = 0; k < n; k++) { - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - D[i][j] = min(D[i][j], D[i][k] + D[k][j]); - } - } - } - printf("Solution to All Pairs Shortest Distance Problem\n"); - printf("Using Floyd's Algorithm - Distance Matrix of the given graph is: \n"); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - printf("%d\t", D[i][j]); - } - printf("\n"); - } - return 0; -} -``` diff --git a/docs/graphs/graph-cloning.md b/docs/graphs/graph-cloning.md deleted file mode 100644 index 13cbd67c2..000000000 --- a/docs/graphs/graph-cloning.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -id: graph-cloning -title: Graph-cloning -sidebar_label: Graph-cloning -description: "The program is to return a deep copy of the graph, preserving the structure and values of its nodes." -tags: [dsa, algorithms, graph] ---- - -### Problem Statement: -You are given the reference of a node in a connected undirected graph. Return a deep copy (clone) of the graph. Each node in the graph contains a value and a list of its neighbors. There are n nodes in the graph each with a unique value from 0 to n-1. - -## Definition: -### Input -- A pointer/reference to a node of the original graph. Each node is represented as follows: - - An integer `val`, which is the unique value of the node. - - A list of pointers/references to neighboring nodes. - -### Output -- A pointer/reference to the corresponding cloned node of the graph. - -### Constraints -- The graph is guaranteed to be connected and undirected. -- The node values are unique integers ranging from `0` to `n - 1`, where `n` is the number of nodes in the graph. - -### Approach -To clone a graph, perform a depth-first search (DFS) or breadth-first search (BFS) starting from the given node, using a hash map to track visited nodes and ensure that each node is cloned only once, along with its neighbors. - -## Algorithm Steps - -1. **Check for Null Node**: - - If the input node is `null`, return `null`. - -2. **Check Visited Nodes**: - - If the node has already been cloned (exists in the visited map), return the clone from the map. - -3. **Create a Clone Node**: - - Create a new node with the same value as the original node. - - Store the clone in the visited map. - -4. **Clone Neighbors**: - - Iterate through each neighbor of the original node: - - Recursively call the clone function for each neighbor. - - Add the cloned neighbor to the `neighbors` list of the cloned node. - -5. **Return Cloned Node**: - - After cloning all neighbors, return the cloned node. - -## Time Complexity: -- The time complexity of the graph cloning algorithm is `O(V + E)`, where `V` is the number of vertices and `E` is the number of edges. Each node and its neighbors are visited once during the DFS traversal, making the process linear with respect to the graph's size. The use of a map to track visited nodes ensures efficient lookups. - -### Sample Input: - ``` - 0 - / \ - 1---2 - ``` -### Sample Output: - Original graph: - Node: 0 Neighbors: 1 2 - Node: 1 Neighbors: 0 2 - Node: 2 Neighbors: 0 1 - - Cloned graph: - Node: 0 Neighbors: 1 2 - Node: 1 Neighbors: 0 2 - Node: 2 Neighbors: 0 1 - -### C++ Implementation: - -```cpp -#include -#include -#include - -using namespace std; - -class Node { -public: - int val; - vector neighbors; - - Node(int _val) { - val = _val; - neighbors = vector(); - } -}; - -class Solution { -public: - unordered_map visited; - - Node* cloneGraph(Node* node) { - if (!node) return nullptr; - if (visited.find(node) != visited.end()) { - return visited[node]; - } - - Node* cloneNode = new Node(node->val); - visited[node] = cloneNode; - - for (Node* neighbor : node->neighbors) { - cloneNode->neighbors.push_back(cloneGraph(neighbor)); - } - - return cloneNode; - } -}; - -void printGraph(Node* node, unordered_map& printed) { - if (!node || printed[node]) return; - - printed[node] = true; // Mark this node as printed - cout << "Node: " << node->val << " Neighbors: "; - for (Node* neighbor : node->neighbors) { - cout << neighbor->val << " "; - } - cout << endl; - - for (Node* neighbor : node->neighbors) { - printGraph(neighbor, printed); - } -} - -int main() { - Node* node0 = new Node(0); - Node* node1 = new Node(1); - Node* node2 = new Node(2); - - node0->neighbors.push_back(node1); - node0->neighbors.push_back(node2); - node1->neighbors.push_back(node0); - node1->neighbors.push_back(node2); - node2->neighbors.push_back(node0); - node2->neighbors.push_back(node1); - - Solution solution; - Node* clonedGraph = solution.cloneGraph(node0); - - // Print the original graph - cout << "Original graph:" << endl; - unordered_map printed; - printGraph(node0, printed); - - // Print the cloned graph - cout << "\nCloned graph:" << endl; - printed.clear(); // Reset printed map for cloned graph - printGraph(clonedGraph, printed); - - return 0; -} -``` - diff --git a/docs/graphs/graph-coloring.md b/docs/graphs/graph-coloring.md deleted file mode 100644 index c7c36b7cc..000000000 --- a/docs/graphs/graph-coloring.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -id: graph-coloring -title: Graph Coloring using Greedy Algorithm -sidebar_label: Graph Coloring -description: "In this document, we explore the graph coloring problem and provide a C implementation using a greedy algorithm." -tags: [dsa, algorithms, graph coloring] ---- - -### C Code: Graph Coloring using Greedy Algorithm - -```c -#include -#include - -#define V 4 // Number of vertices in the graph - -// Function to check if the color assignment is valid for the given vertex -bool isSafe(int v, int graph[V][V], int color[], int c) { - for (int i = 0; i < V; i++) - if (graph[v][i] && color[i] == c) // Check if adjacent vertices have the same color - return false; - return true; -} - -// Recursive function to assign colors to vertices -bool graphColoringUtil(int graph[V][V], int m, int color[], int v) { - if (v == V) // All vertices are assigned a color - return true; - - for (int c = 1; c <= m; c++) { - if (isSafe(v, graph, color, c)) { - color[v] = c; - - // Recur to assign colors to the rest of the vertices - if (graphColoringUtil(graph, m, color, v + 1)) - return true; - - color[v] = 0; // Backtrack - } - } - - return false; -} - -// Main function to solve the m-coloring problem -bool graphColoring(int graph[V][V], int m) { - int color[V] = {0}; // Initialize all vertices as unassigned (0) - - if (!graphColoringUtil(graph, m, color, 0)) { - printf("Solution does not exist\n"); - return false; - } - - // Print the color assignment - printf("Solution exists with the following color assignment:\n"); - for (int i = 0; i < V; i++) - printf("Vertex %d ---> Color %d\n", i, color[i]); - - return true; -} - -// Main function -int main() { - // Example adjacency matrix for a graph - int graph[V][V] = { - {0, 1, 1, 1}, - {1, 0, 1, 0}, - {1, 1, 0, 1}, - {1, 0, 1, 0} - }; - - int m = 3; // Number of colors - graphColoring(graph, m); - - return 0; -} -``` -Key Concepts: - -➢ The graph coloring problem is a classic problem in graph theory where the goal is to assign colors to the vertices of a graph such that no two adjacent vertices share the same color. -➢ The greedy algorithm is a simple and efficient approach to solve the graph coloring problem. It works by iteratively assigning the smallest available color to each vertex while ensuring that no two adjacent vertices share the same color. - - -Here is an example: -Using the adjacency matrix: - -``` -graph[V][V] = { - {0, 1, 1, 1}, - {1, 0, 1, 0}, - {1, 1, 0, 1}, - {1, 0, 1, 0} -}; -``` - -- With m = 3 colors, a possible output is: - -``` -Solution exists with the following color assignment: -Vertex 0 ---> Color 1 -Vertex 1 ---> Color 2 -Vertex 2 ---> Color 3 -Vertex 3 ---> Color 1 -``` - -This result assigns colors such that no two adjacent vertices share the same color. - -### Limitations -- This approach is not efficient for large graphs, as it uses a backtracking technique that has exponential time complexity in the worst case. -- The solution may not be optimal for large and complex graphs. - -### Notes -- Adjust the adjacency matrix and m (number of colors) as needed to test different graphs. -This code can be modified to use a non-greedy approach for graphs where a minimal coloring is essential. \ No newline at end of file diff --git a/docs/graphs/graph-reversal.md b/docs/graphs/graph-reversal.md deleted file mode 100644 index 55996f276..000000000 --- a/docs/graphs/graph-reversal.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: graph-reversal -title: Graph-reversal -sidebar_label: Graph-reversal -description: "Reverse a directed graph so that the incoming edges will be converted to outgoing edges betwwen the same nodes." -tags: [dsa, algorithms, graph] ---- - -### Problem Statement: -Suppose we have a directed graph, we have to find its reverse so if an edge goes from i to j, it now goes from j to i. Here input will be an adjacency list, and if there are n nodes, the nodes will be (0, 1, ..., n-1). - - - -### Approach: -The approach to transposing a directed graph involves creating a new structure to hold reversed edges. For each vertex, the algorithm iterates through its outgoing edges and appends the vertex to the list of the target vertex in the new structure. This efficiently constructs the transposed graph in linear time relative to the number of vertices and edges. - -### Algorithm Steps: - -1. **Initialize Result Structure**: - - Create a list (or vector) `ans` of empty lists, with a size equal to the number of vertices in the graph. - -2. **Iterate Over Each Vertex**: - - For each vertex `i` in the graph: - - Retrieve the list of vertices that `i` points to (i.e., its outgoing edges). - -3. **Reverse Edges**: - - For each vertex `x` in the outgoing edges of vertex `i`: - - Append vertex `i` to the list at index `x` in `ans`. This step captures the transposition of the edge from `x` to `i`. - -4. **Return Transposed Graph**: - - Return the `ans` list, which now represents the transposed graph. - -These steps succinctly outline the algorithm's approach to transforming the directed graph into its transpose. -### Time Complexity: -- The time complexity of the program is `O(V + E)`, where `V` is the number of vertices and `E` is the number of edges, as it processes each vertex and edge once. - -### Sample Input: - -``` - {{1, 2}, {4}, {4}, {1, 2}, {3}} -``` -### Sample Output: - -``` - [[], [0, 3], [0, 3], [4], [1, 2]] -``` - - - -### Explanation of Sample: - -- The input `graph = [[1,2],[4],[4],[1,2],[3]]` represents a directed graph as an adjacency list where: - - - Node 0 points to nodes 1 and 2. - - Node 1 points to node 4. - - Node 2 points to node 4. - - Node 3 points to nodes 1 and 2. - - Node 4 points to node 3. - -- The reversed graph representation is `ans = [[], [0, 3], [0, 3], [4], [1, 2]]`, which means: - - - Node 0 has no outgoing edges. - - Nodes 1 and 2 have outgoing edges to nodes 0 and 3. - - Node 3 has an outgoing edge to node 4. - - Node 4 has outgoing edges to nodes 1 and 2. - -### Diagrammatic Representation of the input: -![directed_graph](https://github.com/user-attachments/assets/b3a8fc46-e508-45a0-bf97-458c2054f085) - -### Diagrammatic Representation of the output: -![directed_graph1](https://github.com/user-attachments/assets/7cb03236-3f1a-49cc-b2ce-6ef73aac7fa4) - - - -### C++ Implementation: - -```cpp - -#include -#include - -using namespace std; - -class Solution { -public: - vector> solve(vector>& graph) { - vector> ans(graph.size()); - for (int i = 0; i < graph.size(); ++i) { - for (int x : graph[i]) { - ans[x].push_back(i); - } - } - return ans; - } -}; - -int main() { - Solution ob; - vector> graph = {{1, 2}, {4}, {4}, {1, 2}, {3}}; - vector> result = ob.solve(graph); - - // Print the result - for (const auto& vec : result) { - cout << "[ "; - for (int val : vec) { - cout << val << " "; - } - cout << "]" << endl; - } - - return 0; -} -``` diff --git a/docs/graphs/hopcroft-karp-algorithm.md b/docs/graphs/hopcroft-karp-algorithm.md deleted file mode 100644 index e61eb69df..000000000 --- a/docs/graphs/hopcroft-karp-algorithm.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: hopcroft-karp -title: Hopcroft-Karp Algorithm -sidebar_label: Hopcroft-Karp Algorithm -description: "In this blog post, we'll explore the Hopcroft-Karp algorithm, an efficient method for finding the maximum matching in a bipartite graph." -tags: [dsa, algorithms, maximum matching] ---- - -### Definition: - -The **Hopcroft-Karp algorithm** is an efficient algorithm used to find the maximum matching in a bipartite graph. It works in two phases: finding augmenting paths using BFS and then updating the matching using DFS. - -### Characteristics: - -- **Bipartite Graph**: - - The algorithm operates on bipartite graphs, which consist of two disjoint sets of vertices such that every edge connects a vertex from one set to a vertex in the other. - -- **Augmenting Path**: - - An augmenting path is a path that starts and ends with unmatched vertices and alternates between edges not in the matching and edges in the matching. The existence of augmenting paths is key to finding a maximum matching. - -- **Efficiency**: - - The algorithm has a time complexity of `O(E √V)`, where `E` is the number of edges and `V` is the number of vertices. - -### Time Complexity: - -- **Time Complexity**: `O(E √V)` - The algorithm repeatedly finds augmenting paths and adjusts the matching, leading to efficient performance even for larger graphs. - -### Space Complexity: - -- **Space Complexity**: `O(V + E)` - The algorithm requires space for the adjacency list of the graph and additional space for storing the matching and visited nodes. - -### Algorithm Steps: - -1. **Initialization**: - - Create an empty matching and initialize all vertices as unmatched. - -2. **BFS for Augmenting Path**: - - Use a breadth-first search (BFS) to find all possible augmenting paths from unmatched vertices. - -3. **DFS for Augmenting Path**: - - Use a depth-first search (DFS) to traverse the found paths and update the matching. - -4. **Repeat**: - - Repeat the BFS and DFS until no more augmenting paths can be found. - -### Example: - -Consider a bipartite graph with two sets of vertices: -- Set U: {1, 2, 3} -- Set V: {`A`, `B`, `C`} - -Edges: -- (1, `A`) -- (2, `B`) -- (3, `C`) - -The maximum matching can be: -- (1, A) -- (2, B) -- (3, C) - -### Java Implementation: - -```java -import java.util.*; - -public class HopcroftKarp { - private static final int INF = Integer.MAX_VALUE; - private int[][] pair; - private int[] dist; - private List> adj; - - public HopcroftKarp(int uCount, int vCount) { - pair = new int[uCount + vCount + 1][2]; // pairs for U and V - dist = new int[uCount + 1]; - adj = new ArrayList<>(); - - for (int i = 0; i <= uCount + vCount; i++) { - adj.add(new ArrayList<>()); - } - } - - public void addEdge(int u, int v) { - adj.get(u).add(v + adj.size() / 2); // offset for v vertices - } - - private boolean bfs(int uCount) { - Queue queue = new LinkedList<>(); - for (int u = 1; u <= uCount; u++) { - if (pair[u][0] == 0) { - dist[u] = 0; - queue.offer(u); - } else { - dist[u] = INF; - } - } - dist[0] = INF; - - while (!queue.isEmpty()) { - int u = queue.poll(); - if (dist[u] < dist[0]) { - for (int v : adj.get(u)) { - if (dist[pair[v][1]] == INF) { - dist[pair[v][1]] = dist[u] + 1; - queue.offer(pair[v][1]); - } - } - } - } - return dist[0] != INF; - } - - private boolean dfs(int uCount) { - if (uCount == 0) { - return true; - } - for (int v : adj.get(uCount)) { - if (dist[pair[v][1]] == dist[uCount] + 1) { - if (dfs(pair[v][1])) { - pair[uCount][0] = v; - pair[v][1] = uCount; - return true; - } - } - } - dist[uCount] = INF; - return false; - } - - public int maximumMatching(int uCount) { - Arrays.fill(pair, new int[]{0, 0}); - int matching = 0; - - while (bfs(uCount)) { - for (int u = 1; u <= uCount; u++) { - if (pair[u][0] == 0 && dfs(u)) { - matching++; - } - } - } - return matching; - } - - public static void main(String[] args) { - int uCount = 3; // Number of vertices in set U - int vCount = 3; // Number of vertices in set V - - HopcroftKarp hk = new HopcroftKarp(uCount, vCount); - hk.addEdge(1, 0); // Edge from U1 to V1 - hk.addEdge(1, 1); // Edge from U1 to V2 - hk.addEdge(2, 1); // Edge from U2 to V2 - hk.addEdge(3, 2); // Edge from U3 to V3 - - int maxMatch = hk.maximumMatching(uCount); - System.out.println("Maximum matching is: " + maxMatch); - } -} \ No newline at end of file diff --git a/docs/graphs/kahn-algo.md b/docs/graphs/kahn-algo.md deleted file mode 100644 index 2b43ab8ad..000000000 --- a/docs/graphs/kahn-algo.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -id: kahn -title: Kahn's Algorithm -sidebar_label: Kahn's Algorithm -description: "In this blog post, we will delve into Kahn's Algorithm, an efficient method for topological sorting of a directed acyclic graph (DAG). This algorithm provides a way to find a linear ordering of vertices such that for every directed edge u → v, vertex u comes before vertex v." -tags: [dsa, algorithms, topological sorting] ---- - -## 📚 Kahn's Algorithm - -Kahn's Algorithm is an efficient method for performing topological sorting on a Directed Acyclic Graph (DAG). It provides a way to order the vertices of the graph such that for every directed edge \( u \rightarrow v \), vertex \( u \) comes before vertex \( v \) in the ordering. This algorithm is particularly useful in scenarios where certain tasks must be completed before others, such as scheduling problems or resolving dependencies. - -### 📝 How Kahn's Algorithm Works - -Kahn's Algorithm operates based on the concept of in-degrees of vertices in a directed graph. The in-degree of a vertex is the number of edges directed towards it. The algorithm follows these steps: - -1. **Calculate In-Degrees**: - - Initialize an array `inDegree` to keep track of the in-degrees of all vertices. - - Traverse the graph and populate the `inDegree` array. - -2. **Initialize the Queue**: - - Create a queue to hold all vertices with an in-degree of 0 (i.e., vertices that have no dependencies). - -3. **Process the Queue**: - - While the queue is not empty, perform the following: - - Dequeue a vertex \( u \) and append it to the topological ordering. - - For each outgoing edge from \( u \) to vertex \( v \), reduce the in-degree of \( v \) by 1. - - If the in-degree of \( v \) becomes 0, enqueue \( v \). - -4. **Check for Cycles**: - - After processing all vertices, if the number of vertices in the topological ordering is less than the total number of vertices in the graph, a cycle exists, and a topological sort is not possible. - -### 🛠️ Time Complexity - -The time complexity of Kahn's Algorithm is \( O(V + E) \), where \( V \) is the number of vertices and \( E \) is the number of edges in the graph. This efficiency makes Kahn's Algorithm suitable for large graphs. - -### 🖥️ C++ Implementation - -Here’s how Kahn's Algorithm can be implemented in C++: - -```cpp -#include -#include -#include - -using namespace std; - -vector kahnTopologicalSort(int V, vector>& adj) { - vector inDegree(V, 0); - vector topologicalOrder; - - // Calculate in-degrees of all vertices - for (int u = 0; u < V; u++) { - for (int v : adj[u]) { - inDegree[v]++; - } - } - - // Initialize the queue with vertices of in-degree 0 - queue q; - for (int i = 0; i < V; i++) { - if (inDegree[i] == 0) { - q.push(i); - } - } - - // Process the queue - while (!q.empty()) { - int u = q.front(); - q.pop(); - topologicalOrder.push_back(u); - - for (int v : adj[u]) { - inDegree[v]--; - if (inDegree[v] == 0) { - q.push(v); - } - } - } - - // Check if there was a cycle - if (topologicalOrder.size() != V) { - return {}; // Return an empty vector if there's a cycle - } - - return topologicalOrder; // Return the topological order -} - -int main() { - int V = 6; // Number of vertices - vector> adj(V); - - // Example graph edges (0->1, 0->2, etc.) - adj[5].push_back(2); - adj[5].push_back(0); - adj[4].push_back(0); - adj[4].push_back(1); - adj[2].push_back(3); - adj[3].push_back(1); - - vector result = kahnTopologicalSort(V, adj); - - if (result.empty()) { - cout << "Graph has a cycle, topological sort not possible." << endl; - } else { - cout << "Topological Sort: "; - for (int u : result) { - cout << u << " "; - } - cout << endl; - } - - return 0; -} - - -``` -### 🔍 Applications of Kahn's Algorithm -Task Scheduling: Used in scenarios where certain tasks must be completed before others. -Build Systems: Helps manage dependencies between files and targets. -Course Scheduling: Useful in academic settings to manage prerequisite courses. -Version Control Systems: Resolves dependencies in source code versioning. - -### ⚖️ Advantages and Limitations -Advantages: -Provides a clear and efficient method for topological sorting. -Handles large graphs effectively with -O(V+E) time complexity. - -### Limitations: -Only applicable to Directed Acyclic Graphs (DAGs); -Cannot be used for graphs with cycles. - - - -### 📝 Conclusion -Kahn's Algorithm is a powerful tool for performing topological sorting in directed acyclic graphs. Its efficiency and straightforward implementation make it a preferred choice in many applications requiring task management based on dependencies. Understanding this algorithm can significantly aid in solving various computational problems involving directed graphs. \ No newline at end of file diff --git a/docs/graphs/kosaraju-algorithm.md b/docs/graphs/kosaraju-algorithm.md deleted file mode 100644 index 8af244ba0..000000000 --- a/docs/graphs/kosaraju-algorithm.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: kosaraju -title: Kosaraju's Algorithm -sidebar_label: Kosaraju's Algorithm -description: "In this blog post, we'll explore Kosaraju's Algorithm, an efficient algorithm used to find all Strongly Connected Components (SCCs) in a directed graph." -tags: [dsa, algorithms, strongly connected components] ---- - -### Definition: - -Kosaraju's Algorithm is an efficient **depth-first search (DFS)-based** algorithm used to find all **Strongly Connected Components (SCCs)** in a directed graph. A strongly connected component is a maximal subgraph where every vertex is reachable from every other vertex in that subgraph. - -### Characteristics: - -- **Strongly Connected Components (SCCs)**: - - A **strongly connected component (SCC)** is a subset of vertices such that every vertex is reachable from any other vertex within that subset. - -- **Two Pass DFS**: - - Kosaraju's algorithm performs **two depth-first searches** (DFS) on the graph. The first DFS is used to determine the finishing order of vertices. The second DFS is done on the transpose (reversed) graph to find SCCs in the order of decreasing finish times. - -- **Transpose Graph**: - - The **transpose of a directed graph** is a graph in which all the edges are reversed. - -- **Linear Time Complexity**: - - Kosaraju's algorithm works in **O(V + E)** time, where `V` is the number of vertices and `E` is the number of edges. This makes it an efficient algorithm for large graphs. - -### Time Complexity: - -- **Best, Average, and Worst Case: O(V + E)** - The algorithm performs two depth-first searches and a graph reversal, all of which run in linear time with respect to the number of vertices and edges. - -### Space Complexity: - -- **Space Complexity: O(V + E)** - The algorithm requires space for storing the graph, its transpose, and auxiliary structures like the visited array and stack. This results in O(V + E) space complexity. - -### Steps of Kosaraju's Algorithm: - -1. **First DFS on the Original Graph**: - - Perform a DFS on the original graph, keeping track of the **finishing times** of each vertex. This information is used to order vertices for the second DFS. - -2. **Transpose the Graph**: - - Reverse the direction of all edges in the graph to create the **transpose graph**. - -3. **Second DFS on the Transpose Graph**: - - Perform a DFS on the transpose graph, processing vertices in decreasing order of their finishing times from the first DFS. Each DFS tree formed in this step corresponds to a **strongly connected component**. - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -class Graph { -public: - int V; // Number of vertices - vector> adj; // Adjacency list - - Graph(int V) { - this->V = V; - adj.resize(V); - } - - // Add edge to the graph - void addEdge(int u, int v) { - adj[u].push_back(v); - } - - // First DFS to fill stack with vertices based on finish times - void DFS(int v, vector& visited, stack& Stack) { - visited[v] = true; - for (int i : adj[v]) - if (!visited[i]) - DFS(i, visited, Stack); - Stack.push(v); - } - - // DFS on transpose graph to find SCCs - void DFSUtil(int v, vector& visited) { - visited[v] = true; - cout << v << " "; - for (int i : adj[v]) - if (!visited[i]) - DFSUtil(i, visited); - } - - // Function to get the transpose of the graph - Graph getTranspose() { - Graph gT(V); - for (int v = 0; v < V; v++) { - for (int i : adj[v]) - gT.adj[i].push_back(v); - } - return gT; - } - - // Function to find and print all SCCs - void findSCCs() { - stack Stack; - - // Step 1: Fill the stack with vertices according to their finishing times - vector visited(V, false); - for (int i = 0; i < V; i++) - if (!visited[i]) - DFS(i, visited, Stack); - - // Step 2: Transpose the graph - Graph gT = getTranspose(); - - // Step 3: Process all vertices in the order of their finishing times - fill(visited.begin(), visited.end(), false); // Reset visited array - while (!Stack.empty()) { - int v = Stack.top(); - Stack.pop(); - - // Perform DFS on the transpose graph if vertex is not visited - if (!visited[v]) { - gT.DFSUtil(v, visited); - cout << endl; - } - } - } -}; - -int main() { - Graph g(5); - g.addEdge(1, 0); - g.addEdge(0, 2); - g.addEdge(2, 1); - g.addEdge(0, 3); - g.addEdge(3, 4); - - cout << "Strongly Connected Components (SCCs) are: \n"; - g.findSCCs(); - - return 0; -} -``` \ No newline at end of file diff --git a/docs/graphs/kruskal-algorithm.md b/docs/graphs/kruskal-algorithm.md deleted file mode 100644 index e1498c8e2..000000000 --- a/docs/graphs/kruskal-algorithm.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -id: kruskal -title: Kruskal's Algorithm -sidebar_label: Kruskal's Algorithm -description: "In this blog post, we'll explore Kruskal's Algorithm, a greedy algorithm used to find the Minimum Spanning Tree in a graph." -tags: [dsa, algorithms, minimum spanning tree] ---- - - -### Definition: - -Kruskal's algorithm is a **greedy algorithm** used to find the Minimum Spanning Tree (MST) of a graph. The MST is a subset of the edges of a connected, weighted, and undirected graph that connects all the vertices together, without any cycles and with the minimum possible total edge weight. - -### Characteristics: - -- **Greedy Approach**: - - Kruskal's algorithm works by selecting the smallest edge and ensuring that no cycles are formed in the process. It greedily adds edges in increasing order of weight. - -- **Disjoint Set Data Structure**: - - The algorithm uses a **Disjoint Set Union (DSU)** or **Union-Find** data structure to efficiently determine whether adding an edge will form a cycle in the growing spanning tree. - -- **Edge-Based Algorithm**: - - Kruskal's algorithm focuses on edges rather than vertices, sorting them by weight and picking the smallest ones that do not create a cycle. - -- **Applicable to Sparse Graphs**: - - Kruskal's algorithm is often preferred for sparse graphs, where the number of edges is much smaller than the number of vertices squared. - -### Time Complexity: - -- **Best, Average, and Worst Case: O(E log E)** - Kruskal's algorithm sorts all the edges in ascending order of their weights, and the most time-consuming operation is sorting, which takes O(E log E), where E is the number of edges. - -### Space Complexity: - -- **Space Complexity: O(V + E)** - The algorithm requires extra space for the parent and rank arrays used by the Union-Find data structure, resulting in O(V + E) space, where V is the number of vertices and E is the number of edges. - -### C++ Implementation: - -```cpp -#include -#include -#include -using namespace std; - -struct Edge { - int u, v, weight; - bool operator<(Edge const& other) { - return weight < other.weight; - } -}; - -vector parent, rank; - -int find(int v) { - if (v == parent[v]) - return v; - return parent[v] = find(parent[v]); -} - -void unite(int a, int b) { - a = find(a); - b = find(b); - if (a != b) { - if (rank[a] < rank[b]) - swap(a, b); - parent[b] = a; - if (rank[a] == rank[b]) - rank[a]++; - } -} - -int kruskal(int n, vector& edges) { - sort(edges.begin(), edges.end()); - parent.resize(n); - rank.resize(n); - for (int i = 0; i < n; i++) { - parent[i] = i; - rank[i] = 0; - } - - int mst_weight = 0; - for (Edge e : edges) { - if (find(e.u) != find(e.v)) { - mst_weight += e.weight; - unite(e.u, e.v); - } - } - - return mst_weight; -} - -int main() { - int n = 4; // number of vertices - vector edges = { - {0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4} - }; - - int mst_weight = kruskal(n, edges); - cout << "Weight of the Minimum Spanning Tree: " << mst_weight << endl; - - return 0; -} -``` - -### Summary: - -Kruskal's algorithm is an efficient way to find the Minimum Spanning Tree of a graph by considering the smallest edges first. It uses the Union-Find data structure to avoid forming cycles and guarantees that the resulting spanning tree has the minimum possible total weight. The algorithm is particularly useful for sparse graphs and is widely used in network design and optimization problems. diff --git a/docs/graphs/minimum-cost-spanning-tree.md b/docs/graphs/minimum-cost-spanning-tree.md deleted file mode 100644 index c413771ed..000000000 --- a/docs/graphs/minimum-cost-spanning-tree.md +++ /dev/null @@ -1,244 +0,0 @@ ---- -id: minimum-spanning-tree -title: Minimum Spanning Tree Algorithms -sidebar_label: Minimum Spanning Tree -description: "In this blog post, we'll explore Minimum Spanning Tree (MST) algorithms, specifically Prim's and Kruskal's algorithms, which are used to find the minimum cost spanning tree in a weighted graph." -tags: [dsa, algorithms, graph algorithms, minimum spanning tree] - ---- - -A Minimum Spanning Tree (MST) of a connected, undirected graph is a spanning tree that has the smallest possible total edge weight among all spanning trees. An MST connects all vertices in the graph without cycles and with the minimum sum of edge weights. - - - -## Characteristics: - -- **Optimal Substructure**: - MST exhibits optimal substructure, meaning that an MST of a graph contains the MSTs of its subgraphs. - -- **Greedy Approach**: - Both Prim's and Kruskal's algorithms use a greedy strategy to find the MST. They build the MST by adding edges in a way that minimizes the total weight while ensuring no cycles are formed. - -## Prim's Algorithm: - -1. **Initialization**: - Start with an arbitrary vertex and mark it as part of the MST. Initialize a priority queue (min-heap) to keep track of the edges. - -2. **Edge Selection**: - Continuously extract the edge with the smallest weight from the priority queue that connects a vertex in the MST to a vertex outside the MST. Add this edge to the MST and mark the new vertex as part of the MST. - -3. **Repeat**: - Repeat the process until all vertices are included in the MST. - - - -## Time Complexity of Prim's Algorithm: - -- **Time Complexity**: $O(E \log V)$ - The complexity arises from maintaining the priority queue for the edges, where E is the number of edges and V is the number of vertices. - -### Kruskal's Algorithm: - -1. **Edge Sorting**: - Start by sorting all the edges in the graph in ascending order based on their weights. - -2. **Union-Find Structure**: - Use a union-find (disjoint-set) data structure to keep track of connected components. - -3. **Edge Selection**: - Iterate through the sorted edge list, adding edges to the MST if they do not form a cycle (i.e., if they connect two different components). - -4. **Repeat**: - Continue until the MST contains exactly \(V-1\) edges, where V is the number of vertices. - -## Time Complexity of Kruskal's Algorithm: - -- **Time Complexity**: $O(E \log E + E \log V)$ - The complexity comes from sorting the edges and performing union-find operations. - -## Example: - -Consider the following graph with vertices and weighted edges: - - - -## Step-by-Step Execution: - -### Prim's Algorithm: - -1. **Initialization**: - Start from vertex A and add edges to the priority queue: - - Edges: `{(A, B, 1), (A, C, 3)}` - -2. **Edge Selection**: - - Select edge `(A, B, 1)`, MST: `{(A, B)}`. - - Add edges from B: `{(B, C, 4), (B, D, 2)}`. - -3. **Repeat**: - - Select edge `(B, D, 2)`, MST: `{(A, B), (B, D)}`. - - Add edges from D: `{(D, C, 5)}`. - - Select edge `(A, C, 3)`, MST: `{(A, B), (B, D), (A, C)}`. - -The final MST contains edges: `{(A, B), (B, D), (A, C)}` with a total weight of `1 + 2 + 3 = 6`. - -### Kruskal's Algorithm: - -1. **Edge Sorting**: - Sorted edges: `{(A, B, 1), (B, D, 2), (A, C, 3), (B, C, 4), (D, C, 5)}`. - -2. **Edge Selection**: - - Select `(A, B, 1)`, MST: `{(A, B)}`. - - Select `(B, D, 2)`, MST: `{(A, B), (B, D)}`. - - Select `(A, C, 3)`, MST: `{(A, B), (B, D), (A, C)}`. - -The final MST contains edges: `{(A, B), (B, D), (A, C)}` with a total weight of `1 + 2 + 3 = 6`. - -## C++ Implementation of Prim's Algorithm: - -```cpp -#include -#include -#include -#include - -using namespace std; - -// Prim's Algorithm -void primMST(vector>>& graph, int V) { - vector key(V, INT_MAX); - vector inMST(V, false); - priority_queue, vector>, greater>> pq; - - key[0] = 0; - pq.push({0, 0}); // {key, vertex} - - while (!pq.empty()) { - int u = pq.top().second; - pq.pop(); - inMST[u] = true; - - for (auto& neighbor : graph[u]) { - int v = neighbor.first; - int weight = neighbor.second; - - if (!inMST[v] && weight < key[v]) { - key[v] = weight; - pq.push({key[v], v}); - } - } - } - - cout << "Minimum Spanning Tree weights:\n"; - for (int i = 1; i < V; ++i) - cout << "Vertex " << i << " has key value: " << key[i] << "\n"; -} - -int main() { - int V = 5; // Number of vertices - vector>> graph(V); - - // Graph edges (u, v, weight) - graph[0].push_back({1, 1}); - graph[1].push_back({0, 1}); - graph[1].push_back({3, 2}); - graph[3].push_back({1, 2}); - graph[3].push_back({4, 5}); - graph[4].push_back({3, 5}); - graph[0].push_back({2, 3}); - graph[2].push_back({0, 3}); - graph[1].push_back({2, 4}); - graph[2].push_back({1, 4}); - - primMST(graph, V); - - return 0; -} -``` - -## C++ Implementation of Kruskal Algorithm: - -```cpp - -#include -#include -#include - -using namespace std; - -// Disjoint Set Union (Union-Find) -class DisjointSet { - vector parent, rank; - -public: - DisjointSet(int n) { - parent.resize(n); - rank.resize(n, 0); - for (int i = 0; i < n; ++i) parent[i] = i; - } - - int find(int u) { - if (u != parent[u]) - parent[u] = find(parent[u]); // Path compression - return parent[u]; - } - - void unionSets(int u, int v) { - int rootU = find(u); - int rootV = find(v); - if (rootU != rootV) { - if (rank[rootU] > rank[rootV]) - parent[rootV] = rootU; - else if (rank[rootU] < rank[rootV]) - parent[rootU] = rootV; - else { - parent[rootV] = rootU; - rank[rootU]++; - } - } - } -}; - -// Kruskal's Algorithm -void kruskalMST(vector>& edges, int V) { - sort(edges.begin(), edges.end()); // Sort edges based on weight - DisjointSet ds(V); - vector> mstEdges; - - for (auto& edge : edges) { - int weight, u, v; - tie(weight, u, v) = edge; - - if (ds.find(u) != ds.find(v)) { - ds.unionSets(u, v); - mstEdges.push_back(edge); - } - } - - cout << "Edges in Minimum Spanning Tree:\n"; - for (auto& edge : mstEdges) { - int weight, u, v; - tie(weight, u, v) = edge; - cout << u << " -- " << v << " == " << weight << "\n"; - } -} - -int main() { - int V = 5; // Number of vertices - vector> edges = { - {1, 0, 1}, - {2, 1, 3}, - {3, 0, 2}, - {4, 1, 2}, - {5, 3, 4} - }; - - kruskalMST(edges, V); - return 0; -} -``` - - - -## Conclusion: - -Prim's and Kruskal's algorithms. Both algorithms efficiently find the MST of a weighted graph, ensuring that all vertices are connected with the minimum total edge weight. Understanding these algorithms is fundamental for various applications in computer science, including network design, clustering, and resource management. diff --git a/docs/graphs/practice-problems.md b/docs/graphs/practice-problems.md deleted file mode 100644 index da34d3eaf..000000000 --- a/docs/graphs/practice-problems.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -id: practice-problems-for-graphs -title: Practice Problems for Graphs -sidebar_label: Practice Problems -sidebar_position: 1 -description: Practice problems for Graphs to help you understand the concepts better. -tags: [Graph, Practice Problems, BFS, DFS, Connected Components, Dijkstra's, Union Find, Minimum Spanning Tree, Topological Sort, Floyd-Warshall, Bellman-Ford] ---- - -### BFS Problems - -- [Flood Fill](https://leetcode.com/problems/flood-fill/) -- [Number of Islands](https://leetcode.com/problems/number-of-islands/) -- [Word Ladder I](https://leetcode.com/problems/word-ladder/) -- [Word Ladder II](https://leetcode.com/problems/word-ladder-ii/) -- [Evaluate Division](https://leetcode.com/problems/evaluate-division/) -- [Get Watched Videos by Your Friends](https://leetcode.com/problems/get-watched-videos-by-your-friends/) -- [Cut Off Trees for Golf Event](https://leetcode.com/problems/cut-off-trees-for-golf-event/) - -### DFS Problems - -- [Number of Islands](https://leetcode.com/problems/number-of-islands/) -- [Flood Fill](https://leetcode.com/problems/flood-fill/) -- [Longest Increasing Path in a Matrix](https://leetcode.com/problems/longest-increasing-path-in-a-matrix/) -- [Evaluate Division](https://leetcode.com/problems/evaluate-division/) -- [Robot Room Cleaner](https://leetcode.com/problems/robot-room-cleaner/) -- [Most Stones Removed with Same Row or Column](https://leetcode.com/problems/most-stones-removed-with-same-row-or-column/) -- [Reconstruct Itinerary](https://leetcode.com/problems/reconstruct-itinerary/) -- [Tree Diameter](https://leetcode.com/problems/tree-diameter/) -- [Accounts Merge](https://leetcode.com/problems/accounts-merge/) - -### Connected Components Problems - -- [Number of Provinces](https://leetcode.com/problems/number-of-provinces/) -- [Number of Connected Components in an Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) -- [Number of Operations to Make Network Connected](https://leetcode.com/problems/number-of-operations-to-make-network-connected/) -- [Accounts Merge](https://leetcode.com/problems/accounts-merge/) -- [Critical Connections in a Network](https://leetcode.com/problems/critical-connections-in-a-network/) - -### Dijkstra's Problems - -- [Path With Maximum Minimum Value](https://leetcode.com/problems/path-with-maximum-minimum-value/) -- [Network Delay Time](https://leetcode.com/problems/network-delay-time/) -- [Path with Maximum Probability](https://leetcode.com/problems/path-with-maximum-probability/) -- [Path With Minimum Effort](https://leetcode.com/problems/path-with-minimum-effort/) -- [Cheapest Flights Within K Stops](https://leetcode.com/problems/cheapest-flights-within-k-stops/) - -### Union Find Problems -- [Number of Islands](https://leetcode.com/problems/number-of-islands/) -- [Largest Component Size by Common Factor](https://leetcode.com/problems/largest-component-size-by-common-factor/) -- [Most Stones Removed with Same Row or Column](https://leetcode.com/problems/most-stones-removed-with-same-row-or-column/) -- [Number of Connected Components in an Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) - -### Minimum Spanning Tree Problems - -- [Connecting Cities With Minimum Cost](https://leetcode.com/problems/connecting-cities-with-minimum-cost/) -- [Min Cost to Connect All Points](https://leetcode.com/problems/min-cost-to-connect-all-points/) - -### Topological Sort Problems - -- [Course Schedule](https://leetcode.com/problems/course-schedule/) -- [Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) -- [Sequence Reconstruction](https://leetcode.com/problems/sequence-reconstruction/) -- [Alien Dictionary](https://leetcode.com/problems/alien-dictionary/solution/) - -### Floyd-Warshall Problems - -- [Find the City With the Smallest Number of Neighbors at a Threshold Distance](https://leetcode.com/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/) -- [Network Delay Time](https://leetcode.com/problems/network-delay-time/) - -### Bellman-Ford Problems - -- [Network Delay Time](https://leetcode.com/problems/network-delay-time/) \ No newline at end of file diff --git a/docs/graphs/prims-algorithm.md b/docs/graphs/prims-algorithm.md deleted file mode 100644 index 7f0c0417a..000000000 --- a/docs/graphs/prims-algorithm.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -id: prims-algorithm -title: "Prim's Algorithm" -sidebar_label: "Prim's Algorithm" -sidebar_position: 2 -description: "Prim's algorithm is a greedy algorithm that finds the Minimum Spanning Tree (MST)" -tags: [Graph Theory, prims-algorithm, Minimum Spanning Tree, Greedy Algorithms, Optimization] ---- - -Prim's Algorithm is a greedy algorithm for finding the Minimum Spanning Tree (MST) of a connected, weighted graph. It connects all vertices with the minimum total edge weight, making it useful in network design, clustering, and various optimization tasks. - -## Introduction - -In graph theory, a Minimum Spanning Tree (MST) is a subset of the edges that connects all vertices in a graph with the minimum possible total edge weight and without any cycles. Prim's Algorithm builds the MST by growing a single tree and repeatedly selecting the smallest edge that connects a vertex in the tree to a vertex outside of it. - -## Characteristics of Prim's Algorithm - -1. **Greedy Nature**: Always selects the smallest available edge at every step. -2. **Optimal Substructure**: The MST problem has an optimal substructure, where an optimal solution can be built from optimal solutions of its subproblems. -3. **Dense Graphs**: Prim's works well with dense graphs with a large number of edges. - - -## How Prim's Algorithm Works -1. **Initialization:** - - Start from an arbitrary vertex and mark it as part of the MST. - - Use a priority queue (min-heap) to store the edges connected to the MST vertices. - -2. **Edge Selection:** - - While not all vertices are in the MST: - - Extract the smallest edge from the priority queue. - - Add the corresponding vertex to the MST. - - Update the priority queue with edges connected to the new vertex. - -3. **Termination:** - - The algorithm terminates when all vertices have been included in the MST. - -## Step-by-Step Execution -Here’s how Prim’s Algorithm can be executed on a simple graph: - -```mermaid -graph TB - B -->|2| A - B -->|4| C - B -->|3| D - A ---|1| D - A --- C - C -->|5| D -``` - -- **Execution Steps:** -1. Start with vertex **A**. -2. Add edge **(A-D)**, weight **1** (smallest edge). -3. Add edge **(A-B)**, weight **2**. -4. Add edge **(B-E)**, weight **3**. -5. Add edge **(A-C)**, weight **4**. - -The final MST includes edges **(A-D)**, **(A-B)**, **(B-E)**, and **(A-C)** with a total weight of **10**. - -## Time Complexity -- The time complexity of Prim's Algorithm is **O(E log V)** when using a priority queue (min-heap), where **E** is the number of edges and **V** is the number of vertices. With an adjacency matrix, it can be reduced to **O(V^2)**. - -## Applications -- **Network Design:** Used in designing computer and telecommunications networks for optimal connectivity. -- **Cabling and Wiring:** Efficiently plans the laying of cables between buildings or cities. -- **Cluster Analysis:** Forms the basis for hierarchical clustering in data analysis. -- **Urban Planning:** Helps design efficient transportation networks and utilities in urban environments. - -## Pseudocode - -```python -1. Initialize a key array to track the minimum weight edge for each vertex. -2. Initialize a boolean array to track the vertices included in the MST. -3. Set the key of the starting vertex to 0. -4. For each vertex not yet in the MST: - a. Pick the vertex with the minimum key value. - b. Add it to the MST. - c. Update the key values of its adjacent vertices. -5. Repeat until all vertices are included in the MST. -``` - -## Advantages of Prim's Algorithm - -- **Greedy and Simple**: Prim's algorithm follows a straightforward greedy approach, making it simple to understand and implement. - -- **Efficient for Dense Graphs**: Prim's algorithm performs well for dense graphs, especially when used with advanced data structures like binary heaps to optimize edge selection. - -- **Ensures Connectivity**: Prim's algorithm guarantees a connected graph, which is particularly useful when graph connectivity is crucial in the problem domain. - -## Limitations - -- **Graph Must Be Connected**: Prim's algorithm only works on connected graphs. If the graph is disconnected, Prim's cannot generate a minimum spanning tree (MST). - -- **May Not Be Efficient for Sparse Graphs**: For graphs with few edges (sparse graphs), Kruskal's algorithm might be more efficient than Prim's algorithm due to the differences in how they explore the graph and manage edge processing. - -## Prim's Algorithm vs. Kruskal's Algorithm - -| Feature | Prim's Algorithm | Kruskal's Algorithm | -|------------------------|--------------------------------------------------------|--------------------------------------------------------------------------| -| **Approach** | Greedy: Start from a vertex and grow the MST | Greedy: Sort edges and add the smallest edge without forming cycles | -| **Data Structure Used**| Adjacency list, priority queue (min-heap) | Union-Find/Disjoint Set data structure | -| **Graph Type** | Dense graphs (many edges) | Sparse graphs (few edges) | -| **Starting Point** | Requires a starting vertex | No starting vertex, works directly with edges | -| **Time Complexity** | $O(E log V)$ using binary heap and adjacency list | $O(E log E)$ due to sorting edges | - -Both algorithms can effectively find the MST, but the choice between them depends on the graph's density and specific use cases. - -## Conclusion - -Prim's Algorithm is a powerful method for finding the Minimum Spanning Tree in a graph. Its greedy approach, efficiency, and wide range of applications make it a fundamental algorithm in computer science and network design. Understanding how Prim's Algorithm works enables developers and researchers to tackle various problems in optimization and connectivity. diff --git a/docs/graphs/shortest-path-algorithms/A-star-algorithm.md b/docs/graphs/shortest-path-algorithms/A-star-algorithm.md deleted file mode 100644 index feb9f9a00..000000000 --- a/docs/graphs/shortest-path-algorithms/A-star-algorithm.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -id: a-star-algo -title: A*-Algorithm -sidebar_label: A*-Algorithm -description: "In this blog post, we'll explore the A* Algorithm, an efficient method for pathfinding and graph traversal." -tags: [dsa, algorithms, pathfinding, graph traversal] ---- - -# A* Algorithm - -The **A* algorithm** is a popular and efficient pathfinding and graph traversal algorithm used to find the shortest path from a starting node to a goal node in a weighted graph. It combines the advantages of Dijkstra's algorithm and Greedy Best-First Search, making it suitable for various applications in computer science and artificial intelligence. - -The A* algorithm employs a heuristic to estimate the cost to reach the goal, allowing it to prioritize promising paths while ensuring optimality. - -## Key Features: -- **Time Complexity**: O(b^d), where b is the branching factor and d is the depth of the optimal solution. -- **Space Complexity**: O(b^d) due to maintaining the open and closed lists. -- Guarantees optimal paths if an admissible heuristic is used. - -## Applications: -- Robotics for navigation and movement planning. -- Game development for AI character movement. -- GPS systems for route finding. -- Network routing protocols. - -# Code in Python - -```python -import heapq - -def a_star(graph, start, goal): - # Create a priority queue - open_set = [] - heapq.heappush(open_set, (0, start)) - - came_from = {} - g_score = {node: float('inf') for node in graph} - g_score[start] = 0 - - f_score = {node: float('inf') for node in graph} - f_score[start] = heuristic(start, goal) - - while open_set: - current = heapq.heappop(open_set)[1] - - if current == goal: - return reconstruct_path(came_from, current) - - for neighbor in graph[current]: - tentative_g_score = g_score[current] + graph[current][neighbor] - - if tentative_g_score < g_score[neighbor]: - came_from[neighbor] = current - g_score[neighbor] = tentative_g_score - f_score[neighbor] = g_score[neighbor] + heuristic(neighbor, goal) - - if neighbor not in [i[1] for i in open_set]: - heapq.heappush(open_set, (f_score[neighbor], neighbor)) - - return [] - -def heuristic(node, goal): - # Implement a heuristic function (e.g., Manhattan distance, Euclidean distance) - pass - -def reconstruct_path(came_from, current): - total_path = [current] - - while current in came_from: - current = came_from[current] - total_path.append(current) - return total_path[::-1] -``` -# Code in Java -```java -import java.util.*; - -class Node { - int x, y; - double g, h; - Node parent; - - public double f() { - return g + h; - } -} - -public class AStar { - public static double heuristic(Node a, Node b) { - return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); // Euclidean distance - } - - public static List getNeighbors(Node node) { - return Arrays.asList( - new Node(node.x + 1, node.y, 0, 0, null), - new Node(node.x - 1, node.y, 0, 0, null), - new Node(node.x, node.y + 1, 0, 0, null), - new Node(node.x, node.y - 1, 0, 0, null) - ); - } - - public static List aStar(Node start, Node goal) { - PriorityQueue openList = new PriorityQueue<>(Comparator.comparingDouble(Node::f)); - Set closedList = new HashSet<>(); - - start.g = 0; - start.h = heuristic(start, goal); - openList.add(start); - - while (!openList.isEmpty()) { - Node currentNode = openList.poll(); - - if (currentNode.x == goal.x && currentNode.y == goal.y) { - List path = new ArrayList<>(); - for (Node n = currentNode; n != null; n = n.parent) { - path.add(n); - } - Collections.reverse(path); - return path; - } - - closedList.add(currentNode); - - for (Node neighbor : getNeighbors(currentNode)) { - if (closedList.contains(neighbor)) - continue; - - double tentativeG = currentNode.g + 1; // Assuming a cost of 1 for movement - - if (tentativeG < neighbor.g || neighbor.g == 0) { - neighbor.g = tentativeG; - neighbor.h = heuristic(neighbor, goal); - neighbor.parent = currentNode; - - openList.add(neighbor); - } - } - } - return Collections.emptyList(); // Return empty if no path found - } -} -``` -## Time Complexity -The time complexity of A* search algorithm depends on the heuristic used. In the worst case, it can be -𝑂(𝑏𝑑), where 𝑏 is the branching factor and -𝑑 is the depth of the solution. - -## Space Complexity -The space complexity is 𝑂(𝑏𝑑) as well, since the open list can potentially store all nodes in the search space. - -## Conclusion -The A* search algorithm is a versatile and efficient pathfinding algorithm that effectively balances between cost and heuristic information to find the shortest path. Its performance can vary significantly based on the choice of the heuristic function, making it crucial to choose one that accurately estimates the distance to the goal. \ No newline at end of file diff --git a/docs/graphs/shortest-path-algorithms/Prims-algorithm.md b/docs/graphs/shortest-path-algorithms/Prims-algorithm.md deleted file mode 100644 index 678a610a4..000000000 --- a/docs/graphs/shortest-path-algorithms/Prims-algorithm.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -id: Prims -title: "Prim's Algorithm" -sidebar_label: "Prim's Algorithm" -description: "In this blog post, we'll explore Prim's Algorithm, a greedy algorithm used to find the Minimum Spanning Tree in a graph." -tags: [dsa, algorithms, minimum spanning tree] ---- - - -### Definition: - -Prim's algorithm is a **greedy algorithm** used to find the Minimum Spanning Tree (MST) of a connected, weighted, and undirected graph. The MST is a subset of the edges that connects all the vertices together with the minimum total edge weight and without forming any cycles. - -### Characteristics: - -- **Greedy Approach**: - - Prim's algorithm starts from a selected node and grows the MST by adding the smallest edge from the MST to a new vertex, continuing until all vertices are included. - -- **Vertex-Based Algorithm**: - - Prim's algorithm focuses on growing the MST vertex by vertex, unlike Kruskal's which focuses on edges. The algorithm adds the shortest edge connected to the growing MST that connects a new vertex. - -- **Priority Queue**: - - Prim's algorithm often uses a priority queue (or a min-heap) to efficiently find the smallest edge. This helps in selecting the minimum weight edge at each step. - -- **Applicable to Dense Graphs**: - -Prim's algorithm is preferred for dense graphs where the number of edges is large relative to the number of vertices. - -### Time Complexity: - -- **Best, Average, and Worst Case: O(E log V)** - Using a priority queue, Prim's algorithm achieves a time complexity of O(E log V), where E is the number of edges and V is the number of vertices. - -### Space Complexity: - -- **Space Complexity: O(V + E)** - The algorithm requires additional space for the priority queue and arrays tracking visited vertices and minimum weights, resulting in a space complexity of O(V + E). - -### C++ Implementation: - -```cpp -#include -#include -#include -#include -using namespace std; - -typedef pair pii; - -int prim(int n, vector>& adj) { - priority_queue, greater> pq; - vector inMST(n, false); - vector key(n, INT_MAX); - int mst_weight = 0; - - key[0] = 0; - pq.push({0, 0}); // {weight, vertex} - - while (!pq.empty()) { - int u = pq.top().second; - int weight = pq.top().first; - pq.pop(); - - if (inMST[u]) - continue; - - inMST[u] = true; - mst_weight += weight; - - for (auto &[w, v] : adj[u]) { - if (!inMST[v] && key[v] > w) { - key[v] = w; - pq.push({key[v], v}); - } - } - } - - return mst_weight; -} - -int main() { - int n = 4; // number of vertices - vector> adj(n); - adj[0].push_back({10, 1}); - adj[0].push_back({6, 2}); - adj[0].push_back({5, 3}); - adj[1].push_back({10, 0}); - adj[1].push_back({15, 3}); - adj[2].push_back({6, 0}); - adj[2].push_back({4, 3}); - adj[3].push_back({5, 0}); - adj[3].push_back({15, 1}); - adj[3].push_back({4, 2}); - - int mst_weight = prim(n, adj); - cout << "Weight of the Minimum Spanning Tree: " << mst_weight << endl; - - return 0; -} -``` - -### Python Implementation: - -```python -import heapq - -def prim(n, adj): - # Initialize the priority queue (min-heap) and other helper arrays - pq = [(0, 0)] # (weight, vertex) - in_mst = [False] * n - key = [float('inf')] * n - key[0] = 0 - mst_weight = 0 - - while pq: - # Extract the minimum weight vertex - weight, u = heapq.heappop(pq) - - if in_mst[u]: - continue - - # Mark the vertex as part of the MST - in_mst[u] = True - mst_weight += weight - - # Check all adjacent vertices - for w, v in adj[u]: - if not in_mst[v] and key[v] > w: - key[v] = w - heapq.heappush(pq, (key[v], v)) - - return mst_weight - -# Example usage: -n = 4 # Number of vertices -adj = [ - [(10, 1), (6, 2), (5, 3)], # Edges from vertex 0 - [(10, 0), (15, 3)], # Edges from vertex 1 - [(6, 0), (4, 3)], # Edges from vertex 2 - [(5, 0), (15, 1), (4, 2)] # Edges from vertex 3 -] - -mst_weight = prim(n, adj) -print("Weight of the Minimum Spanning Tree:", mst_weight) -``` - -### Summary: - -Prim's algorithm is a powerful tool for finding the Minimum Spanning Tree of a graph by growing the tree one vertex at a time. Using a priority queue allows the algorithm to efficiently pick the smallest edge from the MST to a new vertex, ensuring the minimum total weight. It is especially useful for dense graphs and has applications in various network design and optimization problems. diff --git a/docs/graphs/shortest-path-algorithms/_category_.json b/docs/graphs/shortest-path-algorithms/_category_.json deleted file mode 100644 index 0fab03cbe..000000000 --- a/docs/graphs/shortest-path-algorithms/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Shortest Path Algorithms", - "position": 1, - "link": { - "type": "generated-index", - "description": "Learn the most important Shortest Path Algorithms." - } - } \ No newline at end of file diff --git a/docs/graphs/shortest-path-algorithms/bell-man-ford-algorithm.md b/docs/graphs/shortest-path-algorithms/bell-man-ford-algorithm.md deleted file mode 100644 index cdc2fbf38..000000000 --- a/docs/graphs/shortest-path-algorithms/bell-man-ford-algorithm.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -id: bellman-ford -title: Bellman-Ford Algorithm -sidebar_label: Bellman-Ford Algorithm -description: "In this blog post, we'll dive into the Bellman-Ford Algorithm, a fundamental graph algorithm used to find the shortest path between nodes in a graph, even with negative weights." -tags: [dsa, algorithms, shortest path] ---- - -## Introduction -The **Bellman-Ford Algorithm** is an algorithm used to find the shortest path from a single source vertex to all other vertices in a weighted graph. Unlike Dijkstra’s Algorithm, Bellman-Ford works with graphs that have negative weights. However, it does not work with graphs containing negative weight cycles. - -The Bellman-Ford algorithm is useful in scenarios where we expect the graph to have negative edge weights and need to detect negative weight cycles. - -## Implementation - -Let’s see how the Bellman-Ford Algorithm can be implemented in Java: - -# Code in Java - -```java -// A Java program to find the shortest path using Bellman-Ford algorithm - public class BellmanFord { - // A class to represent a weighted edge in a graph - class Edge { - int src, dest, weight; - Edge() { - src = dest = weight = 0; - } - } - - int V, E; - Edge edge[]; - - // Constructor - BellmanFord(int v, int e) { - V = v; - E = e; - edge = new Edge[e]; - for (int i = 0; i < e; ++i) - edge[i] = new Edge(); - } - - // Function to find the shortest path - void bellmanFord(BellmanFord graph, int src) { - int V = graph.V, E = graph.E; - int dist[] = new int[V]; - - // Initialize distances from src to all other vertices as INFINITE - for (int i = 0; i < V; ++i) - dist[i] = Integer.MAX_VALUE; - dist[src] = 0; - - // Relax all edges |V| - 1 times - for (int i = 1; i < V; ++i) { - for (int j = 0; j < E; ++j) { - int u = graph.edge[j].src; - int v = graph.edge[j].dest; - int weight = graph.edge[j].weight; - if (dist[u] != Integer.MAX_VALUE && dist[u] + weight < dist[v]) - dist[v] = dist[u] + weight; - } - } - - // Check for negative-weight cycles - for (int j = 0; j < E; ++j) { - int u = graph.edge[j].src; - int v = graph.edge[j].dest; - int weight = graph.edge[j].weight; - if (dist[u] != Integer.MAX_VALUE && dist[u] + weight < dist[v]) { - System.out.println("Graph contains negative weight cycle"); - return; - } - } - - // Print the distance array - printArr(dist, V); - } - - // Utility function to print the solution - void printArr(int dist[], int V) { - System.out.println("Vertex Distance from Source"); - for (int i = 0; i < V; ++i) - System.out.println(i + "\t\t" + dist[i]); - } - - } -``` -Let’s see how the Bellman-Ford Algorithm can be implemented in C++: - -Code in C++ -```cpp - #include - using namespace std; - - struct Edge { - int src, dest, weight; - }; - - void bellmanFord(int V, int E, vector& edges, int src) { - vector dist(V, INT_MAX); - dist[src] = 0; - - // Relax all edges V-1 times - for (int i = 1; i <= V - 1; i++) { - for (int j = 0; j < E; j++) { - int u = edges[j].src; - int v = edges[j].dest; - int weight = edges[j].weight; - if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) { - dist[v] = dist[u] + weight; - } - } - } - - // Check for negative-weight cycles - for (int j = 0; j < E; j++) { - int u = edges[j].src; - int v = edges[j].dest; - int weight = edges[j].weight; - if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) { - cout << "Graph contains negative weight cycle" << endl; - return; - } - } - - // Print the distance array - cout << "Vertex Distance from Source:" << endl; - for (int i = 0; i < V; i++) - cout << i << "\t\t" << dist[i] << endl; - } - - int main() { - int V, E; - cin >> V >> E; - - vector edges(E); - - for (int i = 0; i < E; i++) { - cin >> edges[i].src >> edges[i].dest >> edges[i].weight; - } - - int src; - cin >> src; - - bellmanFord(V, E, edges, src); - - return 0; - } -``` - - -## Time complexity: - -Bellman-Ford Algorithm: O(V * E), where V is the number of vertices, and E is the number of edges. - - -## Points to Remember: - -- The Bellman-Ford algorithm can handle graphs with negative weight edges. - - - -- It detects negative weight cycles and reports if one exists. - - - -- The algorithm is slower than Dijkstra’s, but it works with graphs that have negative weights. diff --git a/docs/graphs/shortest-path-algorithms/dijkstra-algorithm.md b/docs/graphs/shortest-path-algorithms/dijkstra-algorithm.md deleted file mode 100644 index 850a08fbf..000000000 --- a/docs/graphs/shortest-path-algorithms/dijkstra-algorithm.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -id: dijkstra -title: Dijkstra's Algorithm -sidebar_label: Dijkstra's Algorithm -description: "In this blog post, we'll dive into Dijkstra's Algorithm, a fundamental graph algorithm used to find the shortest path between nodes in a graph." - -tags: [dsa, algorithms, shortest path] ---- - - -## Introduction -Dijkstra's Algorithm is a popular algorithm used to find the shortest path from a source node to all other nodes in a weighted graph. It guarantees the shortest path only when all edge weights are non-negative. The algorithm uses a greedy approach and is commonly used in network routing protocols and GPS systems. - - - -## Implementation - -Let’s see how Dijkstra's Algorithm can be implemented in Java: -# Code in Java - -```java - //let the source node be 'src' - int[] dist = new int[n]; // n represents the number of vertices - boolean[] visited = new boolean[n]; // to track visited nodes - - //initialize distances to infinity and source to 0 - for (int i = 0; i < n; i++) { - dist[i] = Integer.MAX_VALUE; - visited[i] = false; - } - dist[src] = 0; - - for (int i = 0; i < n - 1; i++) { - // find the node with the minimum distance from the source - int u = findMinDistance(dist, visited); - - // mark the chosen node as visited - visited[u] = true; - - // update the distance values of the adjacent vertices of the picked node - for (int v = 0; v < n; v++) { - if (!visited[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE - && dist[u] + graph[u][v] < dist[v]) { - dist[v] = dist[u] + graph[u][v]; - } - } - } - - // Output the shortest distances from the source node - for (int i = 0; i < n; i++) { - System.out.println("Shortest distance from node " + src + " to node " + i + " is " + dist[i]); - } - - // Helper function to find the vertex with the minimum distance - private int findMinDistance(int[] dist, boolean[] visited) { - int min = Integer.MAX_VALUE, minIndex = -1; - - for (int i = 0; i < dist.length; i++) { - if (!visited[i] && dist[i] <= min) { - min = dist[i]; - minIndex = i; - } - } - return minIndex; - } -``` -Let’s see how Dijkstra's Algorithm can be implemented in C++: -# Code in C++ - -```cpp - #include - using namespace std; - - // singel src shortest path algorithm - - vector dijkstra(vector>> &adj, int src){ - priority_queue, vector>, greater>> minHeap; - minHeap.push({0, src}); - vector dist(adj.size(), 1e9); - dist[src] = 0; - while(!minHeap.empty()){ - auto top = minHeap.top(); - minHeap.pop(); - int pDist = top.first, pVert = top.second; // pDist -> dist from src to that node. - for(auto it: adj[pVert]){ - int dis = it.second, vert = it.first; - int d = dis + pDist; - if(d < dist[vert]){ - dist[vert] = d; - minHeap.push({d, vert}); - } - } - } - return dist; - } - - int main() { - int n, e; - cin >> n >> e; - int src; - cin >> src; - vector>> adj(n); - for (int i = 0; i < e; i++){ - int x; - cin >> x; - pair temp; - cin >> temp.first >> temp.second; - adj[x].push_back(temp); - adj[temp.first].push_back({x, temp.second}); // undirected - } - vector dist = dijkstra(adj, src); - for (int i = 0; i < dist.size(); i++) - cout << dist[i] << " "; - cout << endl; - return 0; - } -``` - -In this algorithm, we use a greedy approach where we always pick the unvisited node with the minimum distance from the source node and update the distances to its neighbors. - - -## Time complexity: - -Dijkstra's Algorithm: O(V²) (with an adjacency matrix, where V is the number of vertices)
    -With Priority Queue: O((V + E) log V), where E is the number of edges - -## Points to Remember: - -- Dijkstra's Algorithm is used to find the shortest path in a graph with non-negative edge weights. - -- Works for both directed and undirected graphs. - -- Faster than other algorithms for sparse graphs (when using priority queue). - -- The graph must have non-negative edge weights for Dijkstra's Algorithm to work correctly. - diff --git a/docs/graphs/shortest-path-algorithms/floyd-warshall-algorithm.md b/docs/graphs/shortest-path-algorithms/floyd-warshall-algorithm.md deleted file mode 100644 index bef34b77e..000000000 --- a/docs/graphs/shortest-path-algorithms/floyd-warshall-algorithm.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: floyd-warshall -title: Floyd-Warshall Algorithm -sidebar_label: Floyd-Warshall Algorithm -description: "In this blog post, we'll dive into the Floyd-Warshall Algorithm, a fundamental graph algorithm used to find the shortest path between all pairs of nodes in a graph." -tags: [dsa, algorithms, shortest path] ---- - -## Introduction -The **Floyd-Warshall Algorithm** is an algorithm used to find the shortest paths between all pairs of vertices in a weighted graph. Unlike Dijkstra's or Bellman-Ford algorithms, which find the shortest path from a single source, the Floyd-Warshall algorithm computes the shortest paths between all pairs of vertices. The algorithm works with graphs that have negative weights but does not work with negative weight cycles. - - - -## Implementation - -Let’s see how the Floyd-Warshall Algorithm can be implemented in Java: - -# Code in Java - -```java - public class FloydWarshall { - final static int INF = 99999, V = 4; - - void floydWarshall(int graph[][]) { - int dist[][] = new int[V][V]; - int i, j, k; - - // Initialize the solution matrix same as the input graph matrix - for (i = 0; i < V; i++) - for (j = 0; j < V; j++) - dist[i][j] = graph[i][j]; - - // Add all vertices one by one to the set of intermediate vertices - for (k = 0; k < V; k++) { - for (i = 0; i < V; i++) { - for (j = 0; j < V; j++) { - if (dist[i][k] + dist[k][j] < dist[i][j]) - dist[i][j] = dist[i][k] + dist[k][j]; - } - } - } - - // Print the shortest distance matrix - printSolution(dist); - } - - void printSolution(int dist[][]) { - System.out.println("The following matrix shows the shortest distances between every pair of vertices:"); - for (int i = 0; i < V; ++i) { - for (int j = 0; j < V; ++j) { - if (dist[i][j] == INF) - System.out.print("INF "); - else - System.out.print(dist[i][j] + " "); - } - System.out.println(); - } - } - } -``` - -Let’s see how the Floyd-Warshall Algorithm can be implemented in C++: - -Code in C++ - -```cpp - #include - using namespace std; - - #define INF 99999 - #define V 4 - - void floydWarshall(int graph[][V]) { - int dist[V][V], i, j, k; - - // Initialize the solution matrix same as input graph matrix - for (i = 0; i < V; i++) - for (j = 0; j < V; j++) - dist[i][j] = graph[i][j]; - - // Add all vertices one by one to the set of intermediate vertices - for (k = 0; k < V; k++) { - for (i = 0; i < V; i++) { - for (j = 0; j < V; j++) { - if (dist[i][k] + dist[k][j] < dist[i][j]) - dist[i][j] = dist[i][k] + dist[k][j]; - } - } - } - - // Print the shortest distance matrix - printSolution(dist); - } - - void printSolution(int dist[][V]) { - cout << "The following matrix shows the shortest distances between every pair of vertices:\n"; - for (int i = 0; i < V; i++) { - for (int j = 0; j < V; j++) { - if (dist[i][j] == INF) - cout << "INF "; - else - cout << dist[i][j] << " "; - } - cout << endl; - } - } -``` - -## Time complexity: -Floyd-Warshall Algorithm: O(V³), where V is the number of vertices. - -## Points to Remember: -- The Floyd-Warshall algorithm finds the shortest paths between all pairs of vertices. - -- It can handle negative weights, but it cannot detect negative weight cycles. - -- The algorithm is simple and easy to implement, but its time complexity makes it impractical for large graphs. diff --git a/docs/graphs/tarjans-algo.md b/docs/graphs/tarjans-algo.md deleted file mode 100644 index 46344589f..000000000 --- a/docs/graphs/tarjans-algo.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -id: tarjans-algorithm -title: "Tarjan's Algorithm" -sidebar_label: "Tarjan's Algorithm" -sidebar_position: 3 -description: "Tarjan's algorithm is an efficient method for finding strongly connected components in a directed graph." -tags: [Graph Theory, tarjans-algorithm, Strongly Connected Components, Depth-First Search] ---- -## Tarjan's Algorithm: -Tarjan's Algorithm is a graph traversal technique used to find all strongly connected components (SCCs) in a directed graph. It employs depth-first search (DFS) and uses a low-link value to keep track of the smallest reachable vertex. - -## Introduction - -In graph theory, a strongly connected component (SCC) of a directed graph is a maximal subgraph where every vertex is reachable from every other vertex. Tarjan's Algorithm efficiently identifies all SCCs using a single DFS traversal, making it suitable for various applications in network analysis, compiler design, and more. - -## Characteristics of Tarjan's Algorithm - -1. **Single DFS Traversal**: The algorithm performs a single depth-first search traversal of the graph. -2. **Low-Link Values**: It uses low-link values to determine the smallest reachable vertex in the DFS tree. -3. **Stack-Based**: The algorithm utilizes a stack to track vertices and identify components. - -## How Tarjan's Algorithm Works - -1. **Initialization**: - - Maintain an index to assign unique identifiers to vertices during DFS traversal. - - Use a low-link array to track the lowest index reachable from each vertex. - - Use a stack to keep track of vertices in the current DFS path. - -2. **DFS Traversal**: - - For each unvisited vertex, assign it an index and initialize its low-link value. - - Perform DFS on its neighbors: - - If a neighbor is unvisited, recursively apply Tarjan’s algorithm. - - Update the low-link value based on the neighbor's low-link value. - - If the neighbor is in the stack, update the low-link value to reflect its index. - -3. **Component Identification**: - - After visiting all neighbors, check if the vertex is a root of an SCC: - - If it is, pop vertices from the stack until the vertex itself is reached, marking them as part of the same component. - -4. **Termination**: - - The algorithm terminates when all vertices have been visited, and all SCCs have been identified. - -## Step-by-Step Execution - -Consider a simple directed graph: - -```mermaid -graph TD - A --> B - B --> C - C --> A - B --> D - D --> E - E --> D -``` - - -### Code Implementation: - -```java - import java.util.ArrayList; -import java.util.List; -import java.util.Stack; - -public class TarjanAlgorithm { - private int index = 0; - private int[] indices; - private int[] lowLink; - private boolean[] onStack; - private Stack stack; - private List> sccs; - - public List> tarjansAlgorithm(List> graph) { - int n = graph.size(); - indices = new int[n]; - lowLink = new int[n]; - onStack = new boolean[n]; - stack = new Stack<>(); - sccs = new ArrayList<>(); - - for (int v = 0; v < n; v++) { - if (indices[v] == 0) { - strongconnect(v, graph); - } - } - - return sccs; - } - - private void strongconnect(int v, List> graph) { - indices[v] = lowLink[v] = ++index; - stack.push(v); - onStack[v] = true; - - for (int w : graph.get(v)) { - if (indices[w] == 0) { - // Successor w has not yet been visited; recurse on it - strongconnect(w, graph); - lowLink[v] = Math.min(lowLink[v], lowLink[w]); - } else if (onStack[w]) { - // Successor w is in stack and hence in the current SCC - lowLink[v] = Math.min(lowLink[v], indices[w]); - } - } - - // If v is a root node, pop the stack and generate an SCC - if (lowLink[v] == indices[v]) { - List scc = new ArrayList<>(); - int w; - do { - w = stack.pop(); - onStack[w] = false; - scc.add(w); - } while (w != v); - sccs.add(scc); - } - } - - public static void main(String[] args) { - // Create a sample directed graph - List> graph = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - graph.add(new ArrayList<>()); - } - - // Add edges (directed) - graph.get(0).add(1); - graph.get(1).add(2); - graph.get(2).add(0); - graph.get(1).add(3); - graph.get(3).add(4); - graph.get(4).add(3); - - TarjanAlgorithm tarjan = new TarjanAlgorithm(); - List> sccs = tarjan.tarjansAlgorithm(graph); - - System.out.println("Strongly Connected Components:"); - for (List scc : sccs) { - System.out.println(scc); - } - } -} - -``` -## Time Complexity -The time complexity of Tarjan's Algorithm is O(V + E), where V is the number of vertices and E is the number of edges, as it performs a single DFS traversal of the graph. - - -## Applications -Compiler Optimization: Used to identify strongly connected components in control flow graphs. -Social Network Analysis: Helps to identify communities within networks where every member is reachable from every other member. -Web Page Ranking: Analyzes link structures of web pages for search engine optimization. - -## Advantages of Tarjan's Algorithm - -Efficiency: The algorithm efficiently finds all SCCs in linear time with respect to the number of vertices and edges. -Simplicity: The algorithm is straightforward and can be easily implemented with basic graph traversal techniques. -Memory Usage: Tarjan's algorithm uses minimal additional memory since it operates with a stack and a few arrays. - -## Limitations -Directed Graphs Only: Tarjan's Algorithm is designed specifically for directed graphs and cannot be applied to undirected graphs. -Complex Implementation for Beginners: Understanding the algorithm's use of low-link values and stack management may be challenging for those new to graph theory. - -## Conclusion -Tarjan's Algorithm is a powerful and efficient method for identifying strongly connected components in directed graphs. Its linear time complexity and elegant design make it a fundamental algorithm in computer science, particularly in areas like network analysis, compiler design, and graph theory. Understanding and implementing Tarjan's Algorithm enables developers and researchers to effectively solve problems related to connectivity and component analysis in graphs. \ No newline at end of file diff --git a/docs/graphs/warshall-algo.md b/docs/graphs/warshall-algo.md deleted file mode 100644 index 1f1a2c493..000000000 --- a/docs/graphs/warshall-algo.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -id: warshall-algo -title: Warshall's-Algorithm -sidebar_label: Warshall's-Algorithm -description: "In this blog post, we'll explore the Warshall's-Algorithm, an efficient method to Compute the transitive closure of a given directed graph" -tags: [dsa, algorithms,transitive closure] ---- - -# Warshall's Algorithm - -Warshall's algorithm is a graph-based algorithm used to compute the **transitive closure** of a directed graph. It determines whether a path exists between any two vertices by updating a reachability matrix. The algorithm works by iteratively checking if a vertex can be reached indirectly through another vertex. - -Unlike shortest-path algorithms, Warshall's algorithm is concerned only with reachability, not the distance between vertices. - -## Key Features: -- **Time Complexity**: O(V³), where V is the number of vertices. -- **Space Complexity**: O(V²), as it stores the reachability information in a matrix. -- Suitable for determining reachability in directed graphs. - -## Applications: -- Finding reachability in network analysis. -- Identifying connected components in a graph. -- Transitive closure in databases. - - - -# Code in C - -```c - -#include -#include -int main() - { - int A[10][10], T[10][10], n, i, j, k; - printf("Enter the number of Vertices: "); - scanf("%d", &n); - printf("Enter the adjacency matrix of the given graph row-wise:\n"); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - scanf("%d", &A[i][j]); - T[i][j] = A[i][j]; - } - } - for (k = 0; k < n; k++) { - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - T[i][j] = T[i][j] || (T[i][k] && T[k][j]); - } - } - } - printf("Transitive Closure of the given graph is:\n"); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - printf("%d\t", T[i][j]); - } - printf("\n"); - } - return 0; -} -``` diff --git a/docs/greedy-algorithms/Graph-Coloring.md b/docs/greedy-algorithms/Graph-Coloring.md deleted file mode 100644 index ebf94092b..000000000 --- a/docs/greedy-algorithms/Graph-Coloring.md +++ /dev/null @@ -1,228 +0,0 @@ ---- -id: graph-coloring -title: Graph Coloring Algorithm -sidebar_label: Graph Coloring -description: "In this blog post, we'll explore Graph Coloring, Graph coloring refers to the problem of coloring vertices of a graph in such a way that no two adjacent vertices have the same color. " -tags: [dsa, algorithms, greedy algorithms,graphs] ---- - - -### Definition: -Graph coloring is the process of assigning colors to the vertices of a graph such that no two adjacent vertices share the same color. The greedy algorithm for graph coloring assigns colors to vertices one by one, choosing the smallest available color at each step. While not always optimal, it offers an efficient solution for many graph coloring problems. - -### Characteristics: -- **Greedy Approach**: - Graph coloring can be approached using a greedy algorithm. Vertices are colored one by one, assigning the smallest available color that doesn't violate the condition of adjacent vertices having the same color. - -- **Non-Optimality**: - The greedy approach doesn’t always yield the minimum number of colors (chromatic number), but it provides a valid coloring in a time-efficient manner. - -### Steps Involved: -1. **Sort Vertices by Degree**: - Optionally, vertices can be ordered by their degrees (highest degree first) to potentially improve the result. - -2. **Assign Colors Greedily**: - Starting from the first vertex, assign the smallest available color that isn’t used by its adjacent vertices. - -3. **Check and Color Remaining Vertices**: - Continue coloring each vertex using the same logic until all vertices are colored. - -### Problem Statement: - Given a graph with `n` vertices, assign colors to the vertices such that no two adjacent vertices share the same color, while using the fewest number of colors. - -### Time Complexity: -- **Best, Average, and Worst Case: $O(n + m)$** - Where `n` is the number of vertices and `m` is the number of edges. This is dominated by traversing vertices and their adjacent edges - -### Space Complexity: -- **Space Complexity: $O(n)$** - Space is required to store the colors assigned to each vertex. - -### Example: -Consider the following Graph: -- Vertices: `{A, B, C, D}` -- Edges: `{(A, B), (A, C), (B, D), (C, D)}` - -Step-by-Step Execution: - -1. **Assign color 1 to A**: - -2. **Assign color 2 to B (adjacent to A)**: - -3. **Assign color 2 to C (non-adjacent to B but adjacent to A)**: - -4. **Assign color 1 to D (adjacent to both B and C)**: - -Total Colors Used: `2` - - - - - - -### C++ Implementation: -```cpp -#include -#include -#include - -using namespace std; - -// Function to perform greedy graph coloring -void greedyGraphColoring(vector>& graph, int V) { - // Array to store the color assigned to each vertex - vector result(V, -1); - - // Assign the first color to the first vertex - result[0] = 0; - - // Temporary array to keep track of available colors for vertices - vector available(V, false); - - // Assign colors to remaining vertices - for (int u = 1; u < V; u++) { - // Mark colors of adjacent vertices as unavailable - for (int i = 0; i < graph[u].size(); i++) { - int adjacent = graph[u][i]; - if (result[adjacent] != -1) { - available[result[adjacent]] = true; - } - } - - // Find the first available color - int cr; - for (cr = 0; cr < V; cr++) { - if (!available[cr]) { - break; - } - } - - // Assign the found color to vertex u - result[u] = cr; - - // Reset the available array for the next iteration - for (int i = 0; i < graph[u].size(); i++) { - int adjacent = graph[u][i]; - if (result[adjacent] != -1) { - available[result[adjacent]] = false; - } - } - } - - // Print the result - cout << "Vertex\tColor\n"; - for (int u = 0; u < V; u++) { - cout << u << "\t" << result[u] << endl; - } -} - -int main() { - // Number of vertices - int V = 4; - - // Adjacency list representing the graph - vector> graph(V); - - // Define the edges of the graph - graph[0].push_back(1); // Edge A-B - graph[0].push_back(2); // Edge A-C - graph[1].push_back(0); // Edge B-A - graph[1].push_back(3); // Edge B-D - graph[2].push_back(0); // Edge C-A - graph[2].push_back(3); // Edge C-D - graph[3].push_back(1); // Edge D-B - graph[3].push_back(2); // Edge D-C - - // Call the greedy coloring function - greedyGraphColoring(graph, V); - - return 0; -} - -``` - -### Java Implementation: -```java -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class GraphColoring { - - // Function to perform greedy graph coloring - public static void greedyGraphColoring(List> graph, int V) { - // Array to store the color assigned to each vertex - int[] result = new int[V]; - Arrays.fill(result, -1); - - // Assign the first color to the first vertex - result[0] = 0; - - // Temporary array to keep track of available colors for vertices - boolean[] available = new boolean[V]; - - // Assign colors to remaining vertices - for (int u = 1; u < V; u++) { - // Mark colors of adjacent vertices as unavailable - for (int adjacent : graph.get(u)) { - if (result[adjacent] != -1) { - available[result[adjacent]] = true; - } - } - - // Find the first available color - int cr; - for (cr = 0; cr < V; cr++) { - if (!available[cr]) { - break; - } - } - - // Assign the found color to vertex u - result[u] = cr; - - // Reset the available array for the next iteration - for (int adjacent : graph.get(u)) { - if (result[adjacent] != -1) { - available[result[adjacent]] = false; - } - } - } - - // Print the result - System.out.println("Vertex\tColor"); - for (int u = 0; u < V; u++) { - System.out.println(u + "\t" + result[u]); - } - } - - public static void main(String[] args) { - // Number of vertices - int V = 4; - - // Adjacency list representing the graph - List> graph = new ArrayList<>(); - for (int i = 0; i < V; i++) { - graph.add(new ArrayList<>()); - } - - // Define the edges of the graph - graph.get(0).add(1); // Edge A-B - graph.get(0).add(2); // Edge A-C - graph.get(1).add(0); // Edge B-A - graph.get(1).add(3); // Edge B-D - graph.get(2).add(0); // Edge C-A - graph.get(2).add(3); // Edge C-D - graph.get(3).add(1); // Edge D-B - graph.get(3).add(2); // Edge D-C - - // Call the greedy coloring function - greedyGraphColoring(graph, V); - } -} - - -``` - -### Summary: -Graph coloring is the process of assigning colors to vertices of a graph such that no two adjacent vertices share the same color. It has practical applications in areas like scheduling, register allocation, and map coloring. The problem is NP-complete, meaning there is no known efficient algorithm for finding the minimum number of colors. However, the greedy algorithm offers an approximation by assigning colors sequentially to each vertex while avoiding conflicts. Though it doesn't guarantee the minimum number of colors, it ensures an upper bound of `d+1` colors, where `d` is the maximum degree of any vertex in the graph. diff --git a/docs/greedy-algorithms/job-scheduling.md b/docs/greedy-algorithms/job-scheduling.md deleted file mode 100644 index f0a021d57..000000000 --- a/docs/greedy-algorithms/job-scheduling.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -id: job-scheduling -title: Job Scheduling with Deadline -sidebar_label: Job-Scheduling -description: "The problem aims to maximize total profit by scheduling a set of jobs, each with a deadline and profit, ensuring selected jobs are completed within their deadlines." -tags: [dsa, algorithms, greedy algorithms] ---- - -### Definition: -The Job Scheduling problem is a classical optimization problem where a set of jobs needs to be scheduled such that the profit is maximized. Each job has: -- A deadline by which it must be completed. -- A profit associated with it. - -### Problem Statement: -Given n jobs, each with a deadline and a profit, the objective is to maximize the total profit by selecting jobs that can be completed within their deadlines. - -### Approach: -The algorithm uses a greedy approach where jobs are sorted in decreasing order of their profits. We then try to schedule jobs in the latest possible time slots before their deadline, filling up the schedule greedily to maximize profit. - -### Algorithm Steps: - -1. Sort all jobs in descending order of profit. -2. Iterate over the sorted jobs and attempt to schedule them in the latest available time slot before their deadline. -3. Print the job sequence that maximizes the profit. - -### Steps Involved: -1. **Structure definition**: - Explained each field in the Job struct. - -2. **Comparison function**: - Described its purpose for sorting jobs by profit. - -3. **Main Function**: - - Initialization of job list and user input. - - Sorting and slot allocation logic. -4. **Result output**: - Displays the job sequence that maximizes profit. - - -### Time Complexity: -- Sorting the jobs: Sorting n jobs based on their profit takes `O(n log n)` time. - Scheduling the jobs: For each job, we try to find an available slot in `O(n)` time. Therefore, the total time complexity for scheduling is O(n^2). - Thus, the overall time complexity is `O(n log n + n^2)`, where n is the number of jobs. - -### Sample Input: - -Enter the number of jobs: 4 -Enter job details (id, deadline, profit) for each job: -Job 1: a 4 20 -Job 2: b 1 10 -Job 3: c 1 40 -Job 4: d 1 30 - -### Sample Output: - -Following is the maximum profit sequence of Jobs: -c a - -### Explanation of Sample: - -Job c has the highest profit and is scheduled first. -Job d is scheduled next as it also has a high profit but must be done before its deadline. -Job a is scheduled because there is a remaining slot before its deadline. -Job b is not scheduled because its profit is lower, and no slots are available before its deadline. - - -### C++ Implementation: -```cpp -#include -#include -#include - -// Structure to represent a job with an ID, deadline, and profit -struct Job { - char id; // Job ID - int dead; // Deadline for job completion - int profit; // Profit if job is completed before or on deadline -}; - -// Comparison function to sort jobs in descending order of profit -bool compare(const Job &a, const Job &b) { - return a.profit > b.profit; -} - -// Function to find the minimum of two numbers -int min(int num1, int num2) { - return (num1 > num2) ? num2 : num1; -} - -int main() { - int n; - std::cout << "Enter the number of jobs: "; - std::cin >> n; - - // Vector to store the list of jobs - std::vector jobs(n); - std::cout << "Enter job details (id, deadline, profit) for each job:\n"; - for (int i = 0; i < n; ++i) { - std::cout << "Job " << i + 1 << ": "; - std::cin >> jobs[i].id >> jobs[i].dead >> jobs[i].profit; - } - - // Display the sequence of jobs that maximize profit - std::cout << "Following is the maximum profit sequence of jobs:\n"; - - // Sort jobs by profit in descending order - std::sort(jobs.begin(), jobs.end(), compare); - - // Vector to store the result (sequence of job IDs) - std::vector result(n, -1); - // Boolean vector to keep track of occupied time slots - std::vector slot(n, false); - - // Iterate through all jobs - for (int i = 0; i < n; ++i) { - // Find a free slot for this job, checking from the last possible slot - for (int j = min(n, jobs[i].dead) - 1; j >= 0; --j) { - if (!slot[j]) { // If slot is free - result[j] = i; // Assign this job to the slot - slot[j] = true; // Mark the slot as occupied - break; - } - } - } - - // Print the sequence of job IDs for maximum profit - for (int i = 0; i < n; ++i) { - if (slot[i]) { - std::cout << jobs[result[i]].id << " "; - } - } - - return 0; -} - -``` - diff --git a/docs/hash/Practice Problems.md b/docs/hash/Practice Problems.md deleted file mode 100644 index 25d4d8d1f..000000000 --- a/docs/hash/Practice Problems.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -id: practice-problems-on-hash-tables -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 16 -Description: Here are some practice problems for Hash Table divided into topic-wise and difficulty wise. -tags: [DSA, algorithms,hash-table, dsa] ---- - -### 1. Easy Level - - - [Ransom Note](https://leetcode.com/problems/ransom-note/description/) - - [Isomorphic Strings](https://leetcode.com/problems/isomorphic-strings/description/) - - [Word Pattern](https://leetcode.com/problems/word-pattern/description/) - - [Valid Anagram](https://leetcode.com/problems/valid-anagram/description/) - - [Two Sum](https://leetcode.com/problems/two-sum/description/) - - [Happy Number](https://leetcode.com/problems/happy-number/description/) - - [Contains Duplicate II](https://leetcode.com/problems/contains-duplicate-ii/description/) - - [Find the Difference of Two Arrays](https://leetcode.com/problems/find-the-difference-of-two-arrays/description/) - - [Unique Number of Occurrences](https://leetcode.com/problems/unique-number-of-occurrences/description/) - ---- - -### 2. Medium Level - - - [Group Anagrams](https://leetcode.com/problems/group-anagrams/description/) - - [Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/description/) - - [Determine if Two Strings Are Close](https://leetcode.com/problems/determine-if-two-strings-are-close/description/) - - [Equal Row and Column Pairs](https://leetcode.com/problems/equal-row-and-column-pairs/description/) - ---- - -### 3. Hard Level - - - [Substring with Concatenation of All Words](https://leetcode.com/problems/substring-with-concatenation-of-all-words/description) - - [First Missing Positive](https://leetcode.com/problems/first-missing-positive/description/) - - [Sudoku Solver](https://leetcode.com/problems/sudoku-solver/description/) - - [Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/description/) - ---- diff --git a/docs/hash/_category_.json b/docs/hash/_category_.json deleted file mode 100644 index 4f6772765..000000000 --- a/docs/hash/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Hash tables", - "position": 14, - "link": { - "type": "generated-index", - "description": "A Hash Table is a data structure designed to be fast to work with." - } - } diff --git a/docs/hash/hash-tables.md b/docs/hash/hash-tables.md deleted file mode 100644 index 11f52291e..000000000 --- a/docs/hash/hash-tables.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: hash-tables-dsa -sidebar_position: 1 -title: Hash tables -sidebar_label: Hash tables -description: "In this blog post, we'll dive into the Hash tables and implementations of hash table, a fundamental topic in Data Structures" -tags: [dsa, Hashtables, Hashmaps] ---- - -## Introduction - -Hashing is a technique to convert a range of key values into a range of indexes of an array. To get the idea of what a Hash Table is, let's try to build one from scratch to store unique first names inside it. - -We will build the Hash Set in 5 steps: - -1. Starting with an array. -2. Storing names using a hash function. -3. Looking up an element using a hash function. -4. Handling collisions. -5. The basic Hash Set code example and simulation. - -## Implementation - -### Basic Operations - -Following are the basic primary operations of a hash table: - -- **Search** - Searches an element in a hash table. -- **Insert** - Inserts an element in a hash table. -- **Delete** - Deletes an element from a hash table. - -### 1. Search Operation - -Whenever an element is to be searched, compute the hash code of the key passed and locate the element using that hash code as index in the array. Use linear probing to get the element ahead if the element is not found at the computed hash code. - -```cpp -struct DataItem { - int data; - int key; -}; - -struct DataItem* search(int key) { - // get the hash - int hashIndex = hashCode(key); - - // move in array until an empty - while (hashArray[hashIndex] != NULL) { - if (hashArray[hashIndex]->key == key) - return hashArray[hashIndex]; - - // go to next cell - ++hashIndex; - - // wrap around the table - hashIndex %= SIZE; - } - - return NULL; -} -``` -### 2. Insert Operation - -Whenever an element is to be inserted, compute the hash code of the key passed and locate the index using that hash code as an index in the array. Use linear probing for an empty location if an element is found at the computed hash code. - -```cpp -void insert(int key, int data) { - struct DataItem* item = (struct DataItem*) malloc(sizeof(struct DataItem)); - item->data = data; - item->key = key; - - // get the hash - int hashIndex = hashCode(key); - - // move in array until an empty or deleted cell - while (hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1) { - // go to next cell - ++hashIndex; - - // wrap around the table - hashIndex %= SIZE; - } - - hashArray[hashIndex] = item; -} -``` -### 3. Delete Operation - -Whenever an element is to be deleted, compute the hash code of the key passed and locate the index using that hash code as an index in the array. Use linear probing to get the element ahead if an element is not found at the computed hash code. When found, store a dummy item there to keep the performance of the hash table intact. - -```cpp -struct DataItem* deleteItem(struct DataItem* item) { - int key = item->key; - - // get the hash - int hashIndex = hashCode(key); - - // move in array until an empty - while (hashArray[hashIndex] != NULL) { - if (hashArray[hashIndex]->key == key) { - struct DataItem* temp = hashArray[hashIndex]; - - // assign a dummy item at deleted position - hashArray[hashIndex] = dummyItem; - return temp; - } - - // go to next cell - ++hashIndex; - - // wrap around the table - hashIndex %= SIZE; - } - - return NULL; -} -``` -### Time Complexity -For lookup, insertion, and deletion operations, hash tables have an average-case time complexity of O(1). However, these operations may, in the worst case, require O(n) time, where n is the number of elements in the table. -### Space Complexity -The space complexity of a hash table is O(n), where n is the number of elements in the -table. This is because each element is stored in a separate cell in the array. - -### Applications of Hash Table -Hash tables are frequently used for indexing and searching massive volumes of data. A search engine might use a hash table to store the web pages that it has indexed. -Data is usually cached in memory via hash tables, enabling rapid access to frequently used information. -Hash functions are frequently used in cryptography to create digital signatures, validate data, and guarantee data integrity. -Hash tables can be used for implementing database indexes, enabling fast access to data based on key values. diff --git a/docs/heap/Kth-largest-using-min_heap.md b/docs/heap/Kth-largest-using-min_heap.md deleted file mode 100644 index 3171ce69e..000000000 --- a/docs/heap/Kth-largest-using-min_heap.md +++ /dev/null @@ -1,149 +0,0 @@ ---- - -id: kth-largest-element-min-heap -title: Kth Largest Element using Min Heap -sidebar_label: Kth Largest Element -sidebar_position: 3 -description: Finding the Kth largest element in an array using a min heap data structure, commonly used in streaming and top-K problems. -tags: [Heap, Priority Queue, Top-K, Streaming] - ---- - -# Kth Largest Element Using Min Heap - -A **Min Heap** based approach to find the Kth largest element in an unsorted array. This algorithm maintains a min heap of size K to efficiently track the K largest elements, where the root of the heap represents the Kth largest element. - -## Introduction - -The K-th largest element algorithm using a min heap is particularly useful when dealing with: -- Large datasets where we need to find top K elements -- Streaming data where elements arrive continuously -- Memory-constrained environments where we can't sort the entire array - -The key idea is to maintain a min heap of size K, where the smallest element (root) represents the Kth largest element seen so far. - -## Algorithm Overview - -### Basic Concept - -1. Create a min heap to store the K largest elements -2. Process elements one by one: - - If heap size < K: Insert the element - - If heap size = K: Compare with root (smallest element) - - If current element > root: Remove root and insert current element - - Otherwise: Skip the element -3. After processing all elements, the root contains the Kth largest element - -### Visual Example -``` -Array: [3, 2, 1, 5, 6, 4], K = 3 - -Step-by-step min heap construction: - -1) [3] 2) [2,3] 3) [1,3,2] - 3 2 1 - / / \ - 3 3 2 - -4) [2,3,5] 5) [4,5,6] Final: 4 is the 3rd largest - 2 4 - / \ / \ - 3 5 5 6 -``` - -## Implementation - -### C++ Implementation -```cpp -#include -#include - -class KthLargest { -private: - priority_queue, greater> minHeap; - int k; - -public: - int findKthLargest(vector& nums, int k) { - this->k = k; - - // Process each element - for (int num : nums) { - // Add to heap if size < k - if (minHeap.size() < k) { - minHeap.push(num); - } - // If current element is larger than smallest element - else if (num > minHeap.top()) { - minHeap.pop(); - minHeap.push(num); - } - } - - return minHeap.top(); - } -}; -``` - -## Time and Space Complexity - -- **Time Complexity**: - - Build Heap: $O(n \cdot \log k)$ - - Get Kth largest: $O(1)$ -- **Space Complexity**: $O(k)$ - -## Advantages and Disadvantages - -### Advantages -- Efficient for streaming data -- Memory efficient ($O(k)$ space) -- Good for large datasets where $k \ll n$ -- Maintains running K largest elements - -### Disadvantages -- Not optimal for small datasets -- Not suitable when K is close to n -- Requires rebuilding heap for dynamic K - -## Related LeetCode Problems - -| Problem | Difficulty | Description | Solution Approach | -|---------|------------|-------------|------------------| -| [215. Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) | Medium | Find the kth largest element in an unsorted array | Min Heap of size K | -| [703. Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/) | Easy | Design a class to find the kth largest element in a stream | Maintain Min Heap | -| [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) | Medium | Find the k most frequent elements | Min Heap with frequency pairs | -| [692. Top K Frequent Words](https://leetcode.com/problems/top-k-frequent-words/) | Medium | Find the k most frequent words | Min Heap with custom comparator | -| [973. K Closest Points to Origin](https://leetcode.com/problems/k-closest-points-to-origin/) | Medium | Find K closest points to origin | Min Heap with distance pairs | - -## Applications - -1. **Top-K Problems** - - Finding K largest elements in a stream - - Finding K most frequent elements - - Finding K closest points - -2. **Data Stream Processing** - - Processing real-time data - - Maintaining running statistics - -3. **System Design** - - Top K trending topics - - K most recent items - - K nearest neighbors - -## Tips and Common Pitfalls - -1. **Implementation Tips** - - Use STL priority_queue for easier implementation - - Consider custom comparators for complex objects - - Initialize heap size to K for better performance - -2. **Common Mistakes** - - Using max heap instead of min heap - - Not handling duplicate elements properly - - Incorrect heap size maintenance - -3. **Optimization Opportunities** - - Pre-allocate heap space if K is known - - Early stopping if element ≤ current Kth largest - - Batch processing for better performance \ No newline at end of file diff --git a/docs/heap/Problem-Practice.md b/docs/heap/Problem-Practice.md deleted file mode 100644 index d8ef27534..000000000 --- a/docs/heap/Problem-Practice.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -id: Practice-Problems-on-heap -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 2 -description: Here are some practice problems for heaps, divided into topic-wise and difficulty-wise categories. -tags: [DSA, algorithms, heaps] ---- - -### Basic Problems: - -- [kth largest element in an array](https://leetcode.com/problems/kth-largest-element-in-an-array/description/) -- [Does array represent Heap](https://www.geeksforgeeks.org/problems/does-array-represent-heap4345/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=does-array-represent-heap) -- [Sum of elements between k1'th and k2'th smallest elements](https://www.geeksforgeeks.org/problems/sum-of-elements-between-k1th-and-k2th-smallest-elements3133/0) -- [Heap sort](https://leetcode.com/problems/sort-an-array/description/) - -### Intermediate Problems: - -- [Merge K sorted lists](https://leetcode.com/problems/merge-k-sorted-lists/description/) -- [Task Scheduler](https://leetcode.com/problems/task-scheduler/description/) -- [Hand of Straights](https://leetcode.com/problems/hand-of-straights/description/) -- [BST to max heap](https://www.geeksforgeeks.org/problems/bst-to-max-heap/1) -- [Merge overlapping intervals](https://leetcode.com/problems/merge-intervals/description/) - -### Advanced Problems: - -- [Design Twitter](https://leetcode.com/problems/design-twitter/description/) -- [kth largest element in a stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/description/) -- [Find median from data stream](https://leetcode.com/problems/find-median-from-data-stream/description/) -- [Top k frequent elements](https://leetcode.com/problems/top-k-frequent-elements/description/) -- [Rod Cutting](https://www.geeksforgeeks.org/problems/rod-cutting0840/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=rod-cutting) \ No newline at end of file diff --git a/docs/heap/_category_.json b/docs/heap/_category_.json deleted file mode 100644 index 09345e449..000000000 --- a/docs/heap/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Heap", - "position": 7, - "link": { - "type": "generated-index", - "description": "A Heap is a specialized tree-based data structure that satisfies the **Heap Property**. Heaps are commonly used to implement priority queues and ensure efficient retrieval of the minimum or maximum element." - } -} diff --git a/docs/heap/heap-basics.md b/docs/heap/heap-basics.md deleted file mode 100644 index 830a05d7a..000000000 --- a/docs/heap/heap-basics.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: Heap-data-Structure-2 -title: heap data structure -sidebar_label: Heap Basics -sidebar_position: 2 -description: Heaps are commonly used to implement priority queues and ensure efficient retrieval of the minimum or maximum element. -tags: [Competitive Programming,top-K,priority queue] ---- -# Heap Data Structure - -A **Heap** is a specialized tree-based data structure that satisfies the **Heap Property**. Heaps are commonly used to implement priority queues and ensure efficient retrieval of the minimum or maximum element. - - -## Introduction - -A **Heap** is a complete binary tree, which means every level is fully filled except possibly the last level, which is filled from left to right. The heap is used to efficiently manage a priority queue, allowing us to retrieve the highest or lowest priority element in constant time. - -Heaps can be represented as arrays, which helps in reducing the space complexity by avoiding pointers. - -## Types of Heaps - -### Max Heap - -In a **Max Heap**, for every node `i`, the value of `i` is greater than or equal to the values of its children. Therefore, the root of the tree contains the maximum element. -``` - - 50 - / \ - 30 20 - / \ / - 15 10 8 -``` - - -### Min Heap - -In a **Min Heap**, for every node `i`, the value of `i` is less than or equal to the values of its children. The root contains the minimum element. -``` - 10 - / \ - 15 30 - / \ / - 50 20 40 -``` - -## Heap Operations - -### Insert - -Inserting an element in a heap involves adding the new element at the end of the tree (or array representation) and then "bubbling up" to restore the heap property. - -1. Insert the element at the next available position. -2. Compare the element with its parent and swap if necessary (heapify up). - -### Delete - -The element to be deleted is usually the root (for priority queues). The last element of the heap replaces the root, and the heap property is restored by "bubbling down" (heapify down). - -1. Replace the root with the last element. -2. Restore the heap property by moving the element down (heapify down). - -### Peek - -The **peek** operation returns the root element of the heap without removing it: -- For a **Max Heap**, this returns the maximum element. -- For a **Min Heap**, this returns the minimum element. - -### Heapify - -Heapifying ensures that a subtree satisfies the heap property. Two types of heapify operations are: -- **Heapify Up**: Used in insertion. -- **Heapify Down**: Used in deletion. - -## Applications - -- **Priority Queue**: Used in scheduling processes, graph algorithms (like Dijkstra's shortest path). -- **Heap Sort**: Sorting algorithm using heaps. -- **Graph Algorithms**: Like Prim's and Dijkstra's shortest path algorithms. -- **Median Maintenance**: Heaps can be used to keep track of the median in a dynamic dataset. - -## Time Complexity - -- **Insertion**: $O(log n)$ -- **Deletion**: $O(log n)$ -- **Peek**: $O(1)$ -- **Heapify**: $O(log n)$ - -## Implementation - -### C++ Code Example - -Here’s a C++ implementation of a Max Heap: - -```cpp -#include -#include - -using namespace std; - -class MaxHeap { - vector heap; - - // Heapify up to restore the heap property after insertion - void heapifyUp(int index) { - if (index == 0) return; - int parentIndex = (index - 1) / 2; - if (heap[parentIndex] < heap[index]) { - swap(heap[parentIndex], heap[index]); - heapifyUp(parentIndex); - } - } - - // Heapify down to restore the heap property after deletion - void heapifyDown(int index) { - int leftChild = 2 * index + 1; - int rightChild = 2 * index + 2; - int largest = index; - - if (leftChild < heap.size() && heap[leftChild] > heap[largest]) { - largest = leftChild; - } - - if (rightChild < heap.size() && heap[rightChild] > heap[largest]) { - largest = rightChild; - } - - if (largest != index) { - swap(heap[index], heap[largest]); - heapifyDown(largest); - } - } - -public: - // Insert a new element into the heap - void insert(int value) { - heap.push_back(value); - heapifyUp(heap.size() - 1); - } - - // Remove the maximum element from the heap - void removeMax() { - if (heap.size() == 0) return; - heap[0] = heap.back(); - heap.pop_back(); - heapifyDown(0); - } - - // Peek the maximum element (root) - int getMax() { - if (heap.size() == 0) throw runtime_error("Heap is empty"); - return heap[0]; - } - - // Print heap elements - void printHeap() { - for (int val : heap) { - cout << val << " "; - } - cout << endl; - } -}; - -int main() { - MaxHeap maxHeap; - - maxHeap.insert(50); - maxHeap.insert(30); - maxHeap.insert(20); - maxHeap.insert(15); - maxHeap.insert(10); - maxHeap.insert(8); - - cout << "Heap after insertions: "; - maxHeap.printHeap(); - - cout << "Max element: " << maxHeap.getMax() << endl; - - maxHeap.removeMax(); - cout << "Heap after removing max: "; - maxHeap.printHeap(); - - return 0; -} -``` diff --git a/docs/heap/heap-operations.md b/docs/heap/heap-operations.md deleted file mode 100644 index 63047c85c..000000000 --- a/docs/heap/heap-operations.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -id: Heap-data-Structure-1 -title: heap data structure -sidebar_label: Heap Operations -sidebar_position: 2 -description: Heaps are commonly used to implement priority queues and ensure efficient retrieval of the minimum or maximum element. -tags: [Competitive Programming,top-K,priority queue] ---- -# Heap Data Structure Operations Examples - -## Example 1: Insert and Peek Operations - -- Inserting 40, 60, 20, 10, 50: The heap is reorganized after every insertion to maintain the max heap property. -- Peeking: After the insertions, the maximum element (root) is displayed, which is 60. - -```cpp -#include -#include - -using namespace std; - -class MaxHeap { - vector heap; - - // Heapify up to restore the heap property after insertion - void heapifyUp(int index) { - if (index == 0) return; - int parentIndex = (index - 1) / 2; - if (heap[parentIndex] < heap[index]) { - swap(heap[parentIndex], heap[index]); - heapifyUp(parentIndex); - } - } - -public: - // Insert a new element into the heap - void insert(int value) { - heap.push_back(value); - heapifyUp(heap.size() - 1); - } - - // Peek the maximum element (root) - int getMax() { - if (heap.size() == 0) throw runtime_error("Heap is empty"); - return heap[0]; - } - - // Print heap elements - void printHeap() { - for (int val : heap) { - cout << val << " "; - } - cout << endl; - } -}; - -int main() { - MaxHeap maxHeap; - - // Inserting elements into the heap - maxHeap.insert(40); - maxHeap.insert(60); - maxHeap.insert(20); - maxHeap.insert(10); - maxHeap.insert(50); - - // Printing the heap after insertions - cout << "Heap after insertions: "; - maxHeap.printHeap(); - - // Peeking the maximum element - cout << "Max element: " << maxHeap.getMax() << endl; - - return 0; -} -``` -``` -Heap after insertions: 60 50 20 10 40 -Max element: 60 -``` - - - - -## Example 2: Insert, Delete, and Peek Operations - -```cpp -#include -#include - -using namespace std; - -class MaxHeap { - vector heap; - - // Heapify up to restore the heap property after insertion - void heapifyUp(int index) { - if (index == 0) return; - int parentIndex = (index - 1) / 2; - if (heap[parentIndex] < heap[index]) { - swap(heap[parentIndex], heap[index]); - heapifyUp(parentIndex); - } - } - - // Heapify down to restore the heap property after deletion - void heapifyDown(int index) { - int leftChild = 2 * index + 1; - int rightChild = 2 * index + 2; - int largest = index; - - if (leftChild < heap.size() && heap[leftChild] > heap[largest]) { - largest = leftChild; - } - - if (rightChild < heap.size() && heap[rightChild] > heap[largest]) { - largest = rightChild; - } - - if (largest != index) { - swap(heap[index], heap[largest]); - heapifyDown(largest); - } - } - -public: - // Insert a new element into the heap - void insert(int value) { - heap.push_back(value); - heapifyUp(heap.size() - 1); - } - - // Remove the maximum element from the heap - void removeMax() { - if (heap.size() == 0) throw runtime_error("Heap is empty"); - heap[0] = heap.back(); - heap.pop_back(); - heapifyDown(0); - } - - // Peek the maximum element (root) - int getMax() { - if (heap.size() == 0) throw runtime_error("Heap is empty"); - return heap[0]; - } - - // Print heap elements - void printHeap() { - for (int val : heap) { - cout << val << " "; - } - cout << endl; - } -}; - -int main() { - MaxHeap maxHeap; - - // Inserting elements into the heap - maxHeap.insert(90); - maxHeap.insert(30); - maxHeap.insert(70); - maxHeap.insert(50); - maxHeap.insert(20); - - cout << "Heap after insertions: "; - maxHeap.printHeap(); - - // Removing the max element - maxHeap.removeMax(); - cout << "Heap after removing max: "; - maxHeap.printHeap(); - - // Peeking the new max element - cout << "Max element after removal: " << maxHeap.getMax() << endl; - - return 0; -} -``` - -``` -Heap after insertions: 90 50 70 30 20 -Heap after removing max: 70 50 20 30 -Max element after removal: 70 -``` diff --git a/docs/heap/kth-largest.md b/docs/heap/kth-largest.md deleted file mode 100644 index 12cdddaa9..000000000 --- a/docs/heap/kth-largest.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -id: Kth-Largest-Element-Heap -title: Kth Largest Element in an Array using Heap -sidebar_label: Kth Largest Element -sidebar_position: 11 -description: Find the Kth largest element in an array using a heap data structure. -tags: [Heap, Competitive Programming, Priority Queue, top-K] ---- - -# Kth Largest Element in an Array Using Heap - -## Problem Description: -Given an array of integers, find the **Kth largest element** in the array. The array may contain duplicate values, and you are required to identify the Kth largest element in the sorted order, not the Kth distinct element. - -### Example: -```bash -Input: [3, 2, 1, 5, 6, 4], K = 2 -Output: 5 -``` - -## Approach: -The optimal solution to this problem involves using a Min Heap. The idea is to maintain a heap of size K which contains the largest K elements. The top of the min heap (the smallest element in the heap) will be the Kth largest element when all elements of the array have been processed. - -## Steps: -Initialize a Min Heap with the first K elements of the array. -For the remaining elements, if the current element is greater than the top element of the heap, replace the top element with the current element. -After processing all elements, the top of the heap will contain the Kth largest element. - - -## Time Complexity: -O(n log K), where n is the number of elements in the array. This is because each insertion and removal operation on the heap takes O(log K) time. - -```cpp -#include -#include -#include - -using namespace std; - -// Function to find the Kth largest element -int findKthLargest(vector& nums, int k) { - // Min heap to store the largest K elements - priority_queue, greater> minHeap; - - // Insert the first K elements into the heap - for (int i = 0; i < k; ++i) { - minHeap.push(nums[i]); - } - - // Process the remaining elements - for (int i = k; i < nums.size(); ++i) { - if (nums[i] > minHeap.top()) { - minHeap.pop(); - minHeap.push(nums[i]); - } - } - - // The top element of the heap is the Kth largest element - return minHeap.top(); -} - -int main() { - // Example array - vector nums = {3, 2, 1, 5, 6, 4}; - int k = 2; - - // Find and display the Kth largest element - cout << "The " << k << "th largest element is " << findKthLargest(nums, k) << endl; - - return 0; -} -``` - diff --git a/docs/heap/kth-smallest.md b/docs/heap/kth-smallest.md deleted file mode 100644 index 0513db741..000000000 --- a/docs/heap/kth-smallest.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -id: Heap-data-Structure-3 -title: heap data structure -sidebar_label: Kth smallest Element -sidebar_position: 10 -description: Heaps are commonly used to implement priority queues and ensure efficient retrieval of the minimum or maximum element. -tags: [Competitive Programming,top-K,priority queue] ---- - -# Heap Problems: Kth Smallest Elements - -## Problem : Kth Smallest Element in an Array - -### Problem Description: -Given an array of `n` integers, find the **Kth largest** element. The array may contain duplicate values, but you are tasked with identifying the Kth largest distinct element. - -### Example: -``` -Input: [3, 2, 1, 5, 6, 4], K = 2 -Output: 5 -``` - -Approach: -Using a Min Heap (Optimal Solution): -Use a Min Heap to keep track of the top K largest elements. -Iterate through the array, adding elements to the heap. -If the heap size exceeds K, remove the smallest element from the heap. -The top element of the heap will be the Kth largest when the iteration is complete. -Time Complexity: O(n log K), where n is the number of elements in the array. - -```cpp -#include -#include -#include - -int findKthSmallest(std::vector& nums, int k) { - std::priority_queue maxHeap; - - for (int num : nums) { - maxHeap.push(num); // Add element to max heap - - if (maxHeap.size() > k) { - maxHeap.pop(); // Remove the largest element if size exceeds k - } - } - - return maxHeap.top(); // The top of the heap is the Kth smallest element -} - -int main() { - std::vector nums = {7, 10, 4, 3, 20, 15}; - int k = 3; - std::cout << "The " << k << "th smallest element is " << findKthSmallest(nums, k) << std::endl; - return 0; -} -``` - - diff --git a/docs/heap/time-complexity.md b/docs/heap/time-complexity.md deleted file mode 100644 index 3e6a2c204..000000000 --- a/docs/heap/time-complexity.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -id: Heap-Operations-Time-Complexity -title: Detailed Time Complexity of Heap Operations -sidebar_label: Heap Time Complexity -sidebar_position: 3 -description: A comprehensive guide covering the time complexity of various operations associated with binary heaps, including rationale and examples. -tags: [DSA, algorithms, heaps, time complexity] ---- - -## Heap Operations and Their Time Complexities - -A **binary heap** is a complete binary tree often used to implement priority queues. It can be a **min-heap** (parent nodes are smaller than their children) or a **max-heap** (parent nodes are larger). Binary heaps support several key operations, such as insertion, deletion, and more. Below is a breakdown of these operations, their time complexities, and detailed explanations. - -### 1. Insertion (Insert a New Element) - -- **Time Complexity:** **O(log n)** -- **Explanation:** - Inserting an element into a heap involves two steps: - - 1. The new element is placed at the end of the heap. - 2. The element is then "bubbled up" to its correct position to restore the heap property. - - Since the heap is a complete binary tree, its height is proportional to `log n`. Thus, bubbling up the element takes at most `log n` comparisons and swaps. - -- **Example:** - Consider inserting the number `2` into a min-heap: - ``` - 3 - / \ - 5 7 - / \ - 8 9 - ``` - After insertion: - ``` - 3 - / \ - 5 7 - / \ \ - 8 9 2 - ``` - The element `2` is smaller than its parent `7`, so it bubbles up: - ``` - 3 - / \ - 5 2 - / \ \ - 8 9 7 - ``` - -### 2. Deletion (Extracting the Root) - -- **Time Complexity:** **O(log n)** -- **Explanation:** - Deleting the root (the smallest or largest element in a min-heap or max-heap) is one of the key operations. It involves: - - 1. Replacing the root with the last element in the heap. - 2. "Bubbling down" the new root to maintain the heap property. - - Bubbling down requires comparing and swapping the new root with its children to ensure the heap remains valid. This process can take up to `log n` steps due to the height of the heap. - -- **Example:** - Consider the following max-heap before and after extracting the root (value `9`): - ``` - 9 - / \ - 7 8 - / \ - 6 4 - ``` - After extracting the root and replacing it with the last element `4`: - ``` - 4 - / \ - 7 8 - / - 6 - ``` - The element `4` bubbles down to its correct position: - ``` - 8 - / \ - 7 4 - / - 6 - ``` - -### 3. Heapify (Building a Heap from an Array) - -- **Time Complexity:** **O(n)** -- **Explanation:** - Heapifying an unsorted array to form a valid heap is done in linear time, although it may seem like `O(n log n)`. This is because, during heap construction, the number of operations decreases significantly for elements at lower levels of the tree. Elements closer to the root require more comparisons, but there are fewer such elements. - -- **Example:** - For an array `[4, 10, 3, 5, 1]`, the heapify process builds the following min-heap: - ``` - 1 - / \ - 5 3 - / \ - 10 4 - ``` - -### 4. Peek (Getting the Root) - -- **Time Complexity:** **O(1)** -- **Explanation:** - The root of the heap (either the minimum or maximum element) can be accessed in constant time because it is always at the top of the heap. - -- **Example:** - In the min-heap: - ``` - 1 - / \ - 5 3 - / \ - 10 4 - ``` - Accessing the root (`1`) takes constant time. - -### 5. Decrease Key (For Priority Queues) - -- **Time Complexity:** **O(log n)** -- **Explanation:** - In priority queues, we may need to decrease the key value of a particular element. This involves: - - 1. Reducing the key value. - 2. "Bubbling up" the element to restore the heap property. - - Since bubbling up takes `O(log n)` time, decreasing a key takes logarithmic time as well. - -- **Example:** - If we decrease the key value of the node `10` in a min-heap to `2`, it may need to bubble up to maintain the heap property: - ``` - 1 - / \ - 5 3 - / \ - 2 4 - ``` - -### 6. Delete a Key (Removing an Arbitrary Element) - -- **Time Complexity:** **O(log n)** -- **Explanation:** - To delete a specific element from the heap: - - 1. Replace the element with the last node in the heap. - 2. Restore the heap property by either bubbling up or bubbling down. - - Both of these operations take `O(log n)` time because they depend on the height of the heap. - -- **Example:** - Consider deleting the element `5` from the min-heap: - - ``` - 1 - / \ - 5 3 - / \ - 10 4 - ``` - - After replacing `5` with the last element `4`: - - ``` - 1 - / \ - 4 3 - / - 10 - ``` - - The heap is already valid, so no further adjustments are needed. - ---- - -## Summary Table of Heap Operation Time Complexities - -| Operation | Time Complexity | -| ----------------------- | --------------- | -| Insertion | O(log n) | -| Deletion (Extract Root) | O(log n) | -| Heapify (Build a Heap) | O(n) | -| Peek (Get Root) | O(1) | -| Decrease Key | O(log n) | -| Delete a Key | O(log n) | - ---- - -## Explanation of Time Complexities - -### Why is Heapify O(n)? - -Heapify has a time complexity of `O(n)` because elements at the lowest levels of the tree require fewer comparisons. If you think about the number of operations needed for nodes at different levels of the tree: - -- For nodes at the bottom level, no swaps are needed. -- For nodes at the next level up, only one comparison and swap are needed. -- For nodes higher up, more swaps are required, but there are fewer of these nodes. - -The sum of these operations across the entire tree results in a linear time complexity of `O(n)`. - -### Why is Insertion and Deletion O(log n)? - -Both insertion and deletion involve restructuring the heap by bubbling elements up or down. Since the heap is a complete binary tree, its height is `log n`, meaning that in the worst case, you only need to perform `log n` swaps. - -This logarithmic behavior makes heaps extremely efficient for use cases like priority queues, where fast insertions and deletions are crucial. - ---- - -Understanding the time complexities of heap operations is fundamental when implementing or optimizing algorithms involving heaps, such as scheduling algorithms, Dijkstra's shortest path, or priority queues. The balance between constant-time root access and logarithmic-time inserts/deletes makes heaps ideal for many real-world applications. diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index b93fb64b8..000000000 --- a/docs/index.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -id: docs -title: Welcome to Algo - Gateway to DSA Mastery! -sidebar_label: Welcome to Algo -sidebar_position: 1 -slug: / -description: Algo is your gateway to mastering Data Structures and Algorithms (DSA). Whether you're a coding enthusiast, a student, or a professional looking to enhance your programming skills, Algo is here to guide you through the intricate world of DSA. -tags: [dsa, data structures, algorithms] ---- - -Algo is your gateway to mastering Data Structures and Algorithms (DSA). Whether you're a coding enthusiast, a student, or a professional looking to enhance your programming skills, Algo is here to guide you through the intricate world of DSA. - - - -## What Sets Algo Apart? - -### Comprehensive Learning Pathways - -Algo provides carefully curated learning pathways designed to take you from a DSA novice to a proficient coder. Our structured approach ensures a smooth learning curve, starting with the basics and gradually progressing to advanced topics. - -### Interactive Coding Challenges - -Learning by doing is at the heart of Algo. Engage in hands-on coding challenges that reinforce your understanding of key concepts. Our interactive platform allows you to apply what you've learned in a practical and engaging manner. - - - -### Supportive Community - -Join a vibrant community of learners, mentors, and industry experts who are passionate about DSA. Collaborate, share knowledge, and grow together as you embark on your coding journey. - -### Personalized Learning Experience - -Algo's adaptive learning platform tailors the content to your skill level and learning pace. Whether you're a beginner or an experienced coder, Algo provides a personalized learning experience that meets your unique needs. - -## Get Started with Algo - -Ready to dive into the world of Data Structures and Algorithms? Start your learning journey with Algo today! Explore our learning pathways, tackle coding challenges, and connect with a community of like-minded individuals who share your passion for coding. - ---- - -

    Feedback and Support

    - - \ No newline at end of file diff --git a/docs/knapsack-disaster-relief/knapsack-disaster-relief.md b/docs/knapsack-disaster-relief/knapsack-disaster-relief.md deleted file mode 100644 index b1f10842d..000000000 --- a/docs/knapsack-disaster-relief/knapsack-disaster-relief.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: knapsack-disaster-relief -title: "Optimizing Disaster Relief Supply Packing" -sidebar_label: "Knapsack for Disaster Relief" -sidebar_position: 1 -description: "Solving the 0/1 Knapsack problem to optimize the packing of supplies for disaster relief missions." -tags: [Knapsack, Dynamic Programming, Disaster Relief, Algorithms] ---- - -In real-world scenarios, the 0/1 Knapsack Problem can help optimize packing decisions for disaster relief missions. The aim is to maximize the total priority of supplies (such as food, medical kits, and blankets) that can be loaded onto a truck with a limited weight capacity. - - - -## Problem Description - -As a member of a disaster relief team, you need to pack a truck with supplies while adhering to a weight limit `W`. There are several types of supplies available, each with: - -- **Weight:** The weight of the supply item. -- **Priority score:** An importance score reflecting how critical the supply is for the mission (e.g., medical supplies are prioritized over blankets). - -The goal is to maximize the total priority score of the supplies loaded into the truck without exceeding the weight limit. - -### Input - -- `W` (integer): The maximum weight capacity of the truck. -- A list of `n` supply items, where each item is defined by: - - `weight[i]`: The weight of the `i`-th supply. - - `value[i]`: The priority score of the `i`-th supply. - -### Output - -- The maximum achievable total priority score for the supplies packed within the weight limit. - -### Example Scenario - -Consider a scenario where the truck's weight limit is **50 kg**, and the available supplies are: - -1. Supply 1: Weight = 10 kg, Priority Score = 60 -2. Supply 2: Weight = 20 kg, Priority Score = 100 -3. Supply 3: Weight = 30 kg, Priority Score = 120 - -You cannot pack all three supplies because their combined weight (10 + 20 + 30 = 60 kg) exceeds the truck's capacity. The optimal choice would be to pack supplies 2 and 3, resulting in a total weight of 50 kg and a maximum priority score of **220**. - - - -## Algorithm and Solution - -The 0/1 Knapsack Problem can be solved efficiently using **Dynamic Programming**. Here's an implementation in C++. - -### C++ Code - -```cpp -#include -#include -using namespace std; - -// Function to solve the 0/1 Knapsack Problem -int knapsack(int W, vector& weights, vector& values, int n) { - // Create a 2D array to store the maximum priority score for each subproblem - vector> dp(n + 1, vector(W + 1, 0)); - - // Build the table in a bottom-up manner - for (int i = 1; i <= n; i++) { - for (int w = 0; w <= W; w++) { - if (weights[i - 1] <= w) { - // Choose the maximum between not including the current item and including it - dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1]); - } else { - // If the item's weight exceeds the current weight limit, don't include it - dp[i][w] = dp[i - 1][w]; - } - } - } - - // Return the maximum priority score for the given weight limit - return dp[n][W]; -} - -int main() { - int W = 50; - vector weights = {10, 20, 30}; - vector values = {60, 100, 120}; - int n = weights.size(); - - // Output the result - cout << "Maximum priority score: " << knapsack(W, weights, values, n) << endl; - return 0; -} -``` - -### Code Explanation - -1. **Dynamic Programming Table:** - - A 2D array `dp[n+1][W+1]` is used to store the maximum priority score achievable for each subproblem. - - The first dimension represents the number of items considered, and the second represents the weight capacity from 0 to `W`. - -2. **Decision Making:** - - For each item, the algorithm checks if its weight is less than or equal to the current weight limit `w`. - - If so, it decides whether to include the item by comparing: - - The maximum score when excluding the item (same as before). - - The score when including the item (adding its priority score and reducing the available capacity). - -3. **Result:** - - The final answer, which is the maximum achievable priority score, is stored in `dp[n][W]`. - -### Optimised Approach - -By using a 1D array, we reduce the space complexity to 𝑂(𝑊). Instead of maintaining a table of size `𝑛×𝑊`, we can maintain a single array `dp[W+1]`, updating it from right to left. - -### C++ Code - -``` cpp -#include -#include -using namespace std; - -// Optimized 0/1 Knapsack Solution with 1D DP array -int knapsack(int W, vector& weights, vector& values, int n) { - // Create a 1D array to store the maximum priority score for each weight limit - vector dp(W + 1, 0); - - // Build the array in a bottom-up manner - for (int i = 0; i < n; i++) { - // Update the dp array from right to left to avoid overwriting the results - for (int w = W; w >= weights[i]; w--) { - dp[w] = max(dp[w], dp[w - weights[i]] + values[i]); - } - } - - // Return the maximum priority score for the given weight limit - return dp[W]; -} - -int main() { - int W = 50; - vector weights = {10, 20, 30}; - vector values = {60, 100, 120}; - int n = weights.size(); - - // Output the result - cout << "Maximum priority score: " << knapsack(W, weights, values, n) << endl; - return 0; -} -``` -### Code Explanation - -1. **1D Array:** - - We use a 1D array dp of size `W+1` instead of a 2D array. - -2. **Right-to-Left Update:** - - For each item, we iterate through the weight limit W to weights[i] (from right to left). This is to avoid overwriting values in dp that are needed for the current iteration. - -3. **Efficiency:** - - This reduces space complexity from `𝑂(𝑛𝑊)` to `𝑂(𝑊)`, while still keeping the same time complexity `𝑂(𝑛𝑊)`. diff --git a/docs/languages/C/c-0.md b/docs/languages/C/c-0.md deleted file mode 100644 index d0c051035..000000000 --- a/docs/languages/C/c-0.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -id: introduction-to-c -sidebar_position: 1 -title: "Introduction to C" -sidebar_label: "Introduction to C" ---- - -Welcome to the world of C! In this guide, we'll dive into the essentials of C, a foundational programming language that has influenced modern computing for decades. Whether you're interested in system programming, embedded systems, or software development, learning C will provide you with valuable skills. Let’s get started! - -## 1. What is C? - -C is a procedural programming language developed by Dennis Ritchie in the early 1970s. It is widely known for its simplicity, efficiency, and control over hardware resources, making it one of the most popular languages for system-level programming, such as operating systems and embedded systems. - -## 2. Key Features of C - -- **Procedural Programming:** C follows a procedural approach, focusing on functions, sequences of instructions, and structured programming concepts. -- **Low-Level Access:** C allows direct manipulation of memory through pointers, making it suitable for system programming where hardware-level control is required. -- **Portability:** C programs can be compiled and executed on various platforms with minimal modifications, enhancing its use in cross-platform development. -- **Efficient Performance:** C's minimalistic design enables fast execution, which is crucial for performance-critical applications like operating systems and embedded software. -- **Rich Standard Library:** C includes a powerful standard library that provides functions for memory management, string manipulation, and file handling. - -## 3. Setting Up C - -To start programming in C, you'll need to set up a development environment. Here are some common options: - -- **Integrated Development Environments (IDEs):** - - - **Code::Blocks**: A lightweight, easy-to-use IDE for C and C++. - - **Visual Studio**: A comprehensive IDE for Windows, widely used for C/C++ development. - - **Eclipse**: A versatile IDE with support for multiple programming languages, including C. - -- **Compilers:** - - **GCC (GNU Compiler Collection)**: A popular open-source compiler available for Linux, Windows, and macOS. - - **Clang**: Another fast, open-source compiler that’s part of the LLVM project, suitable for compiling C code. - -## 4. Writing Your First C Program - -Here’s a simple "Hello, World!" program in C:Here’s a simple "Hello, World!" program to get you started: - -```c -#include // Include the standard input-output library - -int main() { - printf("Hello, World!\n"); // Print "Hello, World!" to the console - return 0; // Return 0 to indicate successful execution -} -``` - -Explanation: - -```c -#include : This line includes the standard input-output library required for the `printf` function. -int main(): This is the entry point of the program where execution begins. -printf("Hello, World!\n"): This prints "Hello, World!" to the console. -return 0;: This signifies that the program executed successfully. -``` - -## 5. Basic Syntax - -Comments: Use // for single-line comments and /\* \*/ for multi-line comments. - -```cpp -// This is a single-line comment -/* This is a - multi-line comment */ -``` - -Semicolons: Each statement in C ends with a semicolon (;). - -Braces: Curly braces (`{}`) are used to define the beginning and end of code blocks. - -## 6. Conclusion - -C is a powerful and efficient programming language that has formed the basis for many modern programming languages. Its combination of low-level control and simplicity makes it ideal for a wide range of applications, from operating systems to embedded systems. Mastering C will provide a strong foundation for understanding how software interacts with hardware. diff --git a/docs/languages/C/c-1.md b/docs/languages/C/c-1.md deleted file mode 100644 index 318e30b78..000000000 --- a/docs/languages/C/c-1.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -id: datatypes-in-c -sidebar_position: 1 -title: "Datatypes in C" -sidebar_label: "Datatypes in C" ---- - -Hello! In this guide, we’ll delve into the various data types available in the C programming language. Knowing about data types is vital for creating efficient and effective C programs. Let’s explore! - -- In C, data types specify the type of data a variable can hold, defining the operations that can be performed on it. - -## 1. Understanding Data Types in C - -C supports several built-in data types, which can be classified into three main categories: **basic types**, **derived types**, and **user-defined types**. - -## 2. Basic Data Types - -### a. Integer Types (`int`, `short`, `long`, `long long`) - -- **`int`**: Stores whole numbers. The size typically ranges from 16 to 64 bits, depending on the system. - - ```c - int age = 30; - ``` - -- **`short`**: A smaller integer type, usually 16 bits. - - ```c - short temperature = -10; - ``` - -- **`long`**: A larger integer type, typically at least 32 bits. - - ```c - long population = 7000000000L; - ``` - -- **`long long`**: An even larger integer type, usually at least 64 bits. - ```c - long long distance = 9876543210123LL; - ``` - -### b. Floating-Point Types (`float`, `double`, `long double`) - -- **`float`**: Represents single-precision floating-point numbers, typically 32 bits. - - ```c - float pi = 3.14f; - ``` - -- **`double`**: Represents double-precision floating-point numbers, usually 64 bits, offering more precision. - - ```c - double e = 2.718281828459045; - ``` - -- **`long double`**: Offers extended precision beyond `double`, size varies by implementation. - ```c - long double bigNumber = 3.402823466e+38L; - ``` - -### c. Character Type (`char`) - -- Represents a single character, stored as an integer (ASCII value). - ```c - char initial = 'C'; - ``` - -## 3. Derived Data Types - -### a. Arrays - -- A collection of elements of the same data type, accessed using indices. - ```c - int numbers[5] = {1, 2, 3, 4, 5}; - ``` - -### b. Pointers - -- A variable that stores the memory address of another variable. - ```c - int* ptr; - int value = 42; - ptr = &value; // Assign address of value to ptr - ``` - -### c. Structures (`struct`) - -- A user-defined data type that groups related variables of different types. - ```c - struct Person { - char name[50]; - int age; - }; - ``` - -### d. Unions (`union`) - -- Similar to structures but stores different data types in the same memory location. - ```c - union Data { - int intValue; - float floatValue; - }; - ``` - -## 4. User-Defined Data Types - -### a. Typedef - -- Allows creating new data type names for existing types, enhancing code readability. - ```c - typedef unsigned long ulong; - ``` - -### b. Enumerations (`enum`) - -- A user-defined type that consists of a set of named integer constants. - ```c - enum Color { RED, GREEN, BLUE }; - ``` - -## 5. Constant Variables - -- Constants are declared using the `const` keyword, preventing any modification after initialization. - ```c - const int MAX_USERS = 100; - ``` - -## 6. Type Conversion - -C allows implicit and explicit type conversion between different data types. - -### a. Implicit Type Conversion - -- Automatic conversion performed by the compiler when necessary. - ```c - int a = 10; - double b = a; // Implicit conversion from int to double - ``` - -### b. Explicit Type Conversion (Casting) - -- Manually converting one type to another. - ```c - double x = 9.99; - int y = (int)x; // Explicitly cast double to int - ``` - -## 7. Conclusion - -Understanding data types in C is crucial for efficient programming. It allows you to choose the right type for your data, ensuring that your programs are both effective and resource-efficient. Mastering these data types will serve as a strong foundation for writing robust C applications. diff --git a/docs/languages/C/c-2.md b/docs/languages/C/c-2.md deleted file mode 100644 index 5f23ab5d0..000000000 --- a/docs/languages/C/c-2.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: operators-in-c -sidebar_position: 3 -title: "Operators in C" -sidebar_label: "Operators in C" ---- - -Operators are special symbols in C that perform operations on variables and values. Understanding operators is essential for writing effective C programs. This guide will cover the various types of operators available in C. - -## 1. Arithmetic Operators - -Arithmetic operators are used to perform basic mathematical operations. - -| Operator | Description | Example | -| -------- | ------------------- | ------------------- | -| `+` | Addition | `int sum = a + b;` | -| `-` | Subtraction | `int diff = a - b;` | -| `*` | Multiplication | `int prod = a * b;` | -| `/` | Division | `int quot = a / b;` | -| `%` | Modulus (Remainder) | `int rem = a % b;` | - -### Example: - -```c -int a = 10, b = 3; -int sum = a + b; // 13 -int diff = a - b; // 7 -int prod = a * b; // 30 -int quot = a / b; // 3 -int rem = a % b; // 1 -``` - -## 2. Relational Operators - -Relational operators compare two values and return a boolean result (`true` or `false`). - -| Operator | Description | Example | -| -------- | ------------------------ | --------- | -| == | Equal to | x == y | -| != | Not equal to | x != y | -| > | Greater than | x > y | -| < | Less than | x < y | -| >= | Greater than or equal to | x >= y | -| <= | Less than or equal to | x <= y | - -#### Example: - -```c -#include - -int main() { - int x = 10, y = 5; - printf("%d\n", (x == y)); // Output: 0 (false) - printf("%d\n", (x != y)); // Output: 1 (true) - printf("%d\n", (x > y)); // Output: 1 (true) - printf("%d\n", (x < y)); // Output: 0 (false) - printf("%d\n", (x >= y)); // Output: 1 (true) - printf("%d\n", (x <= y)); // Output: 0 (false) - return 0; -} -``` - -## 3. Logical Operators - -Logical operators are used to perform logical operations and combine multiple conditions. - -| Operator | Description | Example | -| -------- | ----------- | ----------------------- | -| && | Logical AND | (x > 5 && y < 10) | -| ! | Logical NOT | !(x > 5) | - -#### Example: - -```c -#include - -int main() { - int x = 10, y = 5; - printf("%d\n", (x > 5 && y < 10)); // Output: 1 (true) - printf("%d\n", (x > 5 || y > 10)); // Output: 1 (true) - printf("%d\n", !(x > 5)); // Output: 0 (false) - return 0; -} -``` - -## 4. Assignment Operators - -Assignment operators are used to assign values to variables. - -| Operator | Description | Example | -| -------- | ---------------------- | ------- | -| = | Assigns value | x = y | -| += | Adds and assigns | x += y | -| -= | Subtracts and assigns | x -= y | -| \*= | Multiplies and assigns | x \*= y | -| /= | Divides and assigns | x /= y | -| %= | Modulus and assigns | x %= y | - -#### Example: - -```c -#include - -int main() { - int x = 10, y = 5; - x += y; // Equivalent to x = x + y - printf("%d\n", x); // Output: 15 - return 0; -} -``` - -## 5. Increment and Decrement Operators - -Increment and decrement operators are used to increase or decrease a variable's value by 1. - -| Operator | Description | Example | -| -------- | ---------------- | ---------- | -| ++ | Increments value | ++x or x++ | -| -- | Decrements value | --x or x-- | - -#### Example: - -```c -#include - -int main() { - int x = 10; - printf("%d\n", ++x); // Output: 11 (Pre-increment) - printf("%d\n", x--); // Output: 11 (Post-decrement) - printf("%d\n", x); // Output: 10 - return 0; -} -``` - -## 6. Bitwise Operators - -Bitwise operators operate on bits and perform bit-level operations. - -| Operator | Description | Example | -| -------- | ----------- | ---------- | --- | --- | -| & | Bitwise AND | x & y | -| | | Bitwise OR | x | y | -| ^ | Bitwise XOR | x ^ y | -| ~ | Bitwise NOT | ~x | -| \>\> | Left shift | x \>\> 2 | -| \<\< | Right shift | x \<\< 2 | - -#### Example: - -```c -#include - -int main() { - int x = 5, y = 9; - printf("%d\n", (x & y)); // Output: 1 - printf("%d\n", (x | y)); // Output: 13 - return 0; -} - -``` - -## 7. Ternary Operator - -The ternary operator is a shorthand for an if-else statement. - -| Operator | Description | Example | -| -------- | ----------- | ------------------------- | -| ?: | Ternary | condition ? expr1 : expr2 | - -#### Example: - -```c -#include - -int main() { - int x = 10; - int result = (x > 5) ? 100 : 200; - printf("%d\n", result); // Output: 100 - return 0; -} - -``` - ---- - -Understanding these operators is key to mastering C programming and writing efficient code! diff --git a/docs/languages/C/c-3.md b/docs/languages/C/c-3.md deleted file mode 100644 index fb76d2136..000000000 --- a/docs/languages/C/c-3.md +++ /dev/null @@ -1,194 +0,0 @@ ---- -id: decision-making-in-c -sidebar_position: 3 -title: "Decision Making in C" -sidebar_label: "Decision Making in C" ---- - -Hey there! In this guide, we'll explore decision-making in C. Decision-making structures allow you to execute different blocks of code based on certain conditions. Let's dive in! - -- Decision-making structures allow you to execute different blocks of code based on certain conditions. -- C provides several constructs for decision-making, including `if`, `else`, `else if`, and `switch`. - -## 1. The `if` Statement - -#### Syntax: - -```cpp -if (condition) { - // code to be executed if condition is true -} -``` - -#### Example: - -```c -#include - -int main() { - int num = 10; - if (num > 0) { - printf("The number is positive.\n"); - } - return 0; -} -``` - -## 2. The `if...else` Statement - -#### Syntax: - -```c -if (condition1) { - // code to be executed if condition1 is true -} else { - // code to be executed if condition1 is false -} - - -``` - -#### Example: - -```c -#include - -int main() { - int num = -5; - if (num > 0) { - printf("The number is positive.\n"); - } else { - printf("The number is not positive.\n"); - } - return 0; -} - -``` - -## 3. The `if...else if...else` Statement - -#### Syntax: - -```c -if (condition1) { - // code to be executed if condition1 is true -} else if (condition2) { - // code to be executed if condition2 is true -} else { - // code to be executed if both conditions are false -} - -``` - -#### Example: - -```c -#include - -int main() { - int num = 0; - if (num > 0) { - printf("The number is positive.\n"); - } else if (num < 0) { - printf("The number is negative.\n"); - } else { - printf("The number is zero.\n"); - } - return 0; -} - - -``` - -## 4. The `switch` Statement - -#### Syntax: - -```c -switch (expression) { - case value1: - // code to be executed if expression == value1 - break; - case value2: - // code to be executed if expression == value2 - break; - default: - // code to be executed if expression doesn't match any case -} - -``` - -#### Example: - -```c -#include - -int main() { - int day = 3; - switch (day) { - case 1: - printf("Monday\n"); - break; - case 2: - printf("Tuesday\n"); - break; - case 3: - printf("Wednesday\n"); - break; - default: - printf("Not a valid day\n"); - } - return 0; -} - - -``` - -## 5. Nested `if` Statements - -#### Example: - -```c -#include - -int main() { - int num = 15; - if (num > 10) { - printf("The number is greater than 10.\n"); - if (num > 20) { - printf("The number is also greater than 20.\n"); - } - } - return 0; -} - -``` - -## 6. Conditional Operators - -C++ also supports conditional operators for compact decision-making. - -#### Ternary Operator - -```c -(condition) ? expression1 : expression2; - -``` - -#### Example: - -```c -#include - -int main() { - int num = 10; - const char* result = (num > 0) ? "Positive" : "Non-positive"; - printf("%s\n", result); - return 0; -} - -``` - ---- - -Understanding decision-making structures in C is crucial for controlling the flow of your program and executing different actions based on conditions. Happy coding! diff --git a/docs/languages/C/c-4.md b/docs/languages/C/c-4.md deleted file mode 100644 index a95647806..000000000 --- a/docs/languages/C/c-4.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -id: loops-in-c -sidebar_position: 3 -title: "Loops In C" -sidebar_label: "Loops In C" ---- - -Hey there! In this guide, we'll explore loops in C. Loops are used to execute a block of code repeatedly based on specific conditions. Let's dive in! - -- C provides several types of loops that allow you to execute a block of code multiple times based on specific conditions. -- The main types of loops in C are `for`, `while`, and `do-while`. - -## 1. For Loop - -The `for` loop is used when you know how many times you want to execute a statement or a block of statements. - -#### Syntax: - -```c -for(initialization; condition; increment/decrement) { - // code to be executed -} -``` - -#### Example: - -```c -#include - -int main() { - for (int i = 0; i < 5; i++) { - printf("Iteration %d\n", i); - } - return 0; -} - -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -## 2. While Loop - -The `while` loop is used when you want to execute a block of code as long as a specified condition is true. - -#### Syntax: - -```c -while(condition) { - // code to be executed -} - -``` - -#### Example: - -```c -#include - -int main() { - int i = 0; - while (i < 5) { - printf("Iteration %d\n", i); - i++; - } - return 0; -} - -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -## 3. Do-While Loop - -The `do-while` loop is similar to the `while` loop, except that it guarantees that the code block will be executed at least once before the condition is tested. - -#### Syntax: - -```c -do { - // code to be executed -} while(condition); -``` - -#### Example: - -```c -#include - -int main() { - int i = 0; - do { - printf("Iteration %d\n", i); - i++; - } while (i < 5); - return 0; -} - -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -## 4. Nested Loops - -You can also use loops inside other loops, which are called nested loops. - -#### Example: - -```c -#include - -int main() { - for (int i = 1; i <= 3; i++) { - for (int j = 1; j <= 2; j++) { - printf("Outer Loop: %d, Inner Loop: %d\n", i, j); - } - } - return 0; -} - -``` - -``` -Outer Loop: 1, Inner Loop: 1 -Outer Loop: 1, Inner Loop: 2 -Outer Loop: 2, Inner Loop: 1 -Outer Loop: 2, Inner Loop: 2 -Outer Loop: 3, Inner Loop: 1 -Outer Loop: 3, Inner Loop: 2 - - -``` - -## 5. Break and Continue Statements - -### a. Break Statement - -The `break` statement is used to exit a loop prematurely. - -#### Example: - -```c -#include - -int main() { - for (int i = 0; i < 10; i++) { - if (i == 5) { - break; // Exit the loop when i equals 5 - } - printf("Iteration %d\n", i); - } - return 0; -} - -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -### b. Break Statement - -The `continue` statement skips the current iteration and proceeds to the next one. - -#### Example: - -```c -#include - -int main() { - for (int i = 0; i < 5; i++) { - if (i == 2) { - continue; // Skip the iteration when i equals 2 - } - printf("Iteration %d\n", i); - } - return 0; -} - - -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 3 -Iteration 4 - - -``` - ---- - -Loops are essential for controlling the flow of execution in your C++ programs, enabling you to perform repetitive tasks efficiently. Understanding how to use them effectively will greatly enhance your programming skills! diff --git a/docs/languages/SQL/sql-1.md b/docs/languages/SQL/sql-1.md deleted file mode 100644 index de3487c8c..000000000 --- a/docs/languages/SQL/sql-1.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: "introduction-to-sql" -sidebar_position: 1 -title: "Introduction to SQL" -sidebar_label: "Introduction to SQL" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - - -SQL is a standard language for storing, manipulating, and retrieving data in databases. - -Our SQL tutorial will teach you how to use SQL in: MySQL, SQL Server, MS Access, Oracle, Sybase, Informix, Postgres, and other database systems. - -## What is SQL? - -* SQL stands for Structured Query Language -* SQL lets you access and manipulate databases -* SQL became a standard of the American National Standards Institute (ANSI) in 1986, and of the International Organization for Standardization (ISO) in 1987 - -* * * - -## What Can SQL do? - -* SQL can execute queries against a database -* SQL can retrieve data from a database -* SQL can insert records in a database -* SQL can update records in a database -* SQL can delete records from a database -* SQL can create new databases -* SQL can create new tables in a database -* SQL can create stored procedures in a database -* SQL can create views in a database -* SQL can set permissions on tables, procedures, and views - -* * * - -## SQL is a Standard - BUT.... - - -Although SQL is an ANSI/ISO standard, there are different versions of the SQL language. - -However, to be compliant with the ANSI standard, they all support at least the major commands (such as `SELECT`, `UPDATE`, `DELETE`, `INSERT`, `WHERE`) in a similar manner. - -**Note:** Most of the SQL database programs also have their own proprietary extensions in addition to the SQL standard! - -* * * - -## Using SQL in Your Web Site - - -To build a web site that shows data from a database, you will need: - -* An RDBMS database program (i.e. MS Access, SQL Server, MySQL) -* To use a server-side scripting language, like PHP or ASP -* To use SQL to get the data you want -* To use HTML / CSS to style the page - -## RDBMS - - -RDBMS stands for Relational Database Management System. - -RDBMS is the basis for SQL and for all modern database systems such as MS SQL Server, IBM DB2, Oracle, MySQL, and Microsoft Access. - -The data in RDBMS is stored in database objects called tables. A table is a collection of related data entries, and it consists of columns and rows. - -Every table is broken up into smaller entities called fields. The fields in the Customers table consist of CustomerID, CustomerName, ContactName, Address, City, PostalCode, and Country. A field is a column in a table that is designed to maintain specific information about every record in the table. - -A record, also called a row, is each individual entry that exists in a table. For example, there are 91 records in the above Customers table. A record is a horizontal entity in a table. - -A column is a vertical entity in a table that contains all information associated with a specific field in a table. diff --git a/docs/languages/SQL/sql-10.md b/docs/languages/SQL/sql-10.md deleted file mode 100644 index b25f94b88..000000000 --- a/docs/languages/SQL/sql-10.md +++ /dev/null @@ -1,121 +0,0 @@ ---- -id: sql-delete-statement -sidebar_position: 10 -title: "SQL DELETE Statement" -sidebar_label: "SQL DELETE Statement" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `DELETE` statement is used to remove existing records from a table. You can delete specific records using the `WHERE` clause, or delete all records from a table without deleting the table itself. - -In the statement below, we delete the customer with `CustomerID` 1. - -### Example - -Delete the customer with `CustomerID` equal to 1: - -```sql -DELETE FROM Customers -WHERE CustomerID = 1; -``` - -In the example above, the `DELETE` statement removes the row(s) matching the condition specified in the `WHERE` clause. - ---- - -### Syntax - -```sql -DELETE FROM table_name -WHERE condition; -``` - -If you omit the `WHERE` clause, all records in the table will be deleted. - ---- - -### Demo Database - -Below is a selection from the **Customers** table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -| ---------- | ---------------------------------- | ------------------ | ----------------------------- | ----------- | ---------- | ------- | -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - ---- - -## Deleting Multiple Records - -### Example - -Delete all customers from Mexico: - -```sql -DELETE FROM Customers -WHERE Country = 'Mexico'; -``` - ---- - -## Deleting All Records - -### Example - -Delete all customers from the table: - -```sql -DELETE FROM Customers; -``` - -**Note:** Be careful when using `DELETE` without a `WHERE` clause, as it will remove all records in the table. - ---- - -## Using Subquery in DELETE - -### Example - -Delete customers who have no orders in the `Orders` table: - -```sql -DELETE FROM Customers -WHERE CustomerID NOT IN (SELECT CustomerID FROM Orders); -``` - -In this example, a subquery is used to specify customers who do not have entries in the `Orders` table. - ---- - -## Conditional Delete with Multiple Conditions - -### Example - -Delete customers from Germany who live in Berlin: - -```sql -DELETE FROM Customers -WHERE Country = 'Germany' AND City = 'Berlin'; -``` - -You can combine multiple conditions using `AND`, `OR`, etc., to refine which records should be deleted. - ---- - -## Truncate Table (Alternative to DELETE) - -While `DELETE` removes records row by row and can be filtered, `TRUNCATE` is another option to delete all rows quickly. - -### Example - -```sql -TRUNCATE TABLE Customers; -``` - -**Note:** `TRUNCATE` is faster than `DELETE` without a `WHERE` clause but cannot be used to delete specific records and usually cannot be rolled back. - ---- diff --git a/docs/languages/SQL/sql-11.md b/docs/languages/SQL/sql-11.md deleted file mode 100644 index 329537722..000000000 --- a/docs/languages/SQL/sql-11.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: sql-insert-into-statement -sidebar_position: 11 -title: "SQL INSERT INTO Statement" -sidebar_label: "SQL INSERT INTO Statement" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `INSERT INTO` statement is used to add new records to a table. You can insert data into all columns or only into specific columns by specifying their names. - -In the example below, we add a new customer record to the **Customers** table. - -### Example - -Insert a new customer with all column values specified: - -```sql -INSERT INTO Customers (CustomerID, CustomerName, ContactName, Address, City, PostalCode, Country) -VALUES (6, 'Tortuga Cafe', 'Linda Tortuga', 'Ocean St. 45', 'San Diego', '92101', 'USA'); -``` - -In this example, the `INSERT INTO` statement adds a new row with specific values for each column. - ---- - -### Syntax - -For inserting data into **all columns**: - -```sql -INSERT INTO table_name -VALUES (value1, value2, ...); -``` - -For inserting data into **specific columns**: - -```sql -INSERT INTO table_name (column1, column2, ...) -VALUES (value1, value2, ...); -``` - ---- - -### Demo Database - -Below is a selection from the **Customers** table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -| ---------- | ---------------------------------- | ------------------ | ----------------------------- | ----------- | ---------- | ------- | -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - ---- - -## Insert into Specific Columns - -### Example - -Insert a new customer into specific columns only: - -```sql -INSERT INTO Customers (CustomerName, Country) -VALUES ('Desert King', 'USA'); -``` - -If you don’t specify certain columns, they may be filled with default values or `NULL` depending on the table structure. - ---- - -## Insert Multiple Rows - -### Example - -Insert multiple rows at once: - -```sql -INSERT INTO Customers (CustomerName, Country) -VALUES ('Kingdom Cones', 'Canada'), - ('Sunrise Deli', 'Australia'); -``` - -Multiple rows can be inserted in a single `INSERT INTO` statement by separating each row with a comma. - ---- - -## Using Subquery in INSERT INTO - -### Example - -Insert new customers based on data from another table: - -```sql -INSERT INTO Customers (CustomerName, Country) -SELECT SupplierName, Country FROM Suppliers -WHERE Country = 'USA'; -``` - -In this example, data is copied from the `Suppliers` table into the `Customers` table, based on a condition. - ---- - -## Inserting Default Values - -### Example - -Insert a new customer with default values for certain columns: - -```sql -INSERT INTO Customers (CustomerName) -VALUES ('Misty Mountain Market'); -``` - -Columns not specified will use their default value or `NULL` if no default is set. - ---- - -## Inserting Data with NULL Values - -### Example - -Insert a new customer, leaving some columns as `NULL`: - -```sql -INSERT INTO Customers (CustomerID, CustomerName, ContactName) -VALUES (7, 'Mountain Bakery', NULL); -``` - -In this case, `NULL` can be explicitly inserted for columns where data is unknown or not applicable. - ---- diff --git a/docs/languages/SQL/sql-12.md b/docs/languages/SQL/sql-12.md deleted file mode 100644 index 771a4c701..000000000 --- a/docs/languages/SQL/sql-12.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: sql-alter-table-statement -sidebar_position: 12 -title: "SQL ALTER TABLE Statement" -sidebar_label: "SQL ALTER TABLE Statement" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `ALTER TABLE` statement is used to modify an existing table structure, such as adding, deleting, or modifying columns, and altering table constraints. - -In the statement below, we add a new column to the **Customers** table. - -### Example - -Add a new column for storing the customer’s email: - -```sql -ALTER TABLE Customers -ADD Email VARCHAR(100); -``` - -In this example, the `ALTER TABLE` statement adds a new column called `Email` with a data type of `VARCHAR(100)`. - ---- - -### Syntax - -To **add** a column: - -```sql -ALTER TABLE table_name -ADD column_name datatype; -``` - -To **drop** a column: - -```sql -ALTER TABLE table_name -DROP COLUMN column_name; -``` - -To **modify** a column: - -```sql -ALTER TABLE table_name -MODIFY COLUMN column_name datatype; -``` - ---- - -### Demo Database - -Below is a selection from the **Customers** table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -| ---------- | ---------------------------------- | ------------------ | ----------------------------- | ----------- | ---------- | ------- | -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - ---- - -## Adding a Column - -### Example - -Add a `Phone` column to the table: - -```sql -ALTER TABLE Customers -ADD Phone VARCHAR(15); -``` - -This example shows how to add a new column named `Phone` to the table. - ---- - -## Dropping a Column - -### Example - -Remove the `PostalCode` column from the table: - -```sql -ALTER TABLE Customers -DROP COLUMN PostalCode; -``` - -Using `DROP COLUMN` removes the specified column and all data within it. - ---- - -## Modifying a Column - -### Example - -Change the `City` column’s data type to `CHAR(50)`: - -```sql -ALTER TABLE Customers -MODIFY COLUMN City CHAR(50); -``` - -You can use `MODIFY COLUMN` to change a column’s data type, length, or constraints. - ---- - -## Renaming a Column - -### Example - -Rename the `Address` column to `StreetAddress`: - -```sql -ALTER TABLE Customers -RENAME COLUMN Address TO StreetAddress; -``` - -Note: Some SQL databases use the `ALTER TABLE` with `CHANGE` or `MODIFY` syntax for renaming columns. - ---- - -## Adding Constraints - -### Example - -Add a `UNIQUE` constraint on the `Email` column: - -```sql -ALTER TABLE Customers -ADD CONSTRAINT uc_email UNIQUE (Email); -``` - -Adding constraints can enforce data integrity and consistency in the table. - ---- - -## Dropping Constraints - -### Example - -Remove the `UNIQUE` constraint from the `Email` column: - -```sql -ALTER TABLE Customers -DROP CONSTRAINT uc_email; -``` - -When dropping constraints, use the specific constraint name to identify it. - ---- - -## Renaming a Table - -### Example - -Rename the `Customers` table to `Clients`: - -```sql -ALTER TABLE Customers -RENAME TO Clients; -``` - -This will change the name of the entire table to `Clients`. - ---- diff --git a/docs/languages/SQL/sql-13.md b/docs/languages/SQL/sql-13.md deleted file mode 100644 index 6fd8d3fca..000000000 --- a/docs/languages/SQL/sql-13.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: sql-drop-statement -sidebar_position: 13 -title: "SQL DROP Statement" -sidebar_label: "SQL DROP Statement" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `DROP` statement is used to delete entire tables, databases, or specific constraints from a table. It removes the specified object and all associated data permanently, so use with caution. - -In the statement below, we delete the entire **Customers** table from the database. - -### Example - -Drop the **Customers** table: - -```sql -DROP TABLE Customers; -``` - -In this example, the `DROP TABLE` statement deletes the **Customers** table and all data within it. - ---- - -### Syntax - -To **drop a table**: - -```sql -DROP TABLE table_name; -``` - -To **drop a database**: - -```sql -DROP DATABASE database_name; -``` - -To **drop a constraint** from a table: - -```sql -ALTER TABLE table_name -DROP CONSTRAINT constraint_name; -``` - ---- - -### Demo Database - -The **Customers** table structure used in the examples would look like this before dropping: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -| ---------- | ---------------------------------- | ------------------ | ----------------------------- | ----------- | ---------- | ------- | -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - ---- - -## Dropping a Table - -### Example - -Delete the **Orders** table: - -```sql -DROP TABLE Orders; -``` - -This deletes the entire **Orders** table and all of its data permanently. - ---- - -## Dropping a Database - -### Example - -Delete the **SalesDB** database: - -```sql -DROP DATABASE SalesDB; -``` - -Using `DROP DATABASE` will remove the database and all tables and data within it. - ---- - -## Dropping a Column Constraint - -### Example - -Remove the `UNIQUE` constraint from the **Email** column in the **Customers** table: - -```sql -ALTER TABLE Customers -DROP CONSTRAINT uc_email; -``` - -To drop constraints such as `UNIQUE`, `FOREIGN KEY`, or `PRIMARY KEY`, use `ALTER TABLE` followed by `DROP CONSTRAINT` and the specific constraint name. - ---- - -## Dropping an Index - -### Example - -Delete an index named `idx_customer_name`: - -```sql -DROP INDEX idx_customer_name; -``` - -Dropping an index improves space efficiency but may slow down query performance for indexed columns. - ---- - -## Dropping a View - -### Example - -Delete a view named `CustomerOrders`: - -```sql -DROP VIEW CustomerOrders; -``` - -Views can be removed using the `DROP VIEW` statement, similar to tables. - ---- - -## Important Notes - -- **Irreversible**: The `DROP` statement permanently removes objects, and this action cannot be undone. -- **Dependencies**: Dropping tables or databases with dependencies will fail unless the dependencies are removed first. -- **Permissions**: Dropping tables or databases may require specific user permissions. - ---- diff --git a/docs/languages/SQL/sql-14.md b/docs/languages/SQL/sql-14.md deleted file mode 100644 index 067278863..000000000 --- a/docs/languages/SQL/sql-14.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -id: sql-aggregate-functions -sidebar_position: 14 -title: "SQL Aggregate Functions" -sidebar_label: "SQL Aggregate Functions" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -An aggregate function is a function that performs a calculation on a set of values, and returns a single value. - -Aggregate functions are often used with the `GROUP BY` clause of the `SELECT` statement. The `GROUP BY` clause splits the result-set into groups of values and the aggregate function can be used to return a single value for each group. - -The most commonly used SQL aggregate functions are: - -* `MIN()` - returns the smallest value within the selected column -* `MAX()` - returns the largest value within the selected column -* `COUNT()` - returns the number of rows in a set -* `SUM()` - returns the total sum of a numerical column -* `AVG()` - returns the average value of a numerical column - -Aggregate functions ignore null values (except for `COUNT()`). - - -## SQL MIN() and MAX() Functions - -The `MIN()` function returns the smallest value of the selected column. - -The `MAX()` function returns the largest value of the selected column. - -### MIN Example - -Find the lowest price in the Price column: -``` -SELECT MIN(Price) -FROM Products; -``` - -### MAX Example - -Find the highest price in the Price column: -``` -SELECT MAX(Price) -FROM Products; -``` - -### Syntax - -`SELECT MIN(_column_name_) FROM _table_name_ WHERE _condition_;` - -`SELECT MAX(_column_name_) FROM _table_name_ WHERE _condition_;` - -### Demo Database - -Below is a selection from the Products table used in the examples: - -| ProductID | ProductName | SupplierID | CategoryID | Unit | Price | -| --- | --- | --- | --- | --- | --- | -| 1 | Chais | 1 | 1 | 10 boxes x 20 bags | 18 | -| 2 | Chang | 1 | 1 | 24 - 12 oz bottles | 19 | -| 3 | Aniseed Syrup | 1 | 2 | 12 - 550 ml bottles | 10 | -| 4 | Chef Anton's Cajun Seasoning | 2 | 2 | 48 - 6 oz jars | 22 | -| 5 | Chef Anton's Gumbo Mix | 2 | 2 | 36 boxes | 21.35 | - -## Set Column Name (Alias) - -When you use `MIN()` or `MAX()`, the returned column will not have a descriptive name. To give the column a descriptive name, use the `AS` keyword: - -### Example -``` -SELECT MIN(Price) AS SmallestPrice -FROM Products; -``` - -## Use MIN() with GROUP BY - -Here we use the `MIN()` function and the `GROUP BY` clause, to return the smallest price for each category in the Products table: - -### Example -``` -SELECT MIN(Price) AS SmallestPrice, CategoryID -FROM Products -GROUP BY CategoryID; -``` - -You will learn more about the `[GROUP BY](sql_groupby.asp)` clause later in this tutorial. - -======= -description: "An aggregate function is a function that performs a calculation on a set of values, and returns a single value." -tags: [sql, dbms, database] ---- - -## About SQL Aggregates - -An aggregate function is a function that performs a calculation on a set of values and returns a single value. These functions are commonly used with the `GROUP BY` clause in SQL to group rows that share a common attribute. - -The most commonly used SQL aggregate functions include: - -- **MIN()**: Returns the smallest value within a selected column. -- **MAX()**: Returns the largest value within a selected column. -- **COUNT()**: Returns the number of rows in a set. -- **SUM()**: Returns the total sum of a numerical column. -- **AVG()**: Returns the average value of a numerical column. - -Aggregate functions ignore null values, except for `COUNT()`. - ---- - -## Common SQL Aggregate Functions - -### MIN() -- **Description**: Returns the smallest value within the selected column. -- **Syntax**: `MIN(column_name)` -- **Example**: - ```sql - SELECT MIN(salary) FROM employees; - ``` - -### MAX() -- **Description**: Returns the largest value within the selected column. -- **Syntax**: `MAX(column_name)` -- **Example**: - ```sql - SELECT MAX(salary) FROM employees; - ``` - -### COUNT() -- **Description**: Returns the number of rows in a set. -- **Syntax**: - - `COUNT(column_name)` -- Counts non-null values in the specified column - - `COUNT(*)` -- Counts all rows -- **Example**: - ```sql - SELECT COUNT(*) FROM employees; - ``` - -### SUM() -- **Description**: Returns the total sum of a numerical column. -- **Syntax**: `SUM(column_name)` -- **Example**: - ```sql - SELECT SUM(salary) FROM employees; - ``` - -### AVG() -- **Description**: Returns the average value of a numerical column. -- **Syntax**: `AVG(column_name)` -- **Example**: - ```sql - SELECT AVG(salary) FROM employees; - ``` - -## Using Aggregate Functions with GROUP BY - -Aggregate functions can be combined with the `GROUP BY` clause to group rows that have the same values in specified columns. - -- **Syntax**: - ```sql - SELECT column1, AGGREGATE_FUNCTION(column2) - FROM table_name - GROUP BY column1; - ``` - -- **Example**: - ```sql - SELECT department, COUNT(*) AS employee_count - FROM employees - GROUP BY department; - ``` \ No newline at end of file diff --git a/docs/languages/SQL/sql-15.md b/docs/languages/SQL/sql-15.md deleted file mode 100644 index 1bf75b881..000000000 --- a/docs/languages/SQL/sql-15.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: SQL-COUNT-Function -sidebar_position: 15 -title: "SQL COUNT() Function" -sidebar_label: "SQL COUNT() Function" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - - -The `COUNT()` function returns the number of rows that matches a specified criterion. - -### Example -Find the total number of rows in the `Products` table: -``` -SELECT COUNT(\*) -FROM Products; -``` - -### Syntax - -`SELECT COUNT(_column_name_) FROM _table_name_ WHERE _condition_;` - - -### Demo Database - -Below is a selection from the Products table used in the examples: - - -| ProductID | ProductName | SupplierID | CategoryID | Unit | Price | -| --- | --- | --- | --- | --- | --- | -| 1 | Chais | 1 | 1 | 10 boxes x 20 bags | 18 | -| 2 | Chang | 1 | 1 | 24 - 12 oz bottles | 19 | -| 3 | Aniseed Syrup | 1 | 2 | 12 - 550 ml bottles | 10 | -| 4 | Chef Anton's Cajun Seasoning | 2 | 2 | 48 - 6 oz jars | 22 | -| 5 | Chef Anton's Gumbo Mix | 2 | 2 | 36 boxes | 21.35 | - - -## Specify Column - -You can specify a column name instead of the asterix symbol `(*)`. - -If you specify a column name instead of `(*)`, NULL values will not be counted. - -### Example - -Find the number of products where the `ProductName` is not null: -``` -SELECT COUNT(ProductName) -FROM Products; -``` - -## Add a WHERE Clause - -You can add a `WHERE` clause to specify conditions: - -### Example - -Find the number of products where `Price` is higher than 20: - -SELECT COUNT(ProductID) -FROM Products -WHERE Price > 20; - -* * * - -## Ignore Duplicates - -You can ignore duplicates by using the `DISTINCT` keyword in the `COUNT()` function. - -If `DISTINCT` is specified, rows with the same value for the specified column will be counted as one. - -### Example - -How many _different_ prices are there in the `Products` table: -``` -SELECT COUNT(DISTINCT Price) -FROM Products; -``` - -## Use an Alias - -Give the counted column a name by using the `AS` keyword. - -### Example - -Name the column "Number of records": -``` -SELECT COUNT(\*) AS \[Number of records\] -FROM Products; -``` - - -## Use COUNT() with GROUP B - -Here we use the `COUNT()` function and the `GROUP BY` clause, to return the number of records for each category in the Products table: - -### Example -``` -SELECT COUNT(\*) AS \[Number of records\], CategoryID -FROM Products -GROUP BY CategoryID; -``` - diff --git a/docs/languages/SQL/sql-16.md b/docs/languages/SQL/sql-16.md deleted file mode 100644 index 12b69cdf5..000000000 --- a/docs/languages/SQL/sql-16.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: SQL-SUM-Function -sidebar_position: 16 -title: "SQL SUM() Function" -sidebar_label: "SQL SUM() Function" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `SUM()` function returns the total sum of a numeric column. - -### Example - -Return the sum of all `Quantity` fields in the `OrderDetails` table: -``` -SELECT SUM(Quantity) -FROM OrderDetails; -``` - -### Syntax - -`SELECT SUM(_column_name_) FROM _table_name_ WHERE _condition_;` - - -### Demo Database - -Below is a selection from the OrderDetails table used in the examples: - -| OrderDetailID | OrderID | ProductID | Quantity | -|----------------|---------|-----------|----------| -| 1 | 10248 | 11 | 12 | -| 2 | 10248 | 42 | 10 | -| 3 | 10248 | 72 | 5 | -| 4 | 10249 | 14 | 9 | -| 5 | 10249 | 51 | 40 | - - -### Add a WHERE Clause - -You can add a `WHERE` clause to specify conditions: - -### Example - -Return the sum of the `Quantity` field for the product with `ProductID` 11: -``` -SELECT SUM(Quantity) -FROM OrderDetails -WHERE ProductId = 11; -``` -### Use an Alias - -Give the summarized column a name by using the `AS` keyword. - -### Example - -Name the column "total": -``` -SELECT SUM(Quantity) AS total -FROM OrderDetails; -``` -## Use SUM() with GROUP BY - -Here we use the `SUM()` function and the `GROUP BY` clause, to return the `Quantity` for each `OrderID` in the OrderDetails table: - -### Example -``` -SELECT OrderID, SUM(Quantity) AS \[Total Quantity\] -FROM OrderDetails -GROUP BY OrderID; -``` -## SUM() With an Expression - -The parameter inside the `SUM()` function can also be an expression. - -If we assume that each product in the `OrderDetails` column costs 10 dollars, we can find the total earnings in dollars by multiply each quantity with 10: - -### Example - -Use an expression inside the `SUM()` function: -``` -SELECT SUM(Quantity \* 10) -FROM OrderDetails; -``` - -We can also join the `OrderDetails` table to the `Products` table to find the actual amount, instead of assuming it is 10 dollars: - -### Example - -Join `OrderDetails` with `Products`, and use `SUM()` to find the total amount: -``` -SELECT SUM(Price \* Quantity) -FROM OrderDetails -LEFT JOIN Products ON OrderDetails.ProductID = Products.ProductID; -``` - - diff --git a/docs/languages/SQL/sql-17.md b/docs/languages/SQL/sql-17.md deleted file mode 100644 index d5f3090cb..000000000 --- a/docs/languages/SQL/sql-17.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -id: SQL-AVG-Function -sidebar_position: 17 -title: "SQL AVG() Function" -sidebar_label: "SQL AVG() Function" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - - - -The `AVG()` function returns the average value of a numeric column. - -### Example - -Find the average price of all products: -``` -SELECT AVG(Price) -FROM Products; -``` - -### Syntax - -`SELECT AVG(_column_name_) FROM _table_name_ WHERE _condition_;` - - -### Demo Database - -Below is a selection from the Products table used in the examples: - -| ProductID | ProductName | SupplierID | CategoryID | Unit | Price | -| --- | --- | --- | --- | --- | --- | -| 1 | Chais | 1 | 1 | 10 boxes x 20 bags | 18 | -| 2 | Chang | 1 | 1 | 24 - 12 oz bottles | 19 | -| 3 | Aniseed Syrup | 1 | 2 | 12 - 550 ml bottles | 10 | -| 4 | Chef Anton's Cajun Seasoning | 2 | 2 | 48 - 6 oz jars | 22 | -| 5 | Chef Anton's Gumbo Mix | 2 | 2 | 36 boxes | 21.35 | -### Add a WHERE Clause - -You can add a `WHERE` clause to specify conditions: - -### Example - -Return the average price of products in category 1: -``` -SELECT AVG(Price) -FROM Products -WHERE CategoryID = 1; -``` - -### Use an Alias - -Give the AVG column a name by using the `AS` keyword. - -### Example - -Name the column "average price": -``` -SELECT AVG(Price) AS \[average price\] -FROM Products; -``` - -## Higher Than Average - -To list all records with a higher price than average, we can use the `AVG()` function in a sub query: - -### Example - -Return all products with a higher price than the average price: -``` -SELECT \* FROM Products -WHERE price > (SELECT AVG(price) FROM Products); -``` - -## Use AVG() with GROUP BY - -Here we use the `AVG()` function and the `GROUP BY` clause, to return the average price for each category in the Products table: - -### Example -``` -SELECT AVG(Price) AS AveragePrice, CategoryID -FROM Products -GROUP BY CategoryID; -``` \ No newline at end of file diff --git a/docs/languages/SQL/sql-18.md b/docs/languages/SQL/sql-18.md deleted file mode 100644 index a7636891d..000000000 --- a/docs/languages/SQL/sql-18.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -id: sql-joins -sidebar_position: 18 -title: "SQL Joins" -sidebar_label: "SQL Joins" -description: "SQL Joins are used to combine rows from two or more tables based on a related column between them." -tags: [sql, dbms, database, joins] ---- - -### SQL Joins - -SQL Joins are used to combine rows from two or more tables based on a related column between them. - -### Types of Joins - -1. **INNER JOIN**: Returns records that have matching values in both tables. -2. **LEFT JOIN**: Returns all records from the left table and the matched records from the right table. If there is no match, the result is NULL from the right side. -3. **RIGHT JOIN**: Returns all records from the right table and the matched records from the left table. If there is no match, the result is NULL from the left side. -4. **FULL JOIN**: Returns all records when there is a match in either left or right table records. If there is no match, the result is NULL on the side that does not have a match. - -### INNER JOIN - -- **Description**:Retrieve a list of all products with their supplier names. -- **Example**: - ``` - SELECT Products.ProductName, Suppliers.SupplierName - FROM Products - INNER JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID; - ``` - -### LEFT JOIN - -- **Description**:Retrieve a list of all products and their suppliers, including those without suppliers. -- **Example**: - ``` - SELECT Products.ProductName, Suppliers.SupplierName - FROM Products - LEFT JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID; - ``` - -### RIGHT JOIN - -- **Description**:Retrieve a list of all suppliers and their products, including those without products. -- **Example**: - ``` - SELECT Products.ProductName, Suppliers.SupplierName - FROM Products - RIGHT JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID; - ``` - -### FULL JOIN - -- **Description**:Retrieve a complete list of products and suppliers, regardless of matches. -- **Example**: - ``` - SELECT Products.ProductName, Suppliers.SupplierName - FROM Products - FULL JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID; - ``` - -### Combining Joins - -- **Description**:Retrieve product details along with supplier and category information. -- **Example**: - ``` - SELECT Products.ProductName, Suppliers.SupplierName, Categories.CategoryName - FROM Products - INNER JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID - INNER JOIN Categories ON Products.CategoryID = Categories.CategoryID; - ``` \ No newline at end of file diff --git a/docs/languages/SQL/sql-19.md b/docs/languages/SQL/sql-19.md deleted file mode 100644 index babc07b11..000000000 --- a/docs/languages/SQL/sql-19.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -id: SQL-LIKE-Operator -sidebar_position: 19 -title: "SQL LIKE Operator" -sidebar_label: "SQL LIKE Operator" -description: "The SQL LIKE operator is used to filter data based on patterns." -tags: [sql, dbms, database, like] ---- - -The `LIKE` operator is used in a `WHERE` clause to search for a specific pattern in a column. - -### Syntax - -```sql -SELECT column_name(s) -FROM table_name -WHERE column_name LIKE pattern; -``` - -### Pattern Matching - -You can use the following wildcard characters in the pattern: - -* **%**: Matches any character sequence, zero or more times. -* **_**: Matches any single character. - -### Examples - -**Example 1: Find all products that start with 'Ch'** - -```sql -SELECT * -FROM Products -WHERE ProductName LIKE 'Ch%'; -``` - -**Example 2: Find all products that contain 'an' anywhere in the name** - -```sql -SELECT * -FROM Products -WHERE ProductName LIKE '%an%'; -``` - -**Example 3: Find all products that end with 'syrup'** - -```sql -SELECT * -FROM Products -WHERE ProductName LIKE '%syrup'; -``` - -**Example 4: Find all products with a 4-character product ID starting with '1'** - -```sql -SELECT * -FROM Products -WHERE ProductID LIKE '1___'; -``` - -**Note:** The specific implementation and syntax might vary slightly depending on the database system you're using (e.g., MySQL, PostgreSQL, SQL Server). However, the core concept of using the `LIKE` operator with wildcard characters remains consistent. diff --git a/docs/languages/SQL/sql-2.md b/docs/languages/SQL/sql-2.md deleted file mode 100644 index ba057b086..000000000 --- a/docs/languages/SQL/sql-2.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: "sql_syntax" -sidebar_position: 2 -title: "SQL Syntax" -sidebar_label: "SQL Statements" -description: "SQL statements are commands used to perform tasks such as querying, updating, and managing data in relational databases." -tags: [sql, dbms, database] ---- - - - -## SQL Statements - -Most of the actions you need to perform on a database are done with SQL statements. - -SQL statements consist of keywords that are easy to understand. - -## Database Tables - -A database most often contains one or more tables. Each table is identified by a name (e.g., "Customers" or "Orders") and contains records (rows) with data. - -In this tutorial, we will use the well-known Northwind sample database (included in MS Access and MS SQL Server). - -Below is a selection from the Customers table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -|------------|-------------------------------|----------------|------------------------|-------------|------------|----------| -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - -The table above contains five records (one for each customer) and seven columns (CustomerID, CustomerName, ContactName, Address, City, PostalCode, and Country). - -## Keep in Mind That... - -SQL keywords are NOT case-sensitive: `select` is the same as `SELECT`. - -In this tutorial, we will write all SQL keywords in upper-case. - -* * * - -## Semicolon after SQL Statements? - -Some database systems require a semicolon at the end of each SQL statement. - -A semicolon is the standard way to separate each SQL statement in database systems that allow more than one SQL statement to be executed in the same call to the server. - -In this tutorial, we will use a semicolon at the end of each SQL statement. - -* * * - -## Some of The Most Important SQL Commands - -* `SELECT` - extracts data from a database -* `UPDATE` - updates data in a database -* `DELETE` - deletes data from a database -* `INSERT INTO` - inserts new data into a database -* `CREATE DATABASE` - creates a new database -* `ALTER DATABASE` - modifies a database -* `CREATE TABLE` - creates a new table -* `ALTER TABLE` - modifies a table -* `DROP TABLE` - deletes a table -* `CREATE INDEX` - creates an index (search key) -* `DROP INDEX` - deletes an index diff --git a/docs/languages/SQL/sql-20.md b/docs/languages/SQL/sql-20.md deleted file mode 100644 index eb9ba0bf7..000000000 --- a/docs/languages/SQL/sql-20.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -id: SQL-Having-Clause -sidebar_position: 20 -title: "SQL Having Clause" -sidebar_label: "SQL Having Clause" -description: "The `HAVING` clause in SQL is used to filter records in combination with the `GROUP BY` clause." -tags: [sql, dbms, database, having] ---- - -The `HAVING` clause is used in conjunction with the `GROUP BY` clause to filter the results of aggregated data. It allows you to specify conditions on groups created by the `GROUP BY` clause, enabling more advanced data filtering. - -### Syntax - -```sql -SELECT column_name(s), aggregate_function(column_name) -FROM table_name -WHERE condition -GROUP BY column_name(s) -HAVING condition; -``` -### Key Points - -* The HAVING clause is similar to the WHERE clause, but it is applied to groups rather than individual rows. -* You typically use HAVING to filter records after aggregation, making it suitable for conditions on aggregated data. - -### Examples -**Example 1: Find all categories with more than 10 products** - -```sql -SELECT CategoryID, COUNT(ProductID) AS ProductCount -FROM Products -GROUP BY CategoryID -HAVING COUNT(ProductID) > 10; -``` - -**Example 2: Retrieve suppliers who have provided products worth more than $1,000** - -```sql -SELECT SupplierID, SUM(Price) AS TotalValue -FROM Products -GROUP BY SupplierID -HAVING SUM(Price) > 1000; -``` - -**Example 3: List all customers with more than one order** - -```sql -SELECT CustomerID, COUNT(OrderID) AS OrderCount -FROM Orders -GROUP BY CustomerID -HAVING COUNT(OrderID) > 1; -``` -**Note**: -The HAVING clause is often used with aggregate functions such as SUM(), COUNT(), AVG(), etc. It is important to note that the HAVING clause is evaluated after the GROUP BY clause, which means you cannot use it without grouping your results first. diff --git a/docs/languages/SQL/sql-21.md b/docs/languages/SQL/sql-21.md deleted file mode 100644 index 65ab88fed..000000000 --- a/docs/languages/SQL/sql-21.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -id: sql-group-by -sidebar_position: 21 -title: "SQL GROUP BY Statement" -sidebar_label: "SQL GROUP BY" -description: "The SQL GROUP BY statement is used to group rows that have the same values in specified columns and apply aggregate functions." -tags: [sql, dbms, database, group by] ---- - -The `GROUP BY` statement in SQL is used to arrange identical data into groups. It is typically used with aggregate functions (such as `COUNT`, `SUM`, `AVG`, `MAX`, or `MIN`) to perform operations on each group. - -### Syntax - -```sql -SELECT COUNT(CustomerID), Country -FROM Customers -GROUP BY Country -HAVING COUNT(CustomerID) > 5; -``` - -### Key Points - -* The GROUP BY statement groups rows that have the same values in specified columns. -* It is often combined with aggregate functions to perform calculations on each group. -* Using ORDER BY with GROUP BY allows you to sort the grouped results. - -### Examples - -**Example 1: Count the number of products in each category** - -```sql -SELECT CategoryID, COUNT(ProductID) AS ProductCount -FROM Products -GROUP BY CategoryID; -``` - -**Example 2: Find the total sales for each salesperson** - -```sql -SELECT SalespersonID, SUM(SaleAmount) AS TotalSales -FROM Sales -GROUP BY SalespersonID; -``` - -**Example 3: Retrieve the average salary of employees in each department** - -```sql -SELECT DepartmentID, AVG(Salary) AS AverageSalary -FROM Employees -GROUP BY DepartmentID; -``` - -**Note:** -* The GROUP BY clause must appear after the WHERE clause and before the ORDER BY clause if they are used together. -* When using GROUP BY, only the grouped columns or aggregate functions can be included in the SELECT statement, as other columns would produce ambiguous results. -* The HAVING clause can be used with GROUP BY to filter groups based on aggregate conditions. diff --git a/docs/languages/SQL/sql-22.md b/docs/languages/SQL/sql-22.md deleted file mode 100644 index 945e1774f..000000000 --- a/docs/languages/SQL/sql-22.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -id: sql-select-top -sidebar_position: 22 -title: "SQL SELECT TOP" -sidebar_label: "SQL SELECT TOP" -description: "The SQL SELECT TOP clause is used to limit the number of rows returned in a result set." -tags: [sql, dbms, database, select top] ---- - -The `SELECT TOP` clause is used in SQL to limit the number of rows returned in a query result. It is commonly used when you want to retrieve a specific number or percentage of records. - -### Syntax - -In SQL Server: - -```sql -SELECT TOP number|percent column_name(s) -FROM table_name -WHERE condition; -``` -In MySQL and PostgreSQL, you can use LIMIT instead: - -```sql -SELECT column_name(s) -FROM table_name -WHERE condition -LIMIT number; -``` - -### Key Points - -* The SELECT TOP clause is supported in SQL Server, while MySQL and PostgreSQL use the LIMIT clause instead. -* You can specify either a fixed number or a percentage of rows to return. -* This clause is especially useful for retrieving a subset of rows from large datasets, such as the top-performing items or recent entries. - -### Examples - -**Example 1: Retrieve the top 5 most expensive products** - -```sql -SELECT TOP 5 ProductName, Price -FROM Products -ORDER BY Price DESC; -``` -In MySQL/PostgreSQL, use: - -```sql -SELECT ProductName, Price -FROM Products -ORDER BY Price DESC -LIMIT 5; -``` - -**Example 2: Retrieve the top 10% of employees with the highest salaries** - -```sql -SELECT TOP 10 PERCENT EmployeeName, Salary -FROM Employees -ORDER BY Salary DESC; -``` - -In MySQL/PostgreSQL, you would need to calculate the percentage manually, as they don’t support the PERCENT keyword in the same way. - -**Note:** -The SELECT TOP clause is typically used with ORDER BY to control which records are selected based on specific criteria, such as descending order of price or date. Keep in mind that different SQL databases have variations in syntax for limiting rows. diff --git a/docs/languages/SQL/sql-23.md b/docs/languages/SQL/sql-23.md deleted file mode 100644 index 234ea12c3..000000000 --- a/docs/languages/SQL/sql-23.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -id: sql-alias -sidebar_position: 23 -title: "SQL Alias" -sidebar_label: "SQL Alias" -description: "The SQL Alias is used to give a table or a column a temporary name." -tags: [sql, dbms, database, alias] ---- - -SQL aliases are temporary names assigned to tables or columns. They are primarily used to make column names more readable and to simplify queries, especially when working with multiple tables or complex calculations. - -### Syntax - -For Column Alias: - -```sql -SELECT column_name AS alias_name -FROM table_name; -``` - -For Table Alias: - -```sql -SELECT column_name(s) -FROM table_name AS alias_name; -``` - -### Key Points -* Aliases are created using the AS keyword, although the keyword is optional in most databases. -* Column aliases are useful for renaming columns in the result set. -* Table aliases are helpful when dealing with complex queries, especially joins, where referencing the same table multiple times can make the query easier to read and write. - -### Examples -**Example 1: Assign an alias to a column** - -```sql -SELECT ProductName AS Product, Price AS Cost -FROM Products; -``` -In this example, ProductName is displayed as Product and Price as Cost in the result. - -**Example 2: Assign an alias to a table** - -```sql -SELECT p.ProductName, s.SupplierName -FROM Products AS p -INNER JOIN Suppliers AS s ON p.SupplierID = s.SupplierID; -``` -Here, Products is aliased as p and Suppliers as s, making it easier to reference columns in the JOIN operation. - -**Example 3: Using aliases with calculations** - -```sql -SELECT Price, Price * 0.1 AS Tax -FROM Products; -``` -In this example, the calculated value Price * 0.1 is given the alias Tax for readability. - -**Note:** -* Aliases exist only for the duration of the query; they do not change the actual column or table names in the database. -* When using aliases, especially in complex queries or subqueries, it’s good practice to use clear, descriptive names to improve readability. diff --git a/docs/languages/SQL/sql-24.md b/docs/languages/SQL/sql-24.md deleted file mode 100644 index bf51782ae..000000000 --- a/docs/languages/SQL/sql-24.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -id: sql-logical-operators -sidebar_position: 24 -title: "SQL Logical Operators" -sidebar_label: "SQL Logical Operators" -description: "SQL logical operators are used to combine multiple conditions in a query." -tags: [sql, dbms, database, logical operators] ---- - -SQL logical operators are used to combine multiple conditions in a query. They help refine search criteria and filter data based on complex logic. - -### Types of Logical Operators - -1. **AND**: Returns records if all specified conditions are true. -2. **OR**: Returns records if at least one of the specified conditions is true. -3. **NOT**: Reverses the result of a condition, returning records if the condition is false. -4. **IN**: Checks if a value exists within a specified set of values. -5. **BETWEEN**: Checks if a value is within a specified range. -6. **ANY**: Returns true if any of the values match the condition. -7. **ALL**: Returns true only if all values match the condition. - -### Syntax - -Using `AND` and `OR`: - -```sql -SELECT column_name(s) -FROM table_name -WHERE condition1 AND condition2; -- both conditions must be true - -SELECT column_name(s) -FROM table_name -WHERE condition1 OR condition2; -- at least one condition must be true -``` - -Using NOT: - -```sql -SELECT column_name(s) -FROM table_name -WHERE NOT condition -``` - -Using IN: - -```sql -SELECT column_name(s) -FROM table_name -WHERE column_name IN (value1, value2, ...); -``` - -Using BETWEEN: - -```sql -SELECT column_name(s) -FROM table_name -WHERE column_name BETWEEN value1 AND value2; -``` - -Using ANY and ALL: - -```sql -SELECT column_name(s) -FROM table_name -WHERE column_name = ANY (subquery); -- any condition can be met - -SELECT column_name(s) -FROM table_name -WHERE column_name = ALL (subquery); -- all conditions must be met -``` - -### Examples - -**Example 1: Using AND** - -Retrieve products with a price between $10 and $50. - -```sql -SELECT ProductName, Price -FROM Products -WHERE Price >= 10 AND Price <= 50; -``` - -**Example 2: Using OR** - -Retrieve products that are either in CategoryID 1 or CategoryID 2. - -```sql -SELECT ProductName, CategoryID -FROM Products -WHERE CategoryID = 1 OR CategoryID = 2; -``` - -**Example 3: Using NOT** - -Retrieve products that are not in CategoryID 3. - -```sql -SELECT ProductName, CategoryID -FROM Products -WHERE NOT CategoryID = 3; -``` - -**Example 4: Using IN** - -Retrieve products that belong to CategoryID 1, 2, or 3. - -```sql -SELECT ProductName, CategoryID -FROM Products -WHERE CategoryID IN (1, 2, 3); -``` - -**Example 5: Using BETWEEN** - -Retrieve products with a price between $20 and $100. - -```sql -SELECT ProductName, Price -FROM Products -WHERE Price BETWEEN 20 AND 100; -``` - -**Example 6: Using ANY** - -Retrieve products where the price is greater than any price in the DiscountedProducts table. - -```sql -SELECT ProductName, Price -FROM Products -WHERE Price > ANY (SELECT Price FROM DiscountedProducts); -``` - -**Example 7: Using ALL** - -Retrieve products where the price is greater than all prices in the DiscountedProducts table. - -```sql -SELECT ProductName, Price -FROM Products -WHERE Price > ALL (SELECT Price FROM DiscountedProducts); -``` - -**Note:** -* Logical operators are evaluated in the following order: NOT, AND, then OR. Parentheses () can be used to control the evaluation order explicitly. -* IN and BETWEEN help reduce code complexity and improve readability when checking for multiple values or ranges. -* ANY and ALL are typically used with subqueries to evaluate conditions against multiple values. diff --git a/docs/languages/SQL/sql-25.md b/docs/languages/SQL/sql-25.md deleted file mode 100644 index 9b252f4d3..000000000 --- a/docs/languages/SQL/sql-25.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: sql-json-data -sidebar_position: 25 -title: "JSON Data in SQL" -sidebar_label: "JSON Data in SQL" -description: "Handling JSON Data Within SQL." -tags: [sql, dbms, database, json, data, backend] ---- - -## Introduction -With the growing use of JSON (JavaScript Object Notation) for data exchange, many modern databases have introduced native support for JSON data types. This enables efficient querying and manipulation of JSON data directly within SQL. - -## JSON Data Type -Many SQL databases, including MySQL, PostgreSQL, and SQL Server, support a `JSON` data type, allowing structured data to be stored in a single column. - -### Benefits: -- **Structured Storage**: Store hierarchical data. -- **Efficient Access**: Query and manipulate JSON data using SQL. -- **Flexibility**: Schema-less data storage. - -## Storing JSON in SQL -You can store JSON data in a `JSON` or `TEXT` column depending on the database. - -### Example: -```sql -CREATE TABLE users ( - id INT PRIMARY KEY, - details JSON -); - -INSERT INTO users (id, details) VALUES -(1, '{"name": "Alice", "age": 30, "email": "alice@example.com"}'); -``` - -## Querying JSON Data -SQL provides functions to query and extract values from JSON data. - -### MySQL: -```sql -SELECT details->'$.name' AS name FROM users; -``` - -### PostgreSQL: -```sql -SELECT details->>'name' AS name FROM users; -``` - -### SQL Server: -```sql -SELECT JSON_VALUE(details, '$.name') AS name FROM users; -``` - -## Modifying JSON Data -Use JSON functions to update, add, or remove JSON elements. - -### MySQL Example: -```sql -UPDATE users SET details = JSON_SET(details, '$.age', 31) WHERE id = 1; -``` - -### PostgreSQL Example: -```sql -UPDATE users SET details = jsonb_set(details, '{age}', '31', false) WHERE id = 1; -``` - -## Indexing JSON Data -JSON fields can be indexed to improve query performance. - -### MySQL: -```sql -ALTER TABLE users ADD INDEX idx_name ((details->'$.name')); -``` - -### PostgreSQL: -```sql -CREATE INDEX idx_name ON users ((details->>'name')); -``` - -## Use Cases -- **Flexible Data Models**: Store varying data structures. -- **API Integration**: Easily handle JSON responses. -- **Data Analysis**: Aggregate and filter nested data. - -## Conclusion -Handling JSON data within SQL combines the flexibility of JSON with the robustness of SQL databases. By leveraging native JSON support, developers can efficiently store, query, and manipulate JSON data, optimizing database operations for modern applications. - -This file provides a comprehensive guide on handling JSON data within SQL, covering essential operations and examples for different databases. diff --git a/docs/languages/SQL/sql-3.md b/docs/languages/SQL/sql-3.md deleted file mode 100644 index 5513276af..000000000 --- a/docs/languages/SQL/sql-3.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -id: "sql_select_statement" -sidebar_position: 3 -title: "SQL SELECT" -sidebar_label: "SQL Select" -description: "The SELECT statement retrieves specific data from one or more tables in a database." -tags: [sql, dbms, database] ---- - - -## Syntax - -`SELECT _column1_, _column2_, ... FROM _table_name_;` - -Here, column1, column2, ... are the _field names_ of the table you want to select data from. - -The `table_name` represents the name of the _table_ you want to select data from. - -* * * - -## Demo Database - - -Below is a selection from the Customers table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -|------------|-------------------------------|----------------|------------------------|-------------|------------|----------| -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - -## Select ALL columns - -If you want to return all columns without specifying every column name, you can use the `SELECT *` syntax: - -### Example - -Return all the columns from the Customers table: - -`SELECT * FROM Customers;` - -SQL SELECT DISTINCT Statement ------------------------------ - -The SQL SELECT DISTINCT Statement ---------------------------------- - -The `SELECT DISTINCT` statement is used to return only distinct (different) values. - -### Example - -Select all the different countries from the "Customers" table: - -`SELECT DISTINCT Country FROM Customers;` - -Inside a table, a column often contains many duplicate values; and sometimes you only want to list the different (distinct) values. - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -|------------|-------------------------------|----------------|------------------------|-------------|------------|----------| -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - -## SELECT Example Without DISTINCT - -If you omit the `DISTINCT` keyword, the SQL statement returns the "Country" value from all the records of the "Customers" table: - -### Example - -`SELECT Country FROM Customers;` - -## Count Distinct - -By using the `DISTINCT` keyword in a function called `COUNT`, we can return the number of different countries. - -### Example - -`SELECT COUNT(DISTINCT Country) FROM Customers;` - -**Note:** The `COUNT(DISTINCT _column_name_)` is not supported in Microsoft Access databases. - -Here is a workaround for MS Access: - -### Example - -`SELECT Count(*) AS DistinctCountries FROM (SELECT DISTINCT Country FROM Customers);` - -You will learn about the COUNT function later in this tutorial. diff --git a/docs/languages/SQL/sql-4.md b/docs/languages/SQL/sql-4.md deleted file mode 100644 index 23e96a285..000000000 --- a/docs/languages/SQL/sql-4.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: "sql-where-clause" -sidebar_position: 4 -title: "SQL WHERE Clause" -sidebar_label: "SQL WHERE Clause" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `WHERE` clause is used to filter records. - -It is used to extract only those records that fulfill a specified condition. - -### Example - -Select all customers from Mexico: - -``` -SELECT \* FROM Customers -WHERE Country='Mexico'; -``` - -* * * - -### Syntax - -`SELECT _column1_, _column2, ..._ FROM _table_name_ WHERE _condition_;` - -**Note:** The `WHERE` clause is not only used in `SELECT` statements, it is also used in `UPDATE`, `DELETE`, etc.! - -* * * - -### Demo Database - -Below is a selection from the **Customers** table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -|------------|-------------------------------|----------------|------------------------|-------------|------------|----------| -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - -* * * - -## Text Fields vs. Numeric Fields - -SQL requires single quotes around text values (most database systems will also allow double quotes). - -However, numeric fields should not be enclosed in quotes: - -### Example - -``` -SELECT \* FROM Customers -WHERE CustomerID=1; -``` - -* * * - -## Operators in The WHERE Clause - -You can use other operators than the `=` operator to filter the search. - -### Example - -Select all customers with a CustomerID greater than 80: -``` -SELECT \* FROM Customers -WHERE CustomerID > 80; -``` - -The following operators can be used in the `WHERE` clause: - -| Operator | Description | -| --- | --- | -| `=` | Equal | -| `>` | Greater than | -| `<` | Less than | -| `>=` | Greater than or equal | -| `<=` | Less than or equal | -| `<>` | Not equal | -| `BETWEEN` | Between a certain range | -| `LIKE` | Search for a pattern | -| `IN` | To specify multiple possible values for a column | - -* * * - diff --git a/docs/languages/SQL/sql-5.md b/docs/languages/SQL/sql-5.md deleted file mode 100644 index 972675394..000000000 --- a/docs/languages/SQL/sql-5.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: "sql-order-by" -sidebar_position: 5 -title: "SQL ORDER BY" -sidebar_label: "SQL ORDER BY" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `ORDER BY` keyword is used to sort the result-set in ascending or descending order. - -### Example - -Sort the products by price: -``` -SELECT \* FROM Products -ORDER BY Price; -``` - -* * * - -### Syntax - -`SELECT _column1_, _column2, ..._ FROM _table_name_ ORDER BY _column1, column2, ..._ ASC|DESC;` - -* * * - -### Demo Database - -Below is a selection from the **Products** table used in the examples: - -| ProductID | ProductName | SupplierID | CategoryID | Unit | Price | -| --- | --- | --- | --- | --- | --- | -| 1 | Chais | 1 | 1 | 10 boxes x 20 bags | 18 | -| 2 | Chang | 1 | 1 | 24 - 12 oz bottles | 19 | -| 3 | Aniseed Syrup | 1 | 2 | 12 - 550 ml bottles | 10 | -| 4 | Chef Anton's Cajun Seasoning | 2 | 2 | 48 - 6 oz jars | 22 | -| 5 | Chef Anton's Gumbo Mix | 2 | 2 | 36 boxes | 21.35 | - -* * * - - -## DESC - -The `ORDER BY` keyword sorts the records in ascending order by default. To sort the records in descending order, use the `DESC` keyword. - -### Example - -Sort the products from highest to lowest price: -``` -SELECT \* FROM Products -ORDER BY Price DESC; -``` -* * * - -## Order Alphabetically - -For string values the `ORDER BY` keyword will order alphabetically: - -### Example - -Sort the products alphabetically by ProductName: -``` -SELECT \* FROM Products -ORDER BY ProductName; -``` - -* * * - -## Alphabetically DESC - -To sort the table reverse alphabetically, use the `DESC` keyword: - -### Example - -Sort the products by ProductName in reverse order: -``` -SELECT \* FROM Products -ORDER BY ProductName DESC; -``` - -* * * - -## ORDER BY Several Columns - -The following SQL statement selects all customers from the "Customers" table, sorted by the "Country" and the "CustomerName" column. This means that it orders by Country, but if some rows have the same Country, it orders them by CustomerName: - -### Example - -``` -SELECT \* FROM Customers -ORDER BY Country, CustomerName; -``` -* * * - -## Using Both ASC and DESC - -The following SQL statement selects all customers from the "Customers" table, sorted ascending by the "Country" and descending by the "CustomerName" column: - -### Example -``` -SELECT \* FROM Customers -ORDER BY Country ASC, CustomerName DESC; -``` -* * * - diff --git a/docs/languages/SQL/sql-6.md b/docs/languages/SQL/sql-6.md deleted file mode 100644 index de56cae2b..000000000 --- a/docs/languages/SQL/sql-6.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: "sql-and-operator" -sidebar_position: 6 -title: "SQL AND Operator" -sidebar_label: "SQL AND Operator" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - - -The `WHERE` clause can contain one or many `AND` operators. - -The `AND` operator is used to filter records based on more than one condition, like if you want to return all customers from Spain that starts with the letter 'G': - -### Example - -Select all customers from Spain that starts with the letter 'G': -``` -SELECT \* -FROM Customers -WHERE Country = 'Spain' AND CustomerName LIKE 'G%'; -``` -* * * - -### Syntax - -`SELECT _column1_, _column2, ..._ FROM _table_name_ WHERE _condition1_ AND _condition2_ AND _condition3 ..._;` - -* * * - -## AND vs OR - -The `AND` operator displays a record if _all_ the conditions are TRUE. - -The `OR` operator displays a record if _any_ of the conditions are TRUE. - -* * * - -### Demo Database - -Below is a selection from the **Customers** table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -|------------|-------------------------------|----------------|------------------------|-------------|------------|----------| -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - -* * * - - -## All Conditions Must Be True - -The following SQL statement selects all fields from `Customers` where `Country` is "Germany" AND `City` is "Berlin" AND `PostalCode` is higher than 12000: - -### Example -``` -SELECT \* FROM Customers -WHERE Country = 'Germany' -AND City = 'Berlin' -AND PostalCode > 12000; -``` -* * * - -## Combining AND and OR - -You can combine the `AND` and `OR` operators. - -The following SQL statement selects all customers from Spain that starts with a "G" or an "R". - -Make sure you use parenthesis to get the correct result. - -### Example - -Select all Spanish customers that starts with either "G" or "R": -``` -SELECT \* FROM Customers -WHERE Country = 'Spain' AND (CustomerName LIKE 'G%' OR CustomerName LIKE 'R%'); -``` - -Without parenthesis, the select statement will return all customers from Spain that starts with a "G", _plus_ all customers that starts with an "R", regardless of the country value: - -### Example - -Select all customers that either: -are from Spain and starts with either "G", _or_ -starts with the letter "R": - -``` -SELECT \* FROM Customers -WHERE Country = 'Spain' AND CustomerName LIKE 'G%' OR CustomerName LIKE 'R%'; -``` -* * * - diff --git a/docs/languages/SQL/sql-7.md b/docs/languages/SQL/sql-7.md deleted file mode 100644 index f6d1fa6a0..000000000 --- a/docs/languages/SQL/sql-7.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: "sql-or-operator" -sidebar_position: 7 -title: "SQL OR Operator" -sidebar_label: "SQL OR Operator" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `WHERE` clause can contain one or more `OR` operators. - -The `OR` operator is used to filter records based on more than one condition, like if you want to return all customers from Germany but also those from Spain: - -### Example - -Select all customers from Germany or Spain: -``` -SELECT \* -FROM Customers -WHERE Country = 'Germany' OR Country = 'Spain'; -``` -* * * - -### Syntax - -`SELECT _column1_, _column2, ..._ FROM _table_name_ WHERE _condition1_ OR _condition2_ OR _condition3 ..._;` - -* * * - -## OR vs AND - -The `OR` operator displays a record if _any_ of the conditions are TRUE. - -The `AND` operator displays a record if _all_ the conditions are TRUE. - -* * * - -### Demo Database - -Below is a selection from the **Customers** table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -|------------|-------------------------------|----------------|------------------------|-------------|------------|----------| -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - -* * * - -## At Least One Condition Must Be True - -The following SQL statement selects all fields from Customers where either `City` is "Berlin", `CustomerName` starts with the letter "G" or `Country` is "Norway": - -### Example -``` -SELECT \* FROM Customers -WHERE City = 'Berlin' OR CustomerName LIKE 'G%' OR Country = 'Norway'; -``` -* * * - -## Combining AND and OR - -You can combine the `AND` and `OR` operators. - -The following SQL statement selects all customers from Spain that starts with a "G" or an "R". - -Make sure you use parenthesis to get the correct result. - -### Example - -Select all Spanish customers that starts with either "G" or "R": -``` -SELECT \* FROM Customers -WHERE Country = 'Spain' AND (CustomerName LIKE 'G%' OR CustomerName LIKE 'R%'); -``` -Without parenthesis, the select statement will return all customers from Spain that starts with a "G", _plus_ all customers that starts with an "R", regardless of the country value: - -### Example - -Select all customers that either: -are from Spain and starts with either "G", _or_ -starts with the letter "R": -``` -SELECT \* FROM Customers -WHERE Country = 'Spain' AND CustomerName LIKE 'G%' OR CustomerName LIKE 'R%'; -``` -* * * diff --git a/docs/languages/SQL/sql-8.md b/docs/languages/SQL/sql-8.md deleted file mode 100644 index 058002789..000000000 --- a/docs/languages/SQL/sql-8.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: "sql-not-operator" -sidebar_position: 8 -title: "SQL NOT Operator" -sidebar_label: "SQL NOT Operator" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `NOT` operator is used in combination with other operators to give the opposite result, also called the negative result. - -In the select statement below we want to return all customers that are NOT from Spain: - -### Example - -Select only the customers that are NOT from Spain: -``` -SELECT \* FROM Customers -WHERE NOT Country = 'Spain'; -``` - -In the example above, the `NOT` operator is used in combination with the `=` operator, but it can be used in combination with other comparison and/or logical operators. See examples below. - -* * * - -### Syntax - -`SELECT _column1_, _column2, ..._ FROM _table_name_ WHERE NOT _condition_;` - -* * * - -### Demo Database - -Below is a selection from the **Customers** table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -|------------|-------------------------------|----------------|------------------------|-------------|------------|----------| -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | -* * * - -## NOT LIKE - -### Example - -Select customers that does not start with the letter 'A': -``` -SELECT \* FROM Customers -WHERE CustomerName NOT LIKE 'A%'; -``` -* * * - -## NOT BETWEEN - -### Example - -Select customers with a customerID not between 10 and 60: -``` -SELECT \* FROM Customers -WHERE CustomerID NOT BETWEEN 10 AND 60; -``` - - -## NOT IN -### Example - -Select customers that are not from Paris or London: -``` -SELECT \* FROM Customers -WHERE City NOT IN ('Paris', 'London'); -``` -* * * - -## NOT Greater Than - -### Example - -Select customers with a CustomerId not greater than 50: -``` -SELECT \* FROM Customers -WHERE NOT CustomerID > 50; -``` -**Note:** There is a not-greater-than operator: `!>` that would give you the same result. - -* * * - -## NOT Less Than - -### Example - -Select customers with a CustomerID not less than 50: -``` -SELECT \* FROM Customers -WHERE NOT CustomerId < 50; -``` -**Note:** There is a not-less-than operator: `!<` that would give you the same result. - -* * * - diff --git a/docs/languages/SQL/sql-9.md b/docs/languages/SQL/sql-9.md deleted file mode 100644 index 936b3026a..000000000 --- a/docs/languages/SQL/sql-9.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -id: sql-update-statement -sidebar_position: 9 -title: "SQL UPDATE Statement" -sidebar_label: "SQL UPDATE Statement" -description: "SQL (Structured Query Language) is a standardized programming language for managing and manipulating relational databases." -tags: [sql, dbms, database] ---- - -The `UPDATE` statement is used to modify existing records in a table. You can update specific records using the `WHERE` clause, or update all records in a table. - -In the statement below, we want to update the address of the customer with `CustomerID` 1. - -### Example - -Update the address for the customer with `CustomerID` equal to 1: - -```sql -UPDATE Customers -SET Address = 'New Address, 123' -WHERE CustomerID = 1; -``` - -In the example above, the `SET` clause specifies the column(s) to update, and the `WHERE` clause specifies which record(s) to modify. - ----### Syntax - -```sql -UPDATE table_name -SET column1 = value1, column2 = value2, ... -WHERE condition; -``` - -If you omit the `WHERE` clause, all records in the table will be updated. - ---- - -### Demo Database - -Below is a selection from the **Customers** table used in the examples: - -| CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country | -| ---------- | ---------------------------------- | ------------------ | ----------------------------- | ----------- | ---------- | ------- | -| 1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany | -| 2 | Ana Trujillo Emparedados y Helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico | -| 3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico | -| 4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK | -| 5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden | - ---- - -## Updating Multiple Columns - -### Example - -Update both the `Address` and `City` for the customer with `CustomerID` equal to 2: - -```sql -UPDATE Customers -SET Address = 'New Street 456', City = 'Berlin' -WHERE CustomerID = 2; -``` - ---- - -## Updating All Records - -### Example - -Increase all customer postal codes by 100: - -```sql -UPDATE Customers -SET PostalCode = PostalCode + 100; -``` - -**Note:** Be careful when using `UPDATE` without a `WHERE` clause, as it will modify all records in the table. - ---- - -## Using Subquery in UPDATE - -### Example - -Update customers’ `City` based on another table called `Orders`: - -```sql -UPDATE Customers -SET City = (SELECT ShipCity FROM Orders WHERE Orders.CustomerID = Customers.CustomerID) -WHERE Country = 'USA'; -``` - -In this example, a subquery is used to select the `ShipCity` from the `Orders` table for updating `City` in the `Customers` table. - ---- - -## Conditional Update with CASE - -### Example - -Update the `City` based on customer conditions using the `CASE` statement: - -```sql -UPDATE Customers -SET City = CASE - WHEN Country = 'Mexico' THEN 'Mexico City' - WHEN Country = 'Germany' THEN 'Munich' - ELSE City - END; -``` - -The `CASE` statement is used here to conditionally update the `City` field based on the `Country` field. - ---- diff --git a/docs/languages/_category_.json b/docs/languages/_category_.json deleted file mode 100644 index 4b7ca7825..000000000 --- a/docs/languages/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Languages", - "position": 3, - "link": { - "type": "generated-index", - "description": "5 minutes to learn the most important RoadMap for Basic Concepts of programming." - } - } \ No newline at end of file diff --git a/docs/languages/cpp/_category_.json b/docs/languages/cpp/_category_.json deleted file mode 100644 index 08142e368..000000000 --- a/docs/languages/cpp/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "C++", - "position": 3, - "link": { - "type": "generated-index", - "description": "C++ is a compiled, high-level, general-purpose programming language. Developed by Bjarne Stroustrup and first released in 1985, C++ builds on C with object-oriented features, allowing for both low-level memory manipulation and high-level abstractions, making it suitable for a wide range of applications." - } - } \ No newline at end of file diff --git a/docs/languages/cpp/cp-0.md b/docs/languages/cpp/cp-0.md deleted file mode 100644 index e4e9871c8..000000000 --- a/docs/languages/cpp/cp-0.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -id: introduction-to-cpp -sidebar_position: 0 -title: "Introduction to C++" -sidebar_label: "Introduction to C++" ---- - -Welcome to the world of C++! In this guide, we'll explore the fundamentals of C++, a powerful programming language that is widely used in system/software development, game development, and performance-critical applications. Let’s get started! - -## 1. What is C++? - -C++ is a high-level programming language developed by Bjarne Stroustrup in the late 1970s as an extension of the C programming language. It introduces object-oriented programming (OOP) concepts, enabling developers to create complex systems using modular code. - -## 2. Key Features of C++ - -- **Object-Oriented Programming (OOP):** C++ supports OOP principles like encapsulation, inheritance, and polymorphism, allowing for better organization of code. -- **Rich Standard Library:** C++ comes with a robust standard library that provides functions and classes for various tasks, including data manipulation and file handling. -- **Low-Level Manipulation:** C++ allows for direct manipulation of hardware resources and memory, making it suitable for system programming. -- **Portability:** C++ code can be compiled and run on different platforms with little or no modification. -- **Performance:** C++ is designed for performance and efficiency, making it a popular choice for resource-intensive applications. - -## 3. Setting Up C++ - -To start programming in C++, you'll need to set up a development environment. Here are some popular options: - -- **Integrated Development Environments (IDEs):** - - **Code::Blocks**: A free, open-source IDE that is simple to use. - - **Visual Studio**: A powerful IDE for Windows with extensive features. - - **Eclipse**: A versatile IDE that supports various programming languages. - -- **Compilers:** - - **GCC (GNU Compiler Collection)**: A popular open-source compiler for Windows, Linux, and macOS. - - **Clang**: A compiler that is part of the LLVM project, known for its fast compilation times. - -## 4. Writing Your First C++ Program - -Here’s a simple "Hello, World!" program to get you started: - -```cpp -#include // Include the input-output stream library - -int main() { - std::cout << "Hello, World!" << std::endl; // Print "Hello, World!" to the console - return 0; // Return 0 to indicate successful execution -} -``` - -Explanation: - -```cpp -#include : This line includes the standard input-output stream library, which is necessary for using std::cout. -int main(): This is the main function where the program execution starts. -std::cout << "Hello, World!": This line outputs the text "Hello, World!" to the console. -return 0;: This indicates that the program executed successfully. -``` - -## 5. Basic Syntax -Comments: Use // for single-line comments and /* */ for multi-line comments. - - -```cpp -// This is a single-line comment -/* This is a - multi-line comment */ -``` - - -Semicolons: Each statement in C++ ends with a semicolon (;). - -Braces: Curly braces (`{}`) are used to define the beginning and end of code blocks. - -## 6. Conclusion -C++ is a versatile and powerful programming language that has stood the test of time. With its support for both high-level and low-level programming, it is ideal for various applications, from system software to game development. Understanding the fundamentals of C++ will pave the way for developing efficient and robust applications. - diff --git a/docs/languages/cpp/cp-1.md b/docs/languages/cpp/cp-1.md deleted file mode 100644 index 33fb76bc2..000000000 --- a/docs/languages/cpp/cp-1.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -id: datatypes-in-cpp -sidebar_position: 1 -title: "Datatypes in C++" -sidebar_label: "Datatypes in C++" ---- - -Hey there! In this guide, we'll explore the different data types available in C++. Understanding data types is crucial for writing efficient and clear C++ code. Let's dive in! - -* In C++, variables are containers that hold data and are defined by specifying a type followed by the variable name. -* Variables must be declared before use and can hold various data types. - -## 1. Declaring Variables in C++ - -- To declare a variable in C++, you specify its type, followed by the variable's name. -```cpp -int age; -double salary; -char grade; -``` - -## 2. Initializing Variables in C++ - -- Variables can be initialized with a value at the time of declaration. -```cpp -int age = 25; -double salary = 45000.50; -char grade = 'A'; -``` - -## 3. Types of Variables in C++ - -### a. Integer Variables (`int`) -- Holds whole numbers, both positive and negative. -```cpp -int x = 10; -int y = -20; -``` - -### b. Floating-Point Variables (`float`, `double`) -- Represents real numbers, with `float` using less precision than `double`. -```cpp -float pi = 3.14f; -double gravity = 9.81; -``` - -### c. Character Variables (`char`) -- Stores a single character enclosed in single quotes. -```cpp -char initial = 'A'; -``` - -### d. Boolean Variables (`bool`) -- Holds either `true` or `false` values. -```cpp -bool is_sunny = true; -bool is_raining = false; -``` - -### e. String Variables (`std::string`) - -```python -my_list = [1, 2, 3] -my_tuple = tuple(my_list) -print(my_tuple) # Output: (1, 2, 3) -print(type(my_tuple)) # Output: -``` - -## 4. Variable Scope -- The scope of a variable refers to the region of the program where the variable is accessible. - - **Local Variables:** Declared inside functions or blocks, only accessible within that block. - - **Global Variables:** Declared outside all functions and accessible from any part of the program. - -### a. Local Variable Example: - -```cpp -void myFunction() { - int localVar = 10; // Only accessible inside myFunction -} -``` - -### b. Global Variable Example: - -```cpp -int globalVar = 20; // Accessible throughout the program - -void myFunction() { - globalVar = 30; // Modifying globalVar -} -``` - -## 5. Constant Variables -- Variables declared as `const` cannot be modified after initialization. - -```cpp -const int MAX_AGE = 100; -``` - -## 6. Type Conversion -C++ allows conversion between data types either implicitly or explicitly (using type casting). - -### a. Implicit Type Conversion -- C++ automatically converts one type to another when necessary. -```cpp -int x = 10; -double y = x; // Implicit conversion from int to double -``` - -### b. Explicit Type Conversion (Casting) -- You can explicitly convert a variable's type using type casting. -```cpp -double pi = 3.14; -int int_pi = (int)pi; // Cast double to int -``` -## 7. Dynamic Variables -- Variables that are allocated memory during runtime using pointers and dynamic memory allocation (`new` and `delete`). -```cpp -int* ptr = new int; // Dynamically allocate memory for an integer -*ptr = 5; -delete ptr; // Free the allocated memory -``` - ---- - -Variables are a crucial part of any C++ program, and understanding how to use them effectively is key to writing efficient C++ code. \ No newline at end of file diff --git a/docs/languages/cpp/cp-10.md b/docs/languages/cpp/cp-10.md deleted file mode 100644 index 5a0ee7e3e..000000000 --- a/docs/languages/cpp/cp-10.md +++ /dev/null @@ -1,269 +0,0 @@ ---- -id: inheritance-in-cpp -sidebar_position: 10 -title: "Inheritance in C++" -sidebar_label: "Inheritance in C++" ---- - -# Inheritance in C++ - -Inheritance is one of the fundamental concepts of object-oriented programming (OOP) in C++. It allows one class (called the derived or child class) to inherit attributes and methods from another class (called the base or parent class). - ---- - -## 1. What is Inheritance? - -Inheritance enables the creation of new classes based on existing ones. The derived class inherits the properties (attributes and behaviors) of the base class and can add its own properties or override the inherited ones. - ---- - -## 2. Types of Inheritance in C++ - -C++ supports various types of inheritance: - -### a. Single Inheritance: - -A derived class inherits from a single base class. - -```cpp -class Base { - // Base class code -}; - -class Derived : public Base { - // Derived class code -}; -``` - -### b. Multiple Inheritance: - -A derived class can inherit from more than one base class. - -```cpp -class Base1 { - // Base class 1 code -}; - -class Base2 { - // Base class 2 code -}; - -class Derived : public Base1, public Base2 { - // Derived class code -}; -``` - -### c. Multilevel Inheritance: - -A class is derived from another derived class. - -```cpp -class Base { - // Base class code -}; - -class Intermediate : public Base { - // Intermediate derived class code -}; - -class Derived : public Intermediate { - // Final derived class code -}; -``` - -### d. Hierarchical Inheritance: - -Multiple derived classes inherit from the same base class. - -```cpp -class Base { - // Base class code -}; - -class Derived1 : public Base { - // Derived class 1 code -}; - -class Derived2 : public Base { - // Derived class 2 code -}; -``` - -### e. Hybrid Inheritance: - -Combination of two or more types of inheritance. - -```cpp -class Base { - // Base class code -}; - -class Derived1 : public Base { - // Derived class 1 code -}; - -class Derived2 : public Derived1 { - // Derived class 2 code -}; -``` - ---- - -## 3. Access Specifiers in Inheritance - -When a class is derived, the accessibility of base class members depends on the access specifier used. The most common access specifiers are: - -- **public**: Members of the base class remain in the same access level in the derived class. -- **protected**: Public members of the base class become protected in the derived class. -- **private**: All members of the base class become private in the derived class. - ---- - -## 4. Syntax of Inheritance - -#### Basic Syntax: - -```cpp -class Base { - // Base class definition -}; - -class Derived : public Base { - // Derived class definition -}; -``` - ---- - -## 5. Example of Single Inheritance - -```cpp -#include -using namespace std; - -class Animal { -public: - void eat() { - cout << "This animal eats food." << endl; - } -}; - -class Dog : public Animal { -public: - void bark() { - cout << "The dog barks." << endl; - } -}; - -int main() { - Dog myDog; - myDog.eat(); // Inherited from Animal class - myDog.bark(); // Defined in Dog class - return 0; -} -``` - -#### Output: - -``` -This animal eats food. -The dog barks. -``` - ---- - -## 6. Overriding Inherited Methods - -A derived class can override the methods of the base class to provide its own implementation. - -#### Example: - -```cpp -#include -using namespace std; - -class Animal { -public: - virtual void sound() { - cout << "Animals make sound." << endl; - } -}; - -class Dog : public Animal { -public: - void sound() override { - cout << "Dogs bark." << endl; - } -}; - -int main() { - Animal* animalPtr; - Dog myDog; - - animalPtr = &myDog; - animalPtr->sound(); // Calls Dog's sound() method - - return 0; -} -``` - -#### Output: - -``` -Dogs bark. -``` - ---- - -## 7. Constructors in Inheritance - -Constructors of the base class are not inherited by the derived class. However, the base class constructor can be called from the derived class. - -#### Example: - -```cpp -#include -using namespace std; - -class Base { -public: - Base() { - cout << "Base class constructor." << endl; - } -}; - -class Derived : public Base { -public: - Derived() { - cout << "Derived class constructor." << endl; - } -}; - -int main() { - Derived obj; // Calls both Base and Derived class constructors - return 0; -} -``` - -#### Output: - -``` -Base class constructor. -Derived class constructor. -``` - ---- - -## 8. Advantages of Inheritance - -1. **Code Reusability**: Inheritance allows the reuse of code written in base classes. -2. **Extensibility**: Existing classes can be easily extended to add new functionality. -3. **Maintainability**: Changes in the base class are automatically reflected in the derived classes. - ---- - -## 9. Final Thoughts - -Inheritance in C++ is a powerful tool that allows you to extend and reuse existing code, making your programs more efficient and modular. However, it is essential to use it wisely to avoid complexity and maintain clarity in your codebase. - -Happy coding! diff --git a/docs/languages/cpp/cp-11.md b/docs/languages/cpp/cp-11.md deleted file mode 100644 index f51cb002e..000000000 --- a/docs/languages/cpp/cp-11.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -id: polymorphism-in-cpp -sidebar_position: 11 -title: "Polymorphism in C++" -sidebar_label: "Polymorphism in C++" ---- - -# Polymorphism in C++ - -Polymorphism is one of the four fundamental concepts of Object-Oriented Programming (OOP) in C++. It allows objects of different types to be treated as objects of a common base class. Polymorphism enables functions to use objects of different types through a single interface. - ---- - -## 1. What is Polymorphism? - -Polymorphism means "many shapes" in Greek. In C++, polymorphism allows you to redefine the way functions behave for different types. It can be classified into two main types: - -- **Compile-time Polymorphism (Static Binding)**: Achieved using function overloading and operator overloading. -- **Runtime Polymorphism (Dynamic Binding)**: Achieved using inheritance and virtual functions. - ---- - -## 2. Types of Polymorphism in C++ - -### a. Compile-Time Polymorphism (Static Polymorphism) - -Compile-time polymorphism occurs when the function to be invoked is determined at compile time. It is achieved using: - -1. **Function Overloading** -2. **Operator Overloading** - ---- - -### i. Function Overloading - -Function overloading allows multiple functions with the same name but different parameter types or numbers to coexist. - -#### Example: - -```cpp -#include -using namespace std; - -class Print { -public: - void display(int i) { - cout << "Displaying int: " << i << endl; - } - - void display(double d) { - cout << "Displaying double: " << d << endl; - } - - void display(string s) { - cout << "Displaying string: " << s << endl; - } -}; - -int main() { - Print obj; - obj.display(5); - obj.display(6.7); - obj.display("Hello"); - return 0; -} -``` - -#### Output: - -``` -Displaying int: 5 -Displaying double: 6.7 -Displaying string: Hello -``` - ---- - -### ii. Operator Overloading - -Operator overloading allows you to redefine the way operators work for user-defined types (such as classes). - -#### Example: - -```cpp -#include -using namespace std; - -class Complex { -private: - float real, imag; - -public: - Complex() : real(0), imag(0) {} - - Complex operator + (const Complex &obj) { - Complex temp; - temp.real = real + obj.real; - temp.imag = imag + obj.imag; - return temp; - } - - void display() { - cout << "Real: " << real << ", Imaginary: " << imag << endl; - } -}; - -int main() { - Complex c1, c2, result; - result = c1 + c2; - result.display(); - return 0; -} -``` - -#### Output: - -``` -Real: 0, Imaginary: 0 -``` - ---- - -## 3. Runtime Polymorphism (Dynamic Polymorphism) - -Runtime polymorphism occurs when the function call is resolved at runtime. It is achieved using **inheritance** and **virtual functions**. - -### a. Virtual Functions - -A virtual function is a member function that is declared within the base class and redefined by a derived class. It is used to achieve runtime polymorphism. - -#### Syntax: - -```cpp -class Base { -public: - virtual void function_name() { - // Base class code - } -}; -``` - ---- - -### Example of Runtime Polymorphism: - -```cpp -#include -using namespace std; - -class Animal { -public: - virtual void sound() { - cout << "This is an animal sound." << endl; - } -}; - -class Dog : public Animal { -public: - void sound() override { - cout << "The dog barks." << endl; - } -}; - -class Cat : public Animal { -public: - void sound() override { - cout << "The cat meows." << endl; - } -}; - -int main() { - Animal* animalPtr; - Dog dog; - Cat cat; - - animalPtr = &dog; - animalPtr->sound(); // Calls Dog's sound() - - animalPtr = &cat; - animalPtr->sound(); // Calls Cat's sound() - - return 0; -} -``` - -#### Output: - -``` -The dog barks. -The cat meows. -``` - ---- - -## 4. Pure Virtual Functions and Abstract Classes - -A **pure virtual function** is a virtual function with no definition in the base class, and a class containing a pure virtual function is called an abstract class. You cannot instantiate an abstract class. - -#### Syntax: - -```cpp -class AbstractBase { -public: - virtual void show() = 0; // Pure virtual function -}; -``` - -### Example of Abstract Class: - -```cpp -#include -using namespace std; - -class Shape { -public: - virtual void area() = 0; // Pure virtual function -}; - -class Circle : public Shape { -public: - void area() { - cout << "Area of Circle" << endl; - } -}; - -int main() { - Circle c; - c.area(); // Calls Circle's area function - return 0; -} -``` - -#### Output: - -``` -Area of Circle -``` - ---- - -## 5. Advantages of Polymorphism - -1. **Code Reusability**: Allows functions to operate on different types. -2. **Flexibility**: Easier to change or extend the system with new types. -3. **Maintainability**: Polymorphism simplifies code structure and reduces complexity. - ---- - -## 6. Final Thoughts - -Polymorphism in C++ provides a flexible and powerful mechanism for handling multiple types of objects and making your code more scalable and maintainable. It's a crucial concept in OOP and is used extensively in software development. - -Happy coding! diff --git a/docs/languages/cpp/cp-12.md b/docs/languages/cpp/cp-12.md deleted file mode 100644 index c511460c0..000000000 --- a/docs/languages/cpp/cp-12.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: templates-in-cpp -sidebar_position: 12 -title: "Templates in C++" -sidebar_label: "Templates in C++" ---- - -# Templates in C++ - -Templates are a powerful feature in C++ that allow functions and classes to operate with generic types. This means you can write a function or class to work with any data type, without having to rewrite it for each type. - ---- - -## 1. What are Templates? - -Templates in C++ allow you to create **generic functions** and **generic classes**. You can define a function or class once and use it with different data types without rewriting it for each one. - -### Types of Templates: - -1. **Function Templates** -2. **Class Templates** - ---- - -## 2. Function Templates - -A function template works with any data type. You can write a function template that works for **int**, **float**, **double**, or any other type. - -#### Syntax of a Function Template: - -```cpp -template -T function_name(T arg1, T arg2) { - // Code here -} -``` - -- `T` is the placeholder for the data type. - ---- - -### Example of a Function Template: - -```cpp -#include -using namespace std; - -template -T add(T a, T b) { - return a + b; -} - -int main() { - cout << "Sum of integers: " << add(5, 10) << endl; - cout << "Sum of floats: " << add(5.5, 10.1) << endl; - return 0; -} -``` - -#### Output: - -``` -Sum of integers: 15 -Sum of floats: 15.6 -``` - ---- - -## 3. Class Templates - -A class template allows you to create a class that can work with any data type. This is useful for creating data structures like stacks, queues, or linked lists that can handle any type of data. - -#### Syntax of a Class Template: - -```cpp -template -class ClassName { - T variable; -public: - ClassName(T var) : variable(var) {} - void display() { - cout << "Variable: " << variable << endl; - } -}; -``` - ---- - -### Example of a Class Template: - -```cpp -#include -using namespace std; - -template -class Container { - T value; -public: - Container(T val) : value(val) {} - void display() { - cout << "Value: " << value << endl; - } -}; - -int main() { - Container intContainer(42); - Container stringContainer("Hello"); - - intContainer.display(); - stringContainer.display(); - - return 0; -} -``` - -#### Output: - -``` -Value: 42 -Value: Hello -``` - ---- - -## 4. Template Specialization - -Sometimes, you might want to provide a specific implementation of a template for a particular data type. This is called **template specialization**. - ---- - -### Example of Template Specialization: - -```cpp -#include -using namespace std; - -template -class Calculator { -public: - T add(T a, T b) { - return a + b; - } -}; - -// Specialization for string data type -template <> -class Calculator { -public: - string add(string a, string b) { - return a + " " + b; - } -}; - -int main() { - Calculator intCalc; - Calculator stringCalc; - - cout << "Sum of integers: " << intCalc.add(5, 10) << endl; - cout << "Concatenated strings: " << stringCalc.add("Hello", "World") << endl; - - return 0; -} -``` - -#### Output: - -``` -Sum of integers: 15 -Concatenated strings: Hello World -``` - ---- - -## 5. Advantages of Templates - -1. **Code Reusability**: You write a generic function or class once, and use it with any data type. -2. **Type Safety**: Templates are type-safe and checked during compilation. -3. **Flexibility**: Templates allow you to create more flexible, reusable, and maintainable code. - ---- - -## 6. Final Thoughts - -Templates in C++ offer a powerful way to create functions and classes that can work with any data type. They help in writing generic, reusable code and are a key feature in modern C++ programming. - -Happy coding! diff --git a/docs/languages/cpp/cp-13.md b/docs/languages/cpp/cp-13.md deleted file mode 100644 index 7cae4da0b..000000000 --- a/docs/languages/cpp/cp-13.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -id: stl-in-cpp -sidebar_position: 13 -title: "STL in C++" -sidebar_label: "STL In C++" ---- - -# STL in C++ - -In this guide, we will explore the **Standard Template Library (STL)** in C++, which is a powerful library that provides data structures and algorithms in an organized manner. STL helps in writing efficient and maintainable code by offering a wide range of functionalities. - ---- - -## 1. Introduction to STL - -STL in C++ is divided into three main components: - -- **Containers**: Data structures to store objects. -- **Algorithms**: Procedures to process the data stored in containers. -- **Iterators**: Objects that point to elements in containers and allow navigation. - ---- - -## 2. Containers - -Containers are used to store collections of data. They are categorized into three types: - -### 2.1 Sequence Containers - -These containers store data in a linear sequence. - -| Container | Description | -| --------- | ------------------ | -| `vector` | Dynamic array | -| `deque` | Double-ended queue | -| `list` | Doubly linked list | - -#### Example: - -```cpp -#include -#include -using namespace std; - -int main() { - vector numbers = {1, 2, 3, 4, 5}; - for (int num : numbers) { - cout << num << " "; - } - return 0; -} -``` - -#### Output: - -``` -1 2 3 4 5 -``` - ---- - -### 2.2 Associative Containers - -These containers store data in key-value pairs, providing fast search and retrieval. - -| Container | Description | -| ---------- | ----------------------------- | -| `set` | Collection of unique elements | -| `map` | Key-value pairs | -| `multiset` | Allows duplicate values | -| `multimap` | Allows duplicate keys | - -#### Example: - -```cpp -#include -#include -using namespace std; - -int main() { - map students; - students[1] = "Alice"; - students[2] = "Bob"; - - for (auto& student : students) { - cout << student.first << ": " << student.second << endl; - } - return 0; -} -``` - -#### Output: - -``` -1: Alice -2: Bob -``` - ---- - -### 2.3 Container Adaptors - -These are wrappers around sequence containers and provide restricted interfaces. - -| Container | Description | -| ---------------- | --------------------------- | -| `stack` | LIFO (Last In First Out) | -| `queue` | FIFO (First In First Out) | -| `priority_queue` | Elements sorted by priority | - -#### Example (Stack): - -```cpp -#include -#include -using namespace std; - -int main() { - stack s; - s.push(10); - s.push(20); - s.push(30); - - while (!s.empty()) { - cout << s.top() << " "; - s.pop(); - } - return 0; -} -``` - -#### Output: - -``` -30 20 10 -``` - ---- - -## 3. Iterators - -Iterators are used to point to elements in containers. They provide a mechanism to traverse through elements. - -### Types of Iterators: - -- **Input Iterator**: Reads values in a sequence. -- **Output Iterator**: Writes values in a sequence. -- **Forward Iterator**: Can move in one direction (forward). -- **Bidirectional Iterator**: Can move both forward and backward. -- **Random Access Iterator**: Provides direct access to any element. - -#### Example: - -```cpp -#include -#include -using namespace std; - -int main() { - vector vec = {10, 20, 30, 40}; - vector::iterator it; - - for (it = vec.begin(); it != vec.end(); ++it) { - cout << *it << " "; - } - return 0; -} -``` - -#### Output: - -``` -10 20 30 40 -``` - ---- - -## 4. Algorithms - -STL provides a rich set of algorithms to work with data stored in containers. These algorithms work with iterators. - -### 4.1 `sort()` - -Sorts elements in a range. - -#### Example: - -```cpp -#include -#include -#include -using namespace std; - -int main() { - vector vec = {4, 2, 5, 1, 3}; - sort(vec.begin(), vec.end()); - - for (int num : vec) { - cout << num << " "; - } - return 0; -} -``` - -#### Output: - -``` -1 2 3 4 5 -``` - ---- - -### 4.2 `find()` - -Searches for a specific value in a range. - -#### Example: - -```cpp -#include -#include -#include -using namespace std; - -int main() { - vector vec = {10, 20, 30, 40, 50}; - auto it = find(vec.begin(), vec.end(), 30); - - if (it != vec.end()) { - cout << "Element found: " << *it << endl; - } else { - cout << "Element not found" << endl; - } - - return 0; -} -``` - -#### Output: - -``` -Element found: 30 -``` - ---- - -### 4.3 `reverse()` - -Reverses the order of elements in a range. - -#### Example: - -```cpp -#include -#include -#include -using namespace std; - -int main() { - vector vec = {1, 2, 3, 4, 5}; - reverse(vec.begin(), vec.end()); - - for (int num : vec) { - cout << num << " "; - } - return 0; -} -``` - -#### Output: - -``` -5 4 3 2 1 -``` - ---- - -## 5. FUNCTORS : - -Functors are objects that can be treated as though they are a function. Functors are most commonly used along with STL algorithms. It overloads the function-call operator `()` and allows us to use an object like a function. - -### Types of FUNCTORS : - -* Arithmetic Functors -* Relational Functors -* Logical Functors -* Bitwise Functors - -### 5.1 Arithmetic Functors : -* `plus` – Returns the sum of two parameters. -* `minus` – Returns the difference of two parameters. -* `multiplies` – Returns the product of two parameters. -* `divides` – Returns the result after dividing two parameters. -* `modulus` – Returns the remainder after dividing two parameters. -* `negate` – Returns the negated value of a parameter. - -### 5.2 Relational Functors : -* `equal_to` – Returns true if the two parameters are equal. -* `not_equal_to` – Returns true if the two parameters are not equal. -* `greater` – Returns true if the first parameter is greater than the second. -* `greater_equal` – Returns true if the first parameter is greater than or equal to the second. -* `less` – Returns true if the first parameter is less than the second. -* `less_equal` – Returns true if the first parameter is less than or equal to the second. - -### 5.3 Logical Functors : - -* `logical_and` – Returns the result of Logical AND operation of two parameters. -* `logical_or` – Returns the result of Logical OR operation of two parameters. -* `logical_not` – Returns the result of Logical NOT operation of the parameters. - -### 5.4 Bitwise Functors : -* `bit_and` – Returns the result of Bitwise AND operation of two parameters. -* `bit_or` – Returns the result of Bitwise OR operation of two parameters. -* `bit_xor` – Returns the result of Bitwise XOR operation of two parameters. - - -## 6. Commonly Used STL Algorithms - -Here are some commonly used algorithms in STL: - -- **`count()`**: Counts occurrences of an element. -- **`max_element()`**: Finds the largest element. -- **`min_element()`**: Finds the smallest element. -- **`accumulate()`**: Sums up all elements. -- **`binary_search()`**: Searches for an element using binary search. - ---- - -## Conclusion - -The STL in C++ provides a wide range of containers, iterators, and algorithms that help make your code more efficient and easier to maintain. By mastering STL, you can write cleaner and faster code. Happy coding! diff --git a/docs/languages/cpp/cp-2.md b/docs/languages/cpp/cp-2.md deleted file mode 100644 index 10bad4475..000000000 --- a/docs/languages/cpp/cp-2.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -id: operators-in-cpp -sidebar_position: 2 -title: "Operators in C++" -sidebar_label: "Operators in C++" ---- - - -Hey there! In this guide, we'll explore operators in C++. Operators are symbols that instruct the compiler to perform specific operations on variables or values. C++ supports a variety of operators, including arithmetic, relational, logical, bitwise, and more. Let's dive in! - -- Operators are symbols that instruct the compiler to perform specific operations on variables or values. -- C++ supports a variety of operators, including arithmetic, relational, logical, bitwise, and more. - -## 1. Arithmetic Operators - -Arithmetic operators perform mathematical operations such as addition, subtraction, multiplication, and division. - -| Operator | Description | Example | -| -------- | ------------------- | ------- | -| + | Addition | x + y | -| - | Subtraction | x - y | -| * | Multiplication | x * y | -| / | Division | x / y | -| % | Modulus (remainder) | x % y | - -#### Example: - -```cpp -int x = 10, y = 5; -cout << (x + y); // Output: 15 -cout << (x - y); // Output: 5 -cout << (x * y); // Output: 50 -cout << (x / y); // Output: 2 -cout << (x % y); // Output: 0 -``` - -## 2. Relational Operators - -Relational operators compare two values and return a boolean result (`true` or `false`). - -| Operator | Description | Example | -|----------|--------------------|---------| -| == | Equal to | x == y | -| != | Not equal to | x != y | -| \> | Greater than | x \> y | -| \< | Less than | x \< y | -| \>= | Greater than or equal to | x \>= y | -| \<= | Less than or equal to | x \<= y | - -#### Example: - -```cpp -int x = 10, y = 5; -cout << (x == y); // Output: false -cout << (x != y); // Output: true -cout << (x > y); // Output: true -cout << (x < y); // Output: false -cout << (x >= y); // Output: true -cout << (x <= y); // Output: false -``` - -## 3. Logical Operators - -Logical operators are used to perform logical operations and combine multiple conditions. - -| Operator | Description | Example | -|----------|-------------|---------| -| && | Logical AND | (x \> 5 && y \< 10) | -| || | Logical OR | (x \> 5 || y \< 10) | -| ! | Logical NOT | !(x \> 5) | - -#### Example: - -```cpp -int x = 10, y = 5; -cout << (x > 5 && y < 10); // Output: 1 (true) -cout << (x > 5 || y > 10); // Output: 1 (true) -cout << !(x > 5); // Output: 0 (false) -``` - -## 4. Assignment Operators - -Assignment operators are used to assign values to variables. - -| Operator | Description | Example | -|----------|---------------------|-------------| -| = | Assigns value | x = y | -| += | Adds and assigns | x += y | -| -= | Subtracts and assigns| x -= y | -| *= | Multiplies and assigns| x *= y | -| /= | Divides and assigns | x /= y | -| %= | Modulus and assigns | x %= y | - -#### Example: - -```cpp -int x = 10, y = 5; -x += y; // Equivalent to x = x + y -cout << x; // Output: 15 -``` - -## 5. Increment and Decrement Operators - -Increment and decrement operators are used to increase or decrease a variable's value by 1. - -| Operator | Description | Example | -|----------|-----------------|-----------------| -| ++ | Increments value | ++x or x++ | -| -- | Decrements value | --x or x-- | - -#### Example: - -```cpp -int x = 10; -cout << ++x; // Output: 11 (Pre-increment) -cout << x--; // Output: 11 (Post-decrement) -cout << x; // Output: 10 -``` - -## 6. Bitwise Operators - -Bitwise operators operate on bits and perform bit-level operations. - -| Operator | Description | Example | -|----------|---------------|-------------| -| & | Bitwise AND | x & y | -| | | Bitwise OR | x | y | -| ^ | Bitwise XOR | x ^ y | -| ~ | Bitwise NOT | ~x | -| \>\> | Left shift | x \>\> 2 | -| \<\< | Right shift | x \<\< 2 | - -#### Example: - -```cpp -int x = 10; -int x = 5, y = 9; -cout << (x & y); // Output: 1 -cout << (x | y); // Output: 13 -``` - -## 7. Ternary Operator - -The ternary operator is a shorthand for an if-else statement. - -| Operator | Description | Example | -|----------|-------------|---------------------------| -| ?: | Ternary | condition ? expr1 : expr2 | - -#### Example: - -```cpp -int x = 10; -int result = (x > 5) ? 100 : 200; -cout << result; // Output: 100 -``` - ---- - -Understanding these operators is key to mastering C++ programming and writing efficient code! \ No newline at end of file diff --git a/docs/languages/cpp/cp-3.md b/docs/languages/cpp/cp-3.md deleted file mode 100644 index c6cfdfcca..000000000 --- a/docs/languages/cpp/cp-3.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: control-statements-in-cpp -sidebar_position: 3 -title: "Control Statements in C++" -sidebar_label: "Control Statements in C++" ---- - - -Hey there! In this guide, we'll explore decision-making in C++. Conditional statements, also called decision control structures, like `if`, `else` `if`, `else`, and `switch` are used for making decisions in C programs. - -Referred to as Decision-Making Statements, they assess one or more conditions and determine whether a block of code should be executed. -These statements: -* Guide the flow of program execution -* Choosing the path based on evaluated conditions -* Decision-making structures allow you to execute different blocks of code based on certain conditions. -* C++ provides several constructs for decision-making, including `if`, `else` `if`, `else`, and `switch`. - -## 1. The `if` Statement -#### Syntax: -```cpp -if (condition) { - // code to be executed if condition is true -} -``` -#### Example: -```cpp -int num = 10; -if (num > 0) { - std::cout << "The number is positive." << std::endl; -} -``` - -## 2. The `if...else` Statement -#### Syntax: -```cpp -if (condition1) { - // code to be executed if condition1 is true -} else if (condition2) { - // code to be executed if condition2 is true -} else { - // code to be executed if both conditions are false -} - -``` -#### Example: -```cpp -int num = -5; -if (num > 0) { - std::cout << "The number is positive." << std::endl; -} else { - std::cout << "The number is not positive." << std::endl; -} -``` - -## 3. The `if...else if...else` Statement -#### Syntax: -```cpp -if (condition1) { - // code to be executed if condition1 is true -} else if (condition2) { - // code to be executed if condition2 is true -} else { - // code to be executed if both conditions are false -} - -``` -#### Example: -```cpp -int num = 0; -if (num > 0) { - std::cout << "The number is positive." << std::endl; -} else if (num < 0) { - std::cout << "The number is negative." << std::endl; -} else { - std::cout << "The number is zero." << std::endl; -} - -``` - - -## 4. The `switch` Statement -#### Syntax: -```cpp -switch (expression) { - case value1: - // code to be executed if expression == value1 - break; - case value2: - // code to be executed if expression == value2 - break; - default: - // code to be executed if expression doesn't match any case -} -``` -#### Example: -```cpp -int day = 3; -switch (day) { - case 1: - std::cout << "Monday" << std::endl; - break; - case 2: - std::cout << "Tuesday" << std::endl; - break; - case 3: - std::cout << "Wednesday" << std::endl; - break; - default: - std::cout << "Not a valid day" << std::endl; -} - -``` - -## 5. Nested `if` Statements -#### Example: -```cpp -int num = 15; -if (num > 10) { - std::cout << "The number is greater than 10." << std::endl; - if (num > 20) { - std::cout << "The number is also greater than 20." << std::endl; - } -} -``` - -## 6. Conditional Operators -C++ also supports conditional operators for compact decision-making. - -#### Ternary Operator -```cpp -(condition) ? expression1 : expression2; - -``` - -#### Example: -```cpp -int num = 10; -std::string result = (num > 0) ? "Positive" : "Non-positive"; -std::cout << result << std::endl; - -``` - ---- - -Understanding Control Statements structures in C++ is crucial for controlling the flow of your program and executing different actions based on conditions. Happy coding! \ No newline at end of file diff --git a/docs/languages/cpp/cp-4.md b/docs/languages/cpp/cp-4.md deleted file mode 100644 index 74e332d8c..000000000 --- a/docs/languages/cpp/cp-4.md +++ /dev/null @@ -1,228 +0,0 @@ ---- -id: loops-in-cpp -sidebar_position: 4 -title: "Loops In C++" -sidebar_label: "Loops In C++" ---- - -Hey there! In this guide, we'll explore loops in C++. Loops are used to execute a block of code repeatedly based on specific conditions. Let's dive in! - -- C++ provides several types of loops that allow you to execute a block of code multiple times based on specific conditions. -- The main types of loops in C++ are `for`, `while`, and `do-while`. - -## 1. For Loop - -The for loop is used when you know how many times you want to execute a statement or a block of statements. - -#### Syntax: - -```cpp -for(initialization; condition; increment/decrement) { - // code to be executed -} -``` - -#### Example: - -```cpp -#include -using namespace std; - -int main() { - for (int i = 0; i < 5; i++) { - cout << "Iteration " << i << endl; - } - return 0; -} -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -## 2. While Loop - -The `while` loop is used when you want to execute a block of code as long as a specified condition is true. - -#### Syntax: - -```cpp -while(condition) { - // code to be executed -} - -``` - -#### Example: - -```cpp -i#include -using namespace std; - -int main() { - int i = 0; - while (i < 5) { - cout << "Iteration " << i << endl; - i++; - } - return 0; -} -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -## 3. Do-While Loop - -The `do-while` loop is similar to the `while` loop, except that it guarantees that the code block will be executed at least once before the condition is tested. - -#### Syntax: - -```cpp -do { - // code to be executed -} while(condition); -``` - -#### Example: - -```cpp -#include -using namespace std; - -int main() { - int i = 0; - do { - cout << "Iteration " << i << endl; - i++; - } while (i < 5); - return 0; -} -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -## 4. Nested Loops - -You can also use loops inside other loops, which are called nested loops. - -#### Example: - -```cpp -#include -using namespace std; - -int main() { - for (int i = 1; i <= 3; i++) { - for (int j = 1; j <= 2; j++) { - cout << "Outer Loop: " << i << ", Inner Loop: " << j << endl; - } - } - return 0; -} -``` - -``` -Outer Loop: 1, Inner Loop: 1 -Outer Loop: 1, Inner Loop: 2 -Outer Loop: 2, Inner Loop: 1 -Outer Loop: 2, Inner Loop: 2 -Outer Loop: 3, Inner Loop: 1 -Outer Loop: 3, Inner Loop: 2 - -``` - -## 5. Break and Continue Statements - -### a. Break Statement - -The `break` statement is used to exit a loop prematurely. - -#### Example: - -```cpp -#include -using namespace std; - -int main() { - for (int i = 0; i < 10; i++) { - if (i == 5) { - break; // Exit the loop when i equals 5 - } - cout << "Iteration " << i << endl; - } - return 0; -} -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -### b. Break Statement - -The `continue` statement skips the current iteration and proceeds to the next one. - -#### Example: - -```cpp -#include -using namespace std; - -int main() { - for (int i = 0; i < 5; i++) { - if (i == 2) { - continue; // Skip the iteration when i equals 2 - } - cout << "Iteration " << i << endl; - } - return 0; -} - -``` - -#### Output: - -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - ---- - -Loops are essential for controlling the flow of execution in your C++ programs, enabling you to perform repetitive tasks efficiently. Understanding how to use them effectively will greatly enhance your programming skills! diff --git a/docs/languages/cpp/cp-5.md b/docs/languages/cpp/cp-5.md deleted file mode 100644 index 0aeded123..000000000 --- a/docs/languages/cpp/cp-5.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -id: functions-in-cpp -sidebar_position: 5 -title: "Functions In C++" -sidebar_label: "Functions In C++" ---- - -Hey there! In this guide, we'll explore functions in C++. Functions are used to perform certain actions, and they are important for reusing code: Define the code once, and use it many times. Let's dive in! - -* C++ provides the `class` keyword to define a class. -* A class can have private and public members, including data (variables) and functions (methods). - -## 1. Declaring a Function : - -C++ provides some pre-defined functions, such as main(), which is used to execute code. But you can also create your own functions to perform certain actions. - -A C++ function consist of two parts: - -* `Declaration`: the return type, the name of the function, and parameters (if any) -* `Definition`: the body of the function (code to be executed) - -To create (often referred to as declare) a function, specify the name of the function, -followed by parentheses `()`: - -#### Syntax: -```cpp -//declare function -void myFunction() { - // code to be executed -}; -``` - -* myFunction() is the name of the function. -* void means that the function does not have a return value. - -#### Example: -```cpp -// C++ Program to demonstrate working of a function -#include -using namespace std; - -// Following function that takes two parameters 'x' and 'y' -// as input and returns max of two input numbers -int max(int x, int y) -{ - if (x > y) - return x; - else - return y; -} - -// main function that doesn't receive any parameter and -// returns integer -int main() -{ - int a = 10, b = 20; - - // Calling above function to find max of 'a' and 'b' - int m = max(a, b); - - cout << "m is " << m; - return 0; -} -``` - -#### Output: -``` -m is 20 -``` - -* A function declaration tells the compiler about the number of parameters, data types of parameters, and returns type of function. - -# 2. Types of Functions - - -## User-Defined Functions: - -* ### Customization: - These are tailor-made functions created by the user to solve specific problems, reducing complexity in large programs. -* ### Declaration and Definition Required: - User-defined functions must be declared and defined before they can be used in a program. -* ### Flexibility: - Users have full control over the logic, parameters, and functionality of these functions, making them versatile for unique scenarios. - -## Library Functions: - -* ### Pre Defined: - Library functions are built-in and part of the compiler package, meaning they can be used directly without defining them. -* ### Specialized Functions: - These functions perform common, specialized tasks like mathematical operations (e.g., sqrt() ) and string handling (strcat()). -* ### Ease of Use: - They save time and effort, as they come pre-written and require no additional code for their functionality. - -## 3. Parameter Passing to Functions - - * #### The parameters passed to the function are called `actual parameters`. - * #### The parameters received by the function are called `formal parameters`. - - -#### Example: -```cpp -#include -using namespace std; - -// Function definition with formal parameters -void add(int x, int y) { // 'x' and 'y' are formal parameters - int sum = x + y; - cout << "Sum inside the function (using formal parameters): " << sum << endl; -} - -int main() { - int a = 5, b = 10; - - // Function call with actual parameters - add(a, b); // 'a' and 'b' are actual parameters - - cout << "Actual parameters in main function: a = " << a << ", b = " << b << endl; - return 0; -} -``` -#### There are two most popular ways to pass parameters: - -### 1.Pass by Value: -In this parameter passing method, values of actual parameters are copied to the function’s formal parameters. The actual and formal parameters are stored in different memory locations so any changes made in the functions are not reflected in the actual parameters of the caller. - -#### Example: -```cpp -#include -using namespace std; - -void increment(int num) { - num++; // Only affects the local copy - cout << "Inside function: " << num << endl; -} - -int main() { - int value = 5; - increment(value); - cout << "After function call: " << value << endl; // Original value remains unchanged - return 0; -} -``` - -#### Output: -``` -Inside function: 6 -After function call: 5 -``` - -### 2.Pass by Refrence: -Both actual and formal parameters refer to the same locations, so any changes made inside the function are reflected in the actual parameters of the caller. - -#### Example: -```cpp -#include -using namespace std; - -void increment(int &num) { - num++; // Affects the original variable -} - -int main() { - int value = 5; - increment(value); - cout << "After function call: " << value << endl; // Original value is changed - return 0; -} - -``` - -#### Output: -``` -After function call: 6 -``` - -## Points to Remember About Functions in C++ : - 1. Most C++ program has a function called `main()` that is called by the operating system when a user runs the program. - - 2. Every function has a return type. If a function doesn’t return any value, then `void` is used as a return type. Moreover, if the return type of the function is void, we still can use the return statement in the body of the function definition by not specifying any constant, variable, etc. with it, by only mentioning the ` ‘return;’ ` statement which would symbolize the termination of the function. - diff --git a/docs/languages/cpp/cp-6.md b/docs/languages/cpp/cp-6.md deleted file mode 100644 index 5b30dff7b..000000000 --- a/docs/languages/cpp/cp-6.md +++ /dev/null @@ -1,336 +0,0 @@ ---- -id: strings-in-cpp -sidebar_position: 6 -title: "Strings In C++" -sidebar_label: "Strings In C++" ---- - -# Strings in C++ - -Hey there! In this guide, we'll explore how to work with strings in C++. Strings are used to store sequences of characters and are a vital part of any C++ program. Let's dive in! - ---- - -## 1. C-Style Strings - -C++ inherits its basic string handling capabilities from C, known as C-style strings. These are arrays of characters terminated by a null character (`\0`). - -#### Example: -```cpp -#include -using namespace std; - -int main() { - char greeting[] = "Hello"; - cout << greeting << endl; - return 0; -} -``` - -#### Output: -``` -Hello -``` - ---- - -## 2. C++ String Class - -C++ provides a more convenient way to handle strings through the `std::string` class, which is part of the C++ Standard Library. - -#### Example: -```cpp -#include -#include // Required for string -using namespace std; - -int main() { - string greeting = "Hello, World!"; - cout << greeting << endl; - return 0; -} -``` - -#### Output: -``` -Hello, World! -``` - ---- - -## 3. Common String Operations - -### 3.1 String Length - -You can use the `.length()` or `.size()` method to get the length of a string. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string greeting = "Hello, World!"; - cout << "Length: " << greeting.length() << endl; - return 0; -} -``` - -#### Output: -``` -Length: 13 -``` - ---- - -### 3.2 String Concatenation - -You can concatenate two strings using the `+` operator or the `.append()` method. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string firstName = "John"; - string lastName = "Doe"; - string fullName = firstName + " " + lastName; - cout << fullName << endl; - return 0; -} -``` - -#### Output: -``` -John Doe -``` - ---- - -### 3.3 Accessing Characters in a String - -You can access individual characters in a string using array-like indexing. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string greeting = "Hello"; - cout << greeting[0] << endl; // Output: H - return 0; -} -``` - -#### Output: -``` -H -``` - ---- - -## 4. Modifying Strings - -### 4.1 Changing Characters - -You can modify individual characters in a string using array-like indexing. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string greeting = "Hello"; - greeting[0] = 'J'; - cout << greeting << endl; // Output: Jello - return 0; -} -``` - -#### Output: -``` -Jello -``` - ---- - -### 4.2 Substrings - -You can extract a substring from a string using the `.substr()` method. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string greeting = "Hello, World!"; - string sub = greeting.substr(0, 5); // Extracts "Hello" - cout << sub << endl; - return 0; -} -``` - -#### Output: -``` -Hello -``` - ---- - -### 4.3 String Comparison - -You can compare two strings using the comparison operators (`==`, `!=`, `>`, `<`, etc.) or the `.compare()` method. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string str1 = "Hello"; - string str2 = "World"; - - if (str1 == str2) { - cout << "Strings are equal" << endl; - } else { - cout << "Strings are not equal" << endl; - } - - return 0; -} -``` - -#### Output: -``` -Strings are not equal -``` - ---- - -## 5. String Input - -You can input strings from the user using `cin` and `getline()`. - -### 5.1 Using `cin` - -`cin` stops reading input at the first space. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string name; - cout << "Enter your name: "; - cin >> name; - cout << "Hello, " << name << endl; - return 0; -} -``` - -#### Output: -``` -Enter your name: John -Hello, John -``` - -### 5.2 Using `getline()` - -`getline()` reads the entire line, including spaces. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string name; - cout << "Enter your full name: "; - getline(cin, name); - cout << "Hello, " << name << endl; - return 0; -} -``` - -#### Output: -``` -Enter your full name: John Doe -Hello, John Doe -``` - ---- - -## 6. String Functions - -C++ provides several functions to manipulate strings. Some of the most common ones are: - -### 6.1 `find()` - -Finds the first occurrence of a substring. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string str = "Hello, World!"; - size_t pos = str.find("World"); - - if (pos != string::npos) { - cout << "Found at position: " << pos << endl; - } else { - cout << "Not found!" << endl; - } - - return 0; -} -``` - -#### Output: -``` -Found at position: 7 -``` - ---- - -### 6.2 `replace()` - -Replaces part of the string with another string. - -#### Example: -```cpp -#include -#include -using namespace std; - -int main() { - string str = "Hello, World!"; - str.replace(7, 5, "Universe"); - cout << str << endl; - return 0; -} -``` - -#### Output: -``` -Hello, Universe! -``` - ---- - -Strings are an essential part of C++ programming, and mastering them will greatly improve your ability to handle text and input in your programs. Happy coding! diff --git a/docs/languages/cpp/cp-7.md b/docs/languages/cpp/cp-7.md deleted file mode 100644 index fb0292dc2..000000000 --- a/docs/languages/cpp/cp-7.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -id: arrays-in-cpp -sidebar_position: 7 -title: "Arrays in C++" -sidebar_label: "Arrays in C++" ---- - -In this guide, we'll discuss arrays in C++. Arrays are a fundamental data structure that store multiple elements of the same type in a contiguous block of memory. - - - -## 1. What is an Array? - -An array is a collection of elements of the same data type, stored in contiguous memory locations. Each element is accessed by its index, starting from 0. - -## 2. Declaring an Array - -An array can be declared by specifying the data type of its elements, followed by the array name and the number of elements in square brackets. - -**Syntax:** - -```cpp -type arrayName[arraySize]; -``` - -**Example:** - -```cpp -int numbers[5]; // Declares an array of 5 integers -``` - - - -## 3. Initializing an Array - -You can initialize an array at the time of declaration by providing values in curly braces. - -**Example:** - -```cpp -int numbers[5] = {1, 2, 3, 4, 5}; // Initializes an array with 5 elements -``` - -If you don't specify all the elements, the remaining ones are set to 0 by default. - -**Example:** - -```cpp -int numbers[5] = {1, 2}; // Remaining elements are set to 0 -``` - -## 4. Accessing Array Elements - -You can access individual elements of an array using the array name followed by the index in square brackets. - -**Example:** - -```cpp -#include -using namespace std; - -int main() { - int numbers[5] = {1, 2, 3, 4, 5}; - cout << "The first element is: " << numbers[0] << endl; - return 0; -} -``` - -**Output:** - -``` -The first element is: 1 -``` - - - -## 5. Array in Loops - -You can use loops to iterate over an array and access each element. - -**Example:** - -```cpp -#include -using namespace std; - -int main() { - int numbers[5] = {1, 2, 3, 4, 5}; - for (int i = 0; i < 5; i++) { - cout << "Element " << i << " is: " << numbers[i] << endl; - } - return 0; -} -``` - -**Output:** - -``` -Element 0 is: 1 -Element 1 is: 2 -Element 2 is: 3 -Element 3 is: 4 -Element 4 is: 5 -``` - - - -## 6. Multi-dimensional Arrays - -C++ allows you to create arrays with more than one dimension. A two-dimensional array, for instance, can be used to represent a matrix. - -**Example:** - -```cpp -#include -using namespace std; - -int main() { - int matrix[2][3] = { - {1, 2, 3}, - {4, 5, 6} - }; - - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 3; j++) { - cout << matrix[i][j] << " "; - } - cout << endl; - } - return 0; -} -``` - -**Output:** - -``` -1 2 3 -4 5 6 -``` - - - -## 7. Array of Strings - -You can create an array of strings by declaring a two-dimensional array of characters. - -**Example:** - -```cpp -#include -using namespace std; - -int main() { - const char* fruits[3] = {"Apple", "Banana", "Cherry"}; - - for (int i = 0; i < 3; i++) { - cout << fruits[i] << endl; - } - - return 0; -} -``` - -**Output:** - -``` -Apple -Banana -Cherry -``` - - - -## 8. Array Limitations - -While arrays in C++ are useful, they have some limitations: - -- The size of an array is fixed at the time of declaration and cannot be changed during runtime. -- Arrays do not provide bounds checking, meaning accessing an index out of range may result in undefined behaviour. -- No built-in support for dynamic resizing or higher-level operations such as sorting and searching. - -For more advanced functionality, C++ provides other data structures like vectors (from the STL) that address many of these limitations. - - - -## Final Thoughts - -Arrays are an essential part of C++ programming, especially when dealing with fixed-size collections of elements. However, for dynamic and resizable collections, it's better to use other data structures like vectors. diff --git a/docs/languages/cpp/cp-8.md b/docs/languages/cpp/cp-8.md deleted file mode 100644 index e7bb81ba2..000000000 --- a/docs/languages/cpp/cp-8.md +++ /dev/null @@ -1,446 +0,0 @@ ---- -id: classes-in-cpp -sidebar_position: 8 -title: "Classes In C++" -sidebar_label: "Classes In C++" ---- - -Hey there! In this guide, we'll explore classes in C++. Classes are the foundation of Object-Oriented Programming (OOP) and help to encapsulate data and functions into a single entity. Let's dive in! - -* C++ provides the `class` keyword to define a class. -* A class can have private and public members, including data (variables) and functions (methods). - -## 1. Defining a Class - -A class in C++ is a blueprint for creating objects. It defines data members and member functions that operate on the data. - -#### Syntax: -```cpp -class ClassName { - public: - // Public members - int dataMember; - void memberFunction(); - - private: - // Private members - int privateData; -}; -``` - -#### Example: -```cpp -#include -using namespace std; - -class Car { - public: - string brand; - int year; - - void displayDetails() { - cout << "Brand: " << brand << ", Year: " << year << endl; - } -}; - -int main() { - Car car1; - car1.brand = "Toyota"; - car1.year = 2020; - car1.displayDetails(); - return 0; -} -``` - -#### Output: -``` -Brand: Toyota, Year: 2020 -``` - -## 2. Access Modifiers - -C++ provides three access modifiers: `public`, `private`, and `protected`. They determine how members of the class can be accessed. - -- `public`: Members are accessible from outside the class. -- `private`: Members are only accessible within the class. -- `protected`: Members are accessible in the class and derived classes. - -#### Example: -```cpp -#include -using namespace std; - -class Person { - private: - int age; - - public: - string name; - - void setAge(int a) { - age = a; - } - - int getAge() { - return age; - } -}; - -int main() { - Person p; - p.name = "John"; - p.setAge(25); - cout << p.name << " is " << p.getAge() << " years old." << endl; - return 0; -} -``` - -#### Output: -``` -John is 25 years old. -``` - -## 3. Constructors - -A constructor is a special function that is automatically called when an object of a class is created. Constructors are used to initialize the object’s data. - -#### Syntax: -```cpp -class ClassName { - public: - ClassName() { - // Constructor code - } -}; -``` - -#### Example: -```cpp -#include -using namespace std; - -class Car { - public: - string brand; - int year; - - // Constructor - Car(string b, int y) { - brand = b; - year = y; - } - - void displayDetails() { - cout << "Brand: " << brand << ", Year: " << year << endl; - } -}; - -int main() { - Car car1("Honda", 2018); - car1.displayDetails(); - return 0; -} -``` - -#### Output: -``` -Brand: Honda, Year: 2018 -``` - -## 4. Destructors - -A destructor is called automatically when an object is destroyed. It is used to clean up resources allocated to an object. - -#### Syntax: -```cpp -class ClassName { - public: - ~ClassName() { - // Destructor code - } -}; -``` - -#### Example: -```cpp -#include -using namespace std; - -class Car { - public: - Car() { - cout << "Car object created!" << endl; - } - - ~Car() { - cout << "Car object destroyed!" << endl; - } -}; - -int main() { - Car car1; - return 0; -} -``` - -#### Output: -``` -Car object created! -Car object destroyed! -``` - -## 5. Inheritance - -Inheritance allows a class (derived class) to inherit properties and behaviors (members) from another class (base class). - -#### Syntax: -```cpp -class DerivedClass : accessSpecifier BaseClass { - // Derived class members -}; -``` - -#### Example: -```cpp -#include -using namespace std; - -class Animal { - public: - void sound() { - cout << "Animal makes a sound." << endl; - } -}; - -class Dog : public Animal { - public: - void bark() { - cout << "Dog barks." << endl; - } -}; - -int main() { - Dog dog1; - dog1.sound(); - dog1.bark(); - return 0; -} -``` - -#### Output: -``` -Animal makes a sound. -Dog barks. -``` - -## 6. Polymorphism - -Polymorphism allows one function to behave differently based on the object that is invoking it. C++ supports two types of polymorphism: -- **Compile-time polymorphism** (Function overloading, Operator overloading) -- **Run-time polymorphism** (Function overriding with virtual functions) - -### a. Function Overloading - -Function overloading allows multiple functions with the same name but different parameters. - -#### Example: -```cpp -#include -using namespace std; - -class Math { - public: - int add(int a, int b) { - return a + b; - } - - double add(double a, double b) { - return a + b; - } -}; - -int main() { - Math m; - cout << m.add(5, 3) << endl; // Outputs 8 - cout << m.add(5.5, 3.3) << endl; // Outputs 8.8 - return 0; -} -``` - -#### Output: -``` -8 -8.8 -``` - -### b. Function Overriding with Virtual Functions - -Virtual functions are used to achieve run-time polymorphism by overriding a base class function in a derived class. - -#### Example: -```cpp -#include -using namespace std; - -class Animal { - public: - virtual void sound() { - cout << "Animal sound" << endl; - } -}; - -class Dog : public Animal { - public: - void sound() override { - cout << "Dog barks" << endl; - } -}; - -int main() { - Animal *animalPtr; - Dog dog1; - - animalPtr = &dog1; - animalPtr->sound(); // Outputs "Dog barks" due to function overriding - return 0; -} -``` - -#### Output: -``` -Dog barks -``` - ---- - -Classes are a core feature of C++'s object-oriented capabilities, allowing for better code organization, reuse, and encapsulation. Mastering them will enhance your understanding of OOP in C++. -id: functions-in-cpp -sidebar_position: 6 -title: "Functions in C++" -sidebar_label: "Functions in C++" ---- - - -## Introduction to Functions in C++ - -Functions are a fundamental building block in C++ programming. They allow you to encapsulate code for reuse, improve modularity, and enhance readability. In this guide, we will cover the types of functions, how to declare and define them, and their various components. - -## 1. What is a Function? - -A function is a self-contained block of code designed to perform a specific task. Functions can take inputs (arguments), perform operations, and return results. - -### Benefits of Using Functions - -- **Reusability**: Code can be reused multiple times without rewriting it. -- **Modularity**: Functions help break down complex problems into smaller, manageable parts. -- **Readability**: Well-named functions make the code easier to understand. - -## 2. Function Declaration and Definition - -### a. Function Declaration - -A function declaration (or prototype) tells the compiler about the function's name, return type, and parameters. It is typically placed before the `main()` function. - -```cpp -return_type function_name(parameter_type1 parameter_name1, parameter_type2 parameter_name2); - -//Example: -int add(int a, int b); // Declaration of a function named add -``` - -b. Function Definition -The function definition contains the actual code that performs the task. - -```cpp -return_type function_name(parameter_type1 parameter_name1, parameter_type2 parameter_name2) { - // Function body -} - -``` -## 3. Calling a Function -To execute a function, you simply call it by its name and pass the required arguments. - -```cpp -int result = add(5, 3); // Calling the add function with arguments 5 and 3 -``` -## 4. Types of Functions -a. Standard Functions -These are functions that return a value and can take parameters. - -Example: -```cpp -double multiply(double x, double y) { - return x * y; -} - -``` -b. Void Functions -Void functions do not return a value. They perform an action but do not provide feedback to the caller. - -Example: - - -```cpp -void printMessage() { - std::cout << "Hello, World!" << std::endl; -} -``` - -c. Inline Functions -Inline functions are defined with the inline keyword and suggest to the compiler to insert the function's code directly at the point of call. This can improve performance for small, frequently called functions. - -Example: - -```cpp -inline int square(int x) { - return x * x; -} -``` -## 5. Function Overloading -C++ allows you to define multiple functions with the same name but different parameter types or numbers. This is called function overloading. - -Example: - -```cpp - - -int add(int a, int b) { - return a + b; -} - - -double add(double a, double b) { - return a + b; -} -``` -## 6. Default Arguments -You can specify default values for function parameters. If the caller does not provide an argument for that parameter, the default value is used. - -Example: - -```cpp -void display(int a, int b = 10) { - std::cout << "a: " << a << ", b: " << b << std::endl; -} - -// Calling with both arguments -display(5, 15); // Outputs: a: 5, b: 15 - -// Calling with one argument -display(5); // Outputs: a: 5, b: 10 (default value used) -``` -## 7. Recursion -A function can call itself, which is known as recursion. It is essential to have a base condition to prevent infinite recursion. - -Example: - -```cpp -int factorial(int n) { - if (n <= 1) return 1; // Base condition - return n * factorial(n - 1); // Recursive call -} -``` - -## 8. Conclusion -Functions are essential in C++ for creating organized, reusable, and modular code. By mastering the different types of functions, their syntax, and usage, you can write more efficient and maintainable programs. Keep practicing with functions to become proficient in C++ programming! - diff --git a/docs/languages/cpp/cp-9.md b/docs/languages/cpp/cp-9.md deleted file mode 100644 index b60214c67..000000000 --- a/docs/languages/cpp/cp-9.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -id: pointers-in-cpp -sidebar_position: 9 -title: "Pointers in C++" -sidebar_label: "Pointers in C++" ---- - -# Pointers in C++ - -In this guide, we'll explore pointers in C++, a powerful feature that allows you to directly manage memory and perform low-level programming tasks. - ---- - -## 1. What is a Pointer? - -A pointer is a variable that stores the memory address of another variable. Pointers are extremely useful for dynamic memory management, passing large data structures to functions, and more. - ---- - -## 2. Declaring a Pointer - -To declare a pointer, specify the data type of the variable it will point to, followed by an asterisk `*`. - -#### Syntax: - -```cpp -type* pointerName; -``` - -#### Example: - -```cpp -int* ptr; // Declares a pointer to an integer -``` - ---- - -## 3. Address-of Operator (`&`) - -The address-of operator `&` is used to get the memory address of a variable. - -#### Example: - -```cpp -int num = 5; -int* ptr = # // ptr now holds the address of num -``` - ---- - -## 4. Dereferencing a Pointer (`*`) - -Dereferencing a pointer means accessing the value stored at the memory address the pointer is holding. - -#### Example: - -```cpp -#include -using namespace std; - -int main() { - int num = 10; - int* ptr = # // Pointer holds the address of num - - cout << "Value of num: " << *ptr << endl; // Dereference the pointer to get the value of num - return 0; -} -``` - -#### Output: - -``` -Value of num: 10 -``` - ---- - -## 5. Null Pointers - -A pointer that is not assigned a valid memory address is called a null pointer. It is a good practice to initialize pointers to `nullptr` to avoid unexpected behavior. - -#### Example: - -```cpp -int* ptr = nullptr; // Pointer is initialized to null -``` - ---- - -## 6. Pointers and Arrays - -Pointers can be used to iterate over arrays. The name of an array acts as a pointer to its first element. - -#### Example: - -```cpp -#include -using namespace std; - -int main() { - int arr[3] = {1, 2, 3}; - int* ptr = arr; // Pointer points to the first element of the array - - for (int i = 0; i < 3; i++) { - cout << *(ptr + i) << endl; // Dereferencing to get array elements - } - return 0; -} -``` - -#### Output: - -``` -1 -2 -3 -``` - ---- - -## 7. Pointer Arithmetic - -You can perform arithmetic operations on pointers like incrementing or decrementing them. When you increment a pointer, it moves to the next memory location based on the data type it points to. - -#### Example: - -```cpp -#include -using namespace std; - -int numbers[3] = {10, 20, 30}; -int* ptr = numbers; - -cout << "First element: " << *ptr << endl; -ptr++; -cout << "Second element: " << *ptr << endl; -``` - -#### Output: - -``` -First element: 10 -Second element: 20 -``` - ---- - -## 8. Pointers to Pointers - -A pointer can also point to another pointer, creating a chain of pointers. - -#### Example: - -```cpp -#include -using namespace std; - -int num = 10; -int* ptr = # -int** ptr2 = &ptr; // Pointer to a pointer - -cout << "Value of num: " << **ptr2 << endl; // Dereferencing twice to get the value -``` - -#### Output: - -``` -Value of num: 10 -``` - ---- - -## 9. Dynamic Memory Allocation - -Pointers are often used with dynamic memory allocation using the `new` and `delete` operators. - -#### Example: - -```cpp -#include -using namespace std; - -int* ptr = new int; // Allocates memory dynamically -*ptr = 100; // Assign value to the dynamically allocated memory - -cout << "Value: " << *ptr << endl; - -delete ptr; // Free the dynamically allocated memory -``` - -#### Output: - -``` -Value: 100 -``` - ---- - -## 10. Common Pointer Errors - -1. **Dangling Pointer**: Occurs when a pointer points to memory that has already been deallocated. -2. **Memory Leak**: Happens when dynamically allocated memory is not properly freed. -3. **Wild Pointer**: A pointer that is not initialized to any valid memory address. - -Always ensure proper memory management and pointer initialization to avoid these issues. - ---- - -## Final Thoughts - -Pointers are a powerful tool in C++ that allow for efficient memory management and manipulation. However, they require careful handling to avoid common pitfalls such as memory leaks and dangling pointers. - -Happy coding! diff --git a/docs/languages/csharp/_category_.json b/docs/languages/csharp/_category_.json deleted file mode 100644 index 1557350d7..000000000 --- a/docs/languages/csharp/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "C#", - "position": 4, - "link": { - "type": "generated-index", - "description": "C# is a modern, high-level programming language developed by Microsoft as part of the .NET framework. First released in 2002, C# is known for its strong typing, garbage collection, and support for object-oriented programming, making it popular for a variety of applications including web, desktop, and mobile development. With cross-platform support through .NET Core, C# allows developers to create versatile and performant software solutions across different environments." - } -} diff --git a/docs/languages/csharp/csharp-0.md b/docs/languages/csharp/csharp-0.md deleted file mode 100644 index d3a745789..000000000 --- a/docs/languages/csharp/csharp-0.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: introduction-to-csharp -sidebar_position: 1 -title: "Introduction to C#" -sidebar_label: "Introduction to C#" ---- - -Welcome to the world of C#! In this guide, we'll explore the essentials of C#, a modern programming language that is widely used in software development, especially for Windows applications, game development, and enterprise solutions. Whether you're interested in building desktop applications, web applications, or games, learning C# will provide you with powerful, versatile skills. Let’s get started! - -## 1. What is C#? - -C# is a modern, object-oriented programming language developed by Microsoft as part of the .NET framework in the early 2000s. It is known for its simplicity, robustness, and flexibility, making it an excellent choice for various applications, from enterprise software to game development with Unity. - -## 2. Key Features of C# - -- **Object-Oriented Programming (OOP):** C# follows an OOP approach, emphasizing concepts such as classes, objects, inheritance, and polymorphism. -- **Garbage Collection:** C# has built-in memory management, reducing memory leaks and improving application stability. -- **Type Safety:** C# enforces strong typing, minimizing errors due to type mismatches. -- **Cross-Platform Development:** With .NET Core, C# applications can run on Windows, macOS, and Linux. -- **Rich Standard Library:** C# offers a vast library with functionality for file handling, networking, database access, and more. - -## 3. Setting Up C# - -To start programming in C#, you'll need to set up a development environment. Here are some common options: - -- **Integrated Development Environments (IDEs):** - - - **Visual Studio**: A comprehensive IDE with powerful tools for C# development, especially on Windows. - - **Visual Studio Code**: A lightweight editor that can support C# with the right extensions, available on Windows, macOS, and Linux. - - **Rider (by JetBrains)**: A cross-platform C# IDE with powerful features, especially popular among developers using multiple languages. - -- **Frameworks and SDKs:** - - **.NET SDK**: Required for building and running C# applications; you can download the latest version from the .NET website. - -## 4. Writing Your First C# Program - -Here’s a simple "Hello, World!" program in C# to get you started: - -```csharp -using System; // Import the System namespace - -class Program { - static void Main() { - Console.WriteLine("Hello, World!"); // Print "Hello, World!" to the console - } -} -``` - -Explanation: - -- `using System;`: Imports the System namespace, which includes commonly used classes such as Console. -- `class Program`: Defines a class named `Program`. -- `static void Main()`: Defines the `Main` method, the entry point of the application. -- `Console.WriteLine("Hello, World!");`: Prints "Hello, World!" to the console. - -## 5. Basic Syntax - -Comments: Use `//` for single-line comments and `/* */` for multi-line comments. - -```csharp -// This is a single-line comment -/* This is a - multi-line comment */ -``` - -Semicolons: Each statement in C# ends with a semicolon (`;`). - -Braces: Curly braces (`{}`) are used to define the beginning and end of code blocks. - -## 6. Conclusion - -C# is a versatile and modern programming language with a broad range of applications. Its combination of object-oriented principles and modern features makes it ideal for developing applications that are maintainable and scalable. Mastering C# will provide you with a strong foundation in both object-oriented programming and modern software development practices. diff --git a/docs/languages/csharp/csharp-1.md b/docs/languages/csharp/csharp-1.md deleted file mode 100644 index a8d9f05d0..000000000 --- a/docs/languages/csharp/csharp-1.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -id: variables-in-csharp -sidebar_position: 2 -title: "Variables in C#" -sidebar_label: "Variables in C#" ---- - -In C#, variables are used to store data that can be referenced and manipulated within a program. Understanding how to declare and use variables is fundamental to programming in C#. This guide covers the basics of variables, including types, naming conventions, and examples. - -## 1. What is a Variable? - -A variable is a named memory location used to store a value. In C#, variables have a specific type, which determines what kind of data they can hold, such as integers, floating-point numbers, or strings. - -## 2. Declaring Variables in C# - -To declare a variable in C#, you need to specify the data type followed by the variable name. Here’s the basic syntax: - -```csharp -dataType variableName = initialValue; -``` - -### Example: - -```csharp -int age = 25; // Declares an integer variable named 'age' and assigns it the value 25 -string name = "Alice"; // Declares a string variable named 'name' and assigns it "Alice" -``` - -## 3. Data Types in C# - -C# provides various data types that determine the kind of values variables can store. Here are some commonly used data types: - -- **int**: Stores whole numbers (e.g., `int count = 10;`) -- **float**: Stores single-precision floating-point numbers (e.g., `float temperature = 23.5f;`) -- **double**: Stores double-precision floating-point numbers (e.g., `double distance = 123.45;`) -- **char**: Stores a single character (e.g., `char grade = 'A';`) -- **string**: Stores a sequence of characters (e.g., `string message = "Hello";`) -- **bool**: Stores true or false values (e.g., `bool isActive = true;`) - -## 4. Naming Conventions - -In C#, variable names should be meaningful, describing the purpose of the variable. Here are some naming conventions: - -- **Camel Case**: Commonly used for local variables (e.g., `userName`, `totalScore`). -- **Avoid Reserved Keywords**: Variable names cannot be C# reserved keywords like `class`, `void`, or `int`. -- **No Special Characters**: Variable names cannot contain special characters except underscores (_). - -## 5. Example of Using Variables in C# - -Here’s a sample code that demonstrates declaring and using different types of variables: - -```csharp -using System; - -class Program { - static void Main() { - int age = 30; - string name = "John"; - bool isStudent = true; - double height = 5.9; - - Console.WriteLine("Name: " + name); - Console.WriteLine("Age: " + age); - Console.WriteLine("Is Student: " + isStudent); - Console.WriteLine("Height: " + height); - } -} -``` - -### Explanation - -- `int age = 30;`: Declares an integer variable named `age` with the value 30. -- `string name = "John";`: Declares a string variable `name` with the value "John". -- `bool isStudent = true;`: Declares a boolean variable `isStudent` with the value `true`. -- `double height = 5.9;`: Declares a double variable `height` with the value 5.9. - -## 6. Conclusion - -Understanding variables and data types is crucial for effective programming in C#. By learning to declare and use variables properly, you can control data in your applications and perform various operations on it. - ---- diff --git a/docs/languages/csharp/csharp-2.md b/docs/languages/csharp/csharp-2.md deleted file mode 100644 index a11c105d8..000000000 --- a/docs/languages/csharp/csharp-2.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -id: operators-in-csharp -sidebar_position: 3 -title: "Operators in C#" -sidebar_label: "Operators in C#" ---- - -Operators in C# allow you to perform various operations on variables and values, such as arithmetic, comparison, logical, and more. This guide introduces the different types of operators available in C# and provides examples to help you understand how to use them. - -## 1. Types of Operators in C# - -C# supports various operators, which can be broadly categorized as follows: - -- **Arithmetic Operators** -- **Comparison Operators** -- **Logical Operators** -- **Assignment Operators** -- **Unary Operators** -- **Ternary Operator** - -## 2. Arithmetic Operators - -Arithmetic operators are used to perform basic mathematical operations. - -| Operator | Description | Example | -|----------|-----------------------|----------------| -| `+` | Addition | `x + y` | -| `-` | Subtraction | `x - y` | -| `*` | Multiplication | `x * y` | -| `/` | Division | `x / y` | -| `%` | Modulus (Remainder) | `x % y` | - -### Example: - -```csharp -int a = 10, b = 5; -Console.WriteLine(a + b); // Output: 15 -Console.WriteLine(a - b); // Output: 5 -Console.WriteLine(a * b); // Output: 50 -Console.WriteLine(a / b); // Output: 2 -Console.WriteLine(a % b); // Output: 0 -``` - -## 3. Comparison Operators - -Comparison operators are used to compare two values. - -| Operator | Description | Example | -|----------|----------------------|---------------| -| `==` | Equal to | `x == y` | -| `!=` | Not equal to | `x != y` | -| `>` | Greater than | `x > y` | -| `<` | Less than | `x < y` | -| `>=` | Greater than or equal| `x >= y` | -| `<=` | Less than or equal | `x <= y` | - -### Example: - -```csharp -int x = 10, y = 20; -Console.WriteLine(x == y); // Output: False -Console.WriteLine(x != y); // Output: True -Console.WriteLine(x > y); // Output: False -Console.WriteLine(x < y); // Output: True -``` - -## 4. Logical Operators - -Logical operators are used to combine multiple conditions. - -| Operator | Description | Example | -|----------|-----------------------|------------------| -| `&&` | Logical AND | `x && y` | -| `||` | Logical OR | `x || y` | -| `!` | Logical NOT | `!x` | - -### Example: - -```csharp -bool isAdult = true, hasID = false; -Console.WriteLine(isAdult && hasID); // Output: False -Console.WriteLine(isAdult || hasID); // Output: True -Console.WriteLine(!isAdult); // Output: False -``` - -## 5. Assignment Operators - -Assignment operators are used to assign values to variables. - -| Operator | Description | Example | -|----------|---------------------|-------------| -| `=` | Assign | `x = 5` | -| `+=` | Add and assign | `x += 5` | -| `-=` | Subtract and assign | `x -= 5` | -| `*=` | Multiply and assign | `x *= 5` | -| `/=` | Divide and assign | `x /= 5` | -| `%=` | Modulus and assign | `x %= 5` | - -### Example: - -```csharp -int num = 10; -num += 5; // num = 15 -num -= 3; // num = 12 -num *= 2; // num = 24 -num /= 4; // num = 6 -num %= 4; // num = 2 -``` - -## 6. Unary Operators - -Unary operators work with a single operand. - -| Operator | Description | Example | -|----------|------------------------|--------------| -| `+` | Unary plus | `+x` | -| `-` | Unary minus | `-x` | -| `++` | Increment | `x++` or `++x` | -| `--` | Decrement | `x--` or `--x` | -| `!` | Logical NOT | `!x` | - -### Example: - -```csharp -int value = 5; -Console.WriteLine(value++); // Output: 5, value becomes 6 -Console.WriteLine(++value); // Output: 7 -Console.WriteLine(-value); // Output: -7 -``` - -## 7. Ternary Operator - -The ternary operator (`? :`) is a shorthand for an `if-else` condition. - -### Syntax: - -```csharp -condition ? trueValue : falseValue; -``` - -### Example: - -```csharp -int age = 18; -string result = (age >= 18) ? "Adult" : "Minor"; -Console.WriteLine(result); // Output: Adult -``` - -## 8. Conclusion - -Operators are fundamental to performing operations in C#. By using arithmetic, comparison, logical, and other operators effectively, you can manipulate and evaluate data in your programs with ease. - ---- diff --git a/docs/languages/csharp/csharp-3.md b/docs/languages/csharp/csharp-3.md deleted file mode 100644 index 882833ab4..000000000 --- a/docs/languages/csharp/csharp-3.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: functions-in-csharp -sidebar_position: 3 -title: "Functions in C#" -sidebar_label: "Functions in C#" ---- - -# Functions in C# - -Functions, also known as methods, in C# are blocks of code that perform a specific task. They help modularize code and promote reusability. - ---- - -## 1. Structure of a Function - -The basic structure of a function in C# includes an access modifier, return type, name, parameters (optional), and a body. - -```csharp -[access_modifier] return_type FunctionName([parameters]) { - // Function body -} -``` - -### Example: - -```csharp -public int Add(int a, int b) { - return a + b; -} -``` - ---- - -## 2. Access Modifiers - -C# functions use access modifiers to control their visibility and accessibility: - -- **public**: Accessible from any class. -- **private**: Accessible only within the containing class. -- **protected**: Accessible within the containing class and derived classes. -- **internal**: Accessible within the same assembly. -- **protected internal**: Accessible within the same assembly or derived classes. - ---- - -## 3. Return Types - -A function in C# can have any data type as its return type or be `void` if it returns no value. - -### Example: - -```csharp -public int Multiply(int x, int y) { - return x * y; // returns an integer -} - -public void DisplayMessage() { - Console.WriteLine("Hello, World!"); // returns no value -} -``` - ---- - -## 4. Parameters and Arguments - -Functions can take parameters as input. Parameters are defined in the function signature, and arguments are the actual values passed. - -### Example: - -```csharp -public int Subtract(int a, int b) { - return a - b; -} - -// Usage -int result = Subtract(10, 5); // Passes 10 and 5 as arguments -``` - ---- - -## 5. Method Overloading - -Method overloading allows multiple methods to have the same name but different parameters. - -### Example: - -```csharp -public int Add(int a, int b) { - return a + b; -} - -public double Add(double a, double b) { - return a + b; -} -``` - ---- - -## 6. Static Methods - -Static methods belong to the class rather than an instance and can be called directly using the class name. - -### Example: - -```csharp -public static void PrintMessage() { - Console.WriteLine("This is a static method."); -} - -// Usage -ClassName.PrintMessage(); -``` - ---- - -## 7. Recursive Functions - -A recursive function is one that calls itself until a base condition is met. - -### Example: - -```csharp -public int Factorial(int n) { - if (n <= 1) return 1; - return n * Factorial(n - 1); -} -``` - ---- - -## 8. Lambda Expressions - -Lambda expressions provide a concise syntax to define anonymous functions. - -### Example: - -```csharp -Func square = x => x * x; -Console.WriteLine(square(5)); // Outputs: 25 -``` - ---- - -## 9. Async Functions - -Async functions allow asynchronous programming, making use of the `async` and `await` keywords. - -### Example: - -```csharp -public async Task GetDataAsync() { - await Task.Delay(1000); // Simulates asynchronous operation - return "Data loaded"; -} -``` - ---- - -## Summary - -Functions are essential in C# for creating reusable, organized, and maintainable code. Understanding the types, access modifiers, and usage of functions will enhance your programming capabilities. - -Happy coding! diff --git a/docs/languages/csharp/csharp-4.md b/docs/languages/csharp/csharp-4.md deleted file mode 100644 index 4437e18f7..000000000 --- a/docs/languages/csharp/csharp-4.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: loops-in-csharp -sidebar_position: 4 -title: "Loops in C#" -sidebar_label: "Loops in C#" ---- - -# Loops in C# - -Loops in C# allow you to execute a block of code repeatedly based on specific conditions. - ---- - -## 1. For Loop - -The `for` loop is commonly used when the number of iterations is known. - -### Syntax: - -```csharp -for (initialization; condition; increment/decrement) { - // code to be executed -} -``` - -### Example: - -```csharp -for (int i = 0; i < 5; i++) { - Console.WriteLine("Iteration " + i); -} -``` - ---- - -## 2. While Loop - -The `while` loop executes a block of code as long as the specified condition is true. - -### Syntax: - -```csharp -while (condition) { - // code to be executed -} -``` - -### Example: - -```csharp -int i = 0; -while (i < 5) { - Console.WriteLine("Iteration " + i); - i++; -} -``` - ---- - -## 3. Do-While Loop - -The `do-while` loop is similar to the `while` loop but guarantees the code block will execute at least once. - -### Syntax: - -```csharp -do { - // code to be executed -} while (condition); -``` - -### Example: - -```csharp -int i = 0; -do { - Console.WriteLine("Iteration " + i); - i++; -} while (i < 5); -``` - ---- - -## 4. Foreach Loop - -The `foreach` loop is used to iterate over collections, such as arrays or lists. - -### Syntax: - -```csharp -foreach (type variable in collection) { - // code to be executed -} -``` - -### Example: - -```csharp -int[] numbers = {1, 2, 3, 4, 5}; -foreach (int num in numbers) { - Console.WriteLine("Number: " + num); -} -``` - ---- - -## 5. Break and Continue Statements - -### a. Break Statement - -The `break` statement exits a loop prematurely. - -#### Example: - -```csharp -for (int i = 0; i < 10; i++) { - if (i == 5) { - break; // Exit the loop when i equals 5 - } - Console.WriteLine("Iteration " + i); -} -``` - -### b. Continue Statement - -The `continue` statement skips the current iteration and proceeds to the next one. - -#### Example: - -```csharp -for (int i = 0; i < 5; i++) { - if (i == 2) { - continue; // Skip the iteration when i equals 2 - } - Console.WriteLine("Iteration " + i); -} -``` - ---- - -## Summary - -Loops are essential in C# for repeating tasks and iterating over data structures efficiently. Understanding these loops and how to control them with `break` and `continue` will help you write more effective code. - -Happy coding! diff --git a/docs/languages/csharp/csharp-5.md b/docs/languages/csharp/csharp-5.md deleted file mode 100644 index b35058af3..000000000 --- a/docs/languages/csharp/csharp-5.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: arrays-in-csharp -sidebar_position: 5 -title: "Arrays in C#" -sidebar_label: "Arrays in C#" ---- - -# Arrays in C# - -Arrays in C# are used to store multiple values of the same type in a single variable. They are a fundamental data structure for handling collections of data. - ---- - -## 1. Declaring and Initializing Arrays - -In C#, arrays are declared by specifying the type of elements and the square brackets `[]`. - -### Syntax: - -```csharp -type[] arrayName = new type[size]; -``` - -### Example: - -```csharp -int[] numbers = new int[5]; // Array of 5 integers -``` - -You can also initialize an array with values: - -```csharp -int[] numbers = { 1, 2, 3, 4, 5 }; -``` - ---- - -## 2. Accessing Array Elements - -Array elements can be accessed by their index, with the first element at index `0`. - -### Example: - -```csharp -int[] numbers = { 10, 20, 30, 40, 50 }; -Console.WriteLine(numbers[2]); // Outputs 30 -``` - ---- - -## 3. Modifying Array Elements - -You can modify elements by assigning a new value to a specific index. - -### Example: - -```csharp -int[] numbers = { 10, 20, 30, 40, 50 }; -numbers[2] = 100; // Changes the value at index 2 to 100 -Console.WriteLine(numbers[2]); // Outputs 100 -``` - ---- - -## 4. Looping Through Arrays - -Arrays can be traversed using loops, such as `for` or `foreach`. - -### Using a For Loop - -```csharp -int[] numbers = { 1, 2, 3, 4, 5 }; -for (int i = 0; i < numbers.Length; i++) { - Console.WriteLine(numbers[i]); -} -``` - -### Using a Foreach Loop - -```csharp -int[] numbers = { 1, 2, 3, 4, 5 }; -foreach (int num in numbers) { - Console.WriteLine(num); -} -``` - ---- - -## 5. Multi-Dimensional Arrays - -C# supports multi-dimensional arrays, like 2D arrays, which can be used for representing data in a grid format. - -### Syntax: - -```csharp -type[,] arrayName = new type[rows, columns]; -``` - -### Example: - -```csharp -int[,] matrix = new int[3, 3]; // 3x3 matrix -matrix[0, 0] = 1; // Assigning value to the first element -``` - -### Initializing a 2D Array - -```csharp -int[,] matrix = { - {1, 2, 3}, - {4, 5, 6}, - {7, 8, 9} -}; -Console.WriteLine(matrix[1, 1]); // Outputs 5 -``` - ---- - -## 6. Array Class Methods - -The `Array` class in C# provides several useful methods for array manipulation. - -- `Length`: Returns the number of elements. -- `Sort()`: Sorts the elements in ascending order. -- `Reverse()`: Reverses the order of elements. - -### Example: - -```csharp -int[] numbers = { 5, 3, 8, 1, 4 }; -Array.Sort(numbers); // Sorts the array -Array.Reverse(numbers); // Reverses the array -``` - ---- - -## Summary - -Arrays in C# are essential for managing collections of data. Understanding how to declare, initialize, and manipulate arrays will help you effectively handle data in your programs. - -Happy coding! diff --git a/docs/languages/csharp/csharp-6.md b/docs/languages/csharp/csharp-6.md deleted file mode 100644 index 9a9234e42..000000000 --- a/docs/languages/csharp/csharp-6.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -id: objects-in-csharp -sidebar_position: 6 -title: "Objects in C#" -sidebar_label: "Objects in C#" ---- - -# Objects in C# - -In C#, objects are instances of classes, allowing us to bundle data and methods together to represent real-world entities. - ---- - -## 1. What is an Object? - -An object in C# is an instance of a class that contains properties and methods to model data and behavior. - -### Example: - -```csharp -public class Car { - public string color = "red"; - public void Drive() { - Console.WriteLine("The car is driving."); - } -} - -class Program { - static void Main() { - Car myCar = new Car(); // Creating an object of the Car class - Console.WriteLine(myCar.color); // Accessing a property - myCar.Drive(); // Calling a method - } -} -``` - -This code defines a `Car` class with a property `color` and a method `Drive`. An object of `Car` (`myCar`) is created and used. - ---- - -## 2. Creating Objects - -To create an object in C#, we use the `new` keyword along with the class constructor. - -### Syntax: - -```csharp -ClassName objectName = new ClassName(); -``` - -### Example: - -```csharp -Person person = new Person(); // Creating an object of Person class -``` - ---- - -## 3. Accessing Object Properties and Methods - -Object properties and methods are accessed using the dot (`.`) operator. - -### Example: - -```csharp -Car myCar = new Car(); -myCar.color = "blue"; // Modifying a property -myCar.Drive(); // Calling a method -``` - ---- - -## 4. Constructors in Objects - -Constructors are special methods used to initialize objects. - -### Example: - -```csharp -public class Car { - public string color; - public Car(string carColor) { - color = carColor; // Constructor assigns color - } -} - -class Program { - static void Main() { - Car myCar = new Car("blue"); - Console.WriteLine(myCar.color); // Outputs "blue" - } -} -``` - ---- - -## 5. Object Methods - -Objects can have methods that define behavior. - -### Example: - -```csharp -public class Person { - public void Greet() { - Console.WriteLine("Hello!"); - } -} - -class Program { - static void Main() { - Person person = new Person(); - person.Greet(); // Calls the Greet method - } -} -``` - ---- - -## 6. Properties with Getters and Setters - -Properties allow controlled access to an object's data. - -### Example: - -```csharp -public class Person { - private string name; - - public string Name { - get { return name; } - set { name = value; } - } -} - -class Program { - static void Main() { - Person person = new Person(); - person.Name = "Alice"; // Setting property - Console.WriteLine(person.Name); // Getting property - } -} -``` - ---- - -## Summary - -Objects are fundamental to C#, allowing us to model real-world entities with classes, properties, and methods. Mastering object creation and manipulation is essential for effective programming in C#. - -Happy coding! diff --git a/docs/languages/csharp/csharp-7.md b/docs/languages/csharp/csharp-7.md deleted file mode 100644 index 60d05fa3a..000000000 --- a/docs/languages/csharp/csharp-7.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -id: classes-in-csharp -sidebar_position: 7 -title: "Classes in C#" -sidebar_label: "Classes in C#" ---- - -# Classes in C# - -In C#, a class is a blueprint for creating objects. It defines properties, methods, and events that represent the characteristics and behaviors of an object. - ---- - -## 1. What is a Class? - -A class in C# defines the structure and behavior of objects. It includes fields, properties, methods, and constructors. - -### Example: - -```csharp -public class Car { - public string color = "red"; - public void Drive() { - Console.WriteLine("The car is driving."); - } -} -``` - -This example defines a class `Car` with a property `color` and a method `Drive`. - ---- - -## 2. Defining a Class - -In C#, classes are defined using the `class` keyword. - -### Syntax: - -```csharp -public class ClassName { - // fields, properties, methods, and constructors -} -``` - -### Example: - -```csharp -public class Person { - public string Name; - public int Age; -} -``` - ---- - -## 3. Fields in Classes - -Fields are variables that hold data related to an object. They are typically private but can be public as well. - -### Example: - -```csharp -public class Person { - public string Name; // Field -} -``` - ---- - -## 4. Properties - -Properties provide controlled access to fields and use `get` and `set` accessors. - -### Example: - -```csharp -public class Person { - private string name; - - public string Name { - get { return name; } - set { name = value; } - } -} -``` - ---- - -## 5. Methods in Classes - -Methods define actions that an object can perform. - -### Example: - -```csharp -public class Car { - public void Drive() { - Console.WriteLine("The car is driving."); - } -} -``` - ---- - -## 6. Constructors - -Constructors initialize an object when it is created. - -### Example: - -```csharp -public class Person { - public string Name; - - public Person(string name) { - Name = name; // Constructor initializes the Name property - } -} -``` - ---- - -## 7. Access Modifiers - -Access modifiers control the visibility of class members (`public`, `private`, `protected`). - -### Example: - -```csharp -public class Car { - private string color; // Private member - public void SetColor(string c) { - color = c; // Public method to set color - } -} -``` - ---- - -## 8. Static Classes and Members - -Static classes cannot be instantiated, and static members belong to the class itself rather than an instance. - -### Example: - -```csharp -public static class Utility { - public static void PrintMessage(string message) { - Console.WriteLine(message); - } -} -``` - ---- - -## Summary - -Classes are essential for object-oriented programming in C#. They provide a way to organize data and behaviors in your programs, making them more modular and maintainable. - -Happy coding! diff --git a/docs/languages/csharp/csharp-8.md b/docs/languages/csharp/csharp-8.md deleted file mode 100644 index 9016c1f40..000000000 --- a/docs/languages/csharp/csharp-8.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -id: inheritance-in-csharp -sidebar_position: 8 -title: "Inheritance in C#" -sidebar_label: "Inheritance in C#" ---- - -Inheritance is a core concept in object-oriented programming that allows one class to inherit the properties and methods of another class. In C#, inheritance is implemented using a class hierarchy, enabling code reuse, better organization, and the creation of complex relationships between classes. - -## 1. What is Inheritance? - -Inheritance enables a class (called the **derived class**) to inherit members (fields, methods, properties, etc.) from another class (called the **base class**). This provides the derived class with the capabilities of the base class, while also allowing it to define its own unique members. - -### Syntax: - -```csharp -class BaseClass { - // Base class members -} - -class DerivedClass : BaseClass { - // Derived class members -} -``` - -## 2. Example of Inheritance - -Here's a simple example demonstrating inheritance in C#: - -```csharp -using System; - -class Animal { - public void Eat() { - Console.WriteLine("Eating..."); - } -} - -class Dog : Animal { - public void Bark() { - Console.WriteLine("Barking..."); - } -} - -class Program { - static void Main() { - Dog dog = new Dog(); - dog.Eat(); // Inherited from Animal - dog.Bark(); // Defined in Dog - } -} -``` - -### Explanation: - -In this example: -- `Animal` is the base class with a method `Eat`. -- `Dog` is a derived class that inherits from `Animal` and has an additional method `Bark`. -- An instance of `Dog` can use both `Eat` (inherited) and `Bark` (defined in `Dog`). - -## 3. Types of Inheritance in C# - -In C#, inheritance is generally single inheritance, meaning a class can inherit from only one base class. However, you can achieve multiple inheritance by using interfaces. Here are the common types: - -- **Single Inheritance**: A class inherits from one base class. -- **Multiple Inheritance (with Interfaces)**: A class implements multiple interfaces to achieve a form of multiple inheritance. -- **Multilevel Inheritance**: A class is derived from another derived class. - -### Multilevel Inheritance Example: - -```csharp -class Vehicle { - public void Move() { - Console.WriteLine("Moving..."); - } -} - -class Car : Vehicle { - public void Drive() { - Console.WriteLine("Driving..."); - } -} - -class SportsCar : Car { - public void TurboBoost() { - Console.WriteLine("Turbo Boosting..."); - } -} - -class Test { - static void Main() { - SportsCar sc = new SportsCar(); - sc.Move(); // Inherited from Vehicle - sc.Drive(); // Inherited from Car - sc.TurboBoost(); // Defined in SportsCar - } -} -``` - -## 4. The `base` Keyword - -The `base` keyword is used to access members of the base class from within a derived class. This is useful when you want to call a constructor or method of the base class. - -### Example with `base`: - -```csharp -class Person { - public string Name; - public Person(string name) { - Name = name; - } -} - -class Employee : Person { - public int EmployeeID; - - public Employee(string name, int employeeID) : base(name) { - EmployeeID = employeeID; - } -} -``` - -## 5. Sealed Classes and Methods - -The `sealed` keyword is used to prevent further inheritance. When a class is marked as `sealed`, it cannot be used as a base class. - -### Example of Sealed Class: - -```csharp -sealed class FinalClass { - // Class implementation -} -``` - -### Example of Sealed Method: - -```csharp -class BaseClass { - public virtual void Display() { - Console.WriteLine("Base display"); - } -} - -class DerivedClass : BaseClass { - public sealed override void Display() { - Console.WriteLine("Derived display"); - } -} -``` - -## 6. Conclusion - -Inheritance is a powerful concept that allows classes to inherit properties and methods from other classes, promoting code reusability and organization. Mastering inheritance in C# helps in building more structured, readable, and maintainable applications. - ---- diff --git a/docs/languages/csharp/csharp-9.md b/docs/languages/csharp/csharp-9.md deleted file mode 100644 index 2d2996f1e..000000000 --- a/docs/languages/csharp/csharp-9.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -id: interfaces-in-csharp -sidebar_position: 9 -title: "Interfaces in C#" -sidebar_label: "Interfaces in C#" ---- - -In C#, an interface is a contract that defines a set of methods and properties that a class must implement, without providing the implementation itself. Interfaces are fundamental to achieving abstraction, polymorphism, and multiple inheritance in C#. They allow classes to share a common contract, which helps in designing flexible and scalable applications. - -## 1. What is an Interface? - -An interface defines a set of methods, properties, events, or indexers without implementing them. Classes or structs that implement an interface are required to provide an implementation for each member defined in the interface. - -### Syntax: - -```csharp -interface IExample { - void MethodA(); - int PropertyB { get; set; } -} -``` - -## 2. Implementing an Interface - -A class can implement multiple interfaces by providing implementations for each member defined in the interface. - -### Example: - -```csharp -using System; - -interface IAnimal { - void MakeSound(); -} - -class Dog : IAnimal { - public void MakeSound() { - Console.WriteLine("Bark"); - } -} - -class Program { - static void Main() { - Dog dog = new Dog(); - dog.MakeSound(); // Outputs "Bark" - } -} -``` - -### Explanation: - -In this example: -- `IAnimal` is an interface with a method `MakeSound`. -- `Dog` implements `IAnimal` by providing an implementation of `MakeSound`. -- The `Program` class creates an instance of `Dog` and calls `MakeSound`. - -## 3. Properties in Interfaces - -Interfaces can also define properties. Implementing classes must define the getter and/or setter for the properties as specified. - -### Example: - -```csharp -interface IPerson { - string Name { get; set; } -} - -class Student : IPerson { - public string Name { get; set; } -} -``` - -## 4. Multiple Interface Implementation - -C# does not support multiple inheritance with classes, but a class can implement multiple interfaces. - -### Example: - -```csharp -interface IFlyable { - void Fly(); -} - -interface IWalkable { - void Walk(); -} - -class Bird : IFlyable, IWalkable { - public void Fly() { - Console.WriteLine("Flying"); - } - - public void Walk() { - Console.WriteLine("Walking"); - } -} -``` - -In this example, `Bird` implements both `IFlyable` and `IWalkable` interfaces, showing how a class can implement multiple interfaces. - -## 5. Default Interface Methods (C# 8.0) - -In C# 8.0 and later, interfaces can provide default implementations for methods. This feature allows interfaces to have methods with a body, which can be overridden by implementing classes if needed. - -### Example: - -```csharp -interface ICalculator { - int Add(int a, int b); - int Multiply(int a, int b) => a * b; // Default implementation -} - -class Calculator : ICalculator { - public int Add(int a, int b) { - return a + b; - } -} -``` - -## 6. Interface Inheritance - -Interfaces can inherit from other interfaces, allowing more complex structures. - -### Example: - -```csharp -interface IReadable { - void Read(); -} - -interface IWritable : IReadable { - void Write(); -} - -class File : IWritable { - public void Read() { - Console.WriteLine("Reading file"); - } - - public void Write() { - Console.WriteLine("Writing file"); - } -} -``` - -In this example, `IWritable` extends `IReadable`, and `File` implements `IWritable`, so it must implement both `Read` and `Write`. - -## 7. Explicit Interface Implementation - -In cases where a class implements multiple interfaces that contain members with the same name, explicit interface implementation can be used to specify which interface’s method is being implemented. - -### Example: - -```csharp -interface IA { - void Display(); -} - -interface IB { - void Display(); -} - -class Test : IA, IB { - void IA.Display() { - Console.WriteLine("Display from IA"); - } - - void IB.Display() { - Console.WriteLine("Display from IB"); - } -} -``` - -## 8. Conclusion - -Interfaces in C# are essential for creating extensible, testable, and flexible code. They provide a contract that ensures consistency across implementing classes, enabling polymorphism and multiple inheritance through interfaces. - ---- diff --git a/docs/languages/java/_category_.json b/docs/languages/java/_category_.json deleted file mode 100644 index 158dff25c..000000000 --- a/docs/languages/java/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Java", - "position": 5, - "link": { - "type": "generated-index", - "description": "Java is a high-level, class-based, object-oriented programming language that is designed to have as few implementation dependencies as possible." - } - } \ No newline at end of file diff --git a/docs/languages/java/ex1.md b/docs/languages/java/ex1.md deleted file mode 100644 index 35faceca4..000000000 --- a/docs/languages/java/ex1.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: introduction-to-java -sidebar_position: 1 -title: Introduction to Java -sidebar_label: Introduction to Java ---- - -Hey, everyone! In this guide, we'll explore the fundamentals of Java programming language. -Java is a versatile, high-level, object-oriented programming language widely used for building robust and scalable applications. - -## What is Java? -Java is a general-purpose, class-based, and object-oriented programming language designed for -minimal implementation dependencies. It is known for its "Write Once, Run Anywhere" philosophy, which means that -compiled Java code can run on all platforms that support Java without the need for recompilation. - -## Why Use Java? -Java is a powerful and versatile programming language, offering several compelling reasons why developers choose to use it: - -### 1. **Platform Independence** -Java applications can run on different platforms like Windows, Mac, Linux, and even Raspberry Pi. - This is due to the "Write Once, Run Anywhere" capability provided by the Java Virtual Machine (JVM), making it highly portable. - -### 2. **Popularity** -Java is one of the most popular programming languages globally. With millions of developers using Java, - its ecosystem is mature and widely adopted in industries ranging from finance to tech startups. - -### 3. **High Demand in the Job Market** -There is a large demand for Java developers, and it continues to be a required skill in various job roles - such as software engineers, Android developers, and backend developers. - -### 4. **Ease of Learning** -Java has a simple, clean, and well-structured syntax. It is easy to learn, especially for those familiar with languages - like C++ or C#. This helps in reducing the learning curve for beginners and transitioning developers. - -### 5. **Open-Source and Free** -Java is open-source and freely available, enabling anyone to use it for developing a wide variety of applications - without licensing costs. - -### 6. **Secure, Fast, and Powerful** -Java provides security features like bytecode verification, and it is designed to minimize vulnerabilities like - buffer overflows. Additionally, the JVM optimizes the performance of applications, making Java both fast and powerful. - -### 7. **Community Support** -Java has a vast developer community with tens of millions of active members. There is extensive documentation, - forums, and community support available, ensuring that help is always available for developers. - -### 8. **Object-Oriented Language** -Java is an object-oriented language, which offers a clear structure for organizing and writing code. Object-oriented programming - (OOP) allows for better modularity, code reuse, and reduced development costs. - -### 9. **Similarity to C++ and C#** -Since Java is syntactically similar to C++ and C#, it is easier for developers to transition between these languages, - leveraging existing knowledge to learn Java or vice versa. - - -## Java Syntax -In this section, we will explore the basic structure of a Java program, using a "Hello World" example to understand key syntax rules. - -### 1. "Hello World" Example -```java title="Main.java" -public class Main { - public static void main(String[] args) { - System.out.println("Hello World"); - } -} -``` - -### 2. Example Breakdown -Let's break down this code step-by-step: - -**Classes in Java** -- Every line of code that runs in Java must be inside a class. Classes act as blueprints for creating objects. - In the example, the class is named `Main`. -- The class name should always start with an uppercase letter. -- **Java is case-sensitive**: for example, `MyClass` and `myclass` would be considered different names. - -**Filename and Class Name** -- The name of the Java file must match the class name. In this case, since the class is named `Main`, - the file should be saved as `Main.java`. - -**The `main` Method** -- The `main()` method is mandatory in every Java program, as it is the entry point where the program starts execution: -```java -public static void main(String[] args) { - // code inside here will run -} -``` --The `main()` method is written as public static void main(String[] args): -- **public:** This means the method can be called from outside the class. -- **static:** This means the method belongs to the class itself, not instances of the class. -- **void:** This means the method does not return a value. -- **String[] args:** This is used to pass arguments to the program. - -**System.out.println()** -- Inside the main() method, we can use the println() method to print a line of text to the screen: -```java -public static void main(String[] args) { - System.out.println("Hello World"); -} -``` - -### Note : -- The curly braces `{}` marks the beginning and the end of a block of code. -- System is a built-in Java class that contains useful members, such as out, which is short for "output". -- The `println()` method, short for "print line", is used to print a value to the screen (or a file). -- You should also note that each code statement must end with a semicolon (;). \ No newline at end of file diff --git a/docs/languages/java/ex2.md b/docs/languages/java/ex2.md deleted file mode 100644 index 6116afd20..000000000 --- a/docs/languages/java/ex2.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -id: variables-in-java -sidebar_position: 2 -title: Variables in Java -sidebar_label: Variables in Java ---- - -Hey, everyone! In this guide, we'll explore the concept of variables in Java. Variables are essential in programming, allowing you to store and manipulate data dynamically. Let's dive in! - -# 1. What is a Variable? - -A **variable** is a container that holds data that can be used and modified throughout a program. Each variable in Java has: -- **Data type**: Defines the type of value it can hold (e.g., `int`, `double`, `char`). -- **Name**: A unique identifier used to refer to it. -- **Value**: The data or information stored in the variable. - -### Syntax - -```java -dataType variableName = value; -``` -### Example - -```java -int age = 25; -double salary = 55000.50; -``` -In this example: -- age is an int variable holding the value 25. -- salary is a double variable holding the value 55000.50. - -# 2. Types of Variables in Java -Java provides different types of variables categorized by scope and purpose: - -- Instance Variables -- Class (Static) Variables -- Local Variables - -## 2.1. Instance Variables -- Declared inside a class but outside any method or constructor. -- Each object of the class has its own copy of the instance variables. -- Initialized to default values if not explicitly initialized. - -### Example -```java -public class Person { - String name; // Instance variable - int age; // Instance variable - - public Person(String name, int age) { - this.name = name; - this.age = age; - } -} -``` -In this example: -- name and age are instance variables for each Person object. - -## 2.2. Class (Static) Variables -- Declared with the `static` keyword inside a class. -- Shared across all instances of a class, meaning all objects share the same copy. -- Used for memory management or when a variable’s value is supposed to be the same across all instances. - -### Example -```java -public class Counter { - static int count = 0; // Static variable - - public Counter() { - count++; - } -} -``` -In this example: -- count is a static variable shared across all Counter objects. - -## 2.3. Local Variables -- Declared inside a method or constructor. -- Only accessible within the block or method they are declared in. -- Not given a default value and must be initialized before use. - -### Example -```java -public class Calculator { - public void add() { - int num1 = 10; // Local variable - int num2 = 20; // Local variable - int sum = num1 + num2; - System.out.println("Sum: " + sum); - } -} -``` -In this example: -- num1, num2, and sum are local variables within the add method. - -# 3. Variable Declaration and Initialization -Declaring a variable means defining its data type and name. Initializing a variable means assigning it a value. - -### Example -```java -int number; // Declaration -number = 5; // Initialization - -// Declaration and initialization in a single statement -int age = 25; -``` - -# 4. Data Types in Variables -Each variable in Java has a data type, which defines the type of data it can store. - -- **Primitive Data Types** : - -| Data Type | Size | Range | Default Value | -|-----------|---------|-------------------------------------------|---------------| -| `byte` | 1 byte | -128 to 127 | `0` | -| `short` | 2 bytes | -32,768 to 32,767 | `0` | -| `int` | 4 bytes | -2^31 to 2^31-1 | `0` | -| `long` | 8 bytes | -2^63 to 2^63-1 | `0L` | -| `float` | 4 bytes | Approximately ±3.40282347E+38F | `0.0f` | -| `double` | 8 bytes | Approximately ±1.79769313486231570E+308 | `0.0d` | -| `char` | 2 bytes | 0 to 65,535 (Unicode characters) | `'\u0000'` | -| `boolean` | 1 bit | `true` or `false` | `false` | - -## Detailed Explanation of Each Type - -- **`byte`**: - - Used to save space in large arrays, where memory savings are most needed. - - Example: `byte b = 100;` - -- **`short`**: - - Mainly used for compatibility with legacy code that requires data in the range of -32,768 to 32,767. - - Example: `short s = 1000;` - -- **`int`**: - - Default data type for integer values. - - Example: `int i = 100000;` - -- **`long`**: - - Used when a wider range than `int` is needed. - - Example: `long l = 100000000L;` - -- **`float`**: - - Single-precision 32-bit IEEE 754 floating point. - - Example: `float f = 10.5f;` - -- **`double`**: - - Double-precision 64-bit IEEE 754 floating point. - - Example: `double d = 10.5d;` - -- **`char`**: - - Stores a single 16-bit Unicode character. - - Example: `char c = 'A';` - -- **`boolean`**: - - Used for simple flags that track true/false conditions. - - Example: `boolean flag = true;` - -# 5. Constants in Java -A constant is a variable whose value cannot change once it has been assigned. Constants in Java are declared using the final keyword. - -### Example -```java -final double PI = 3.14159; -``` - -# 6. Variable Naming Conventions -Variable names should be descriptive and follow these conventions: -- Names should be meaningful such as age, price, count etc. -- Names can contain letters, digits, underscores, and dollar signs -- Names must begin with a letter -- Names should start with a lowercase letter, and cannot contain whitespace -- Names can also begin with $ and _ -- Names are case-sensitive ("myVar" and "myvar" are different variables) -- Reserved words (like Java keywords, such as int or boolean) cannot be used as names - -### Example -```java -int studentAge = 20; -double productPrice = 99.99; -``` - -## Summary -In this tutorial, we have covered the basics of variables in Java, including data types, constants and naming conventions. -With different types of variables and scopes, understanding how to declare, initialize, and use variables effectively is essential for Java programming. - -## Code Example -```java -// Create integer variables -int length = 4; -int width = 6; -int area; - -// Calculate the area of a rectangle -area = length * width; - -// Print variables -System.out.println("Length is: " + length); -System.out.println("Width is: " + width); -System.out.println("Area of the rectangle is: " + area); -``` \ No newline at end of file diff --git a/docs/languages/java/ex4.md b/docs/languages/java/ex4.md deleted file mode 100644 index d6d46f8be..000000000 --- a/docs/languages/java/ex4.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -id: multithreading-in-java -sidebar_position: 4 -title: Multithread in Java -sidebar_label: Multithread in Java ---- - -## What is a Thread? -A **thread** is the smallest unit of a process that can be scheduled for execution. It is a lightweight process that shares the same memory and resources of its parent process, allowing multiple tasks to be performed simultaneously. Java provides built-in support for multithreaded programming, which allows applications to perform multiple tasks at the same time, improving performance and responsiveness. - -### Key Concepts -- **Process**: An independent program in execution, with its own memory space. -- **Thread**: A subset of a process that shares the process’s memory and resources. -- **Multithreading**: The ability to execute multiple threads simultaneously. - -## Why Use Multithreading? -Multithreading enables efficient utilization of the CPU and improves the performance of applications by: -- Running tasks concurrently. -- Reducing idle time by utilizing CPU cycles better. -- Enhancing responsiveness in applications, especially in UI-based applications. - -## Creating a Thread in Java -Java provides two primary ways to create a thread: -1. **Extending the Thread class** -2. **Implementing the Runnable interface** - -### 1. Extending the Thread Class -To create a thread by extending the `Thread` class, a class must inherit from `Thread` and override its `run()` method. - -```java -class MyThread extends Thread { - public void run() { - System.out.println("Thread is running..."); - } - - public static void main(String[] args) { - MyThread thread = new MyThread(); - thread.start(); // Start the thread - } -} -``` - -### 2. Implementing the Runnable Interface -Another way to create a thread is by implementing the Runnable interface, which has a single run() method. - -```java -class MyRunnable implements Runnable { - @Override - public void run() { - System.out.println("Thread is running"); - } -} - -public class Main { - public static void main(String[] args) { - Thread thread = new Thread(new MyRunnable()); - thread.start(); // Starts the thread and calls the run() method - } -} -``` -**Note:** Implementing Runnable is preferred over extending Thread when a class already extends another class, as Java does not support multiple inheritance. - -## Thread Life Cycle -A thread in Java goes through the following states: - -1. **New**: - - When a thread is created, but not yet started. -2. **Runnable**: - - When the thread is ready to run, but not yet selected by the scheduler. -3. **Blocked**: - - When the thread is waiting to acquire a lock. -4. **Waiting**: - - When a thread is waiting indefinitely for another thread to perform a particular action. -5. **Timed Waiting**: - - When a thread is waiting for another thread to perform an action within a specific time frame. -6. **Terminated**: - - When a thread has completed its task and terminates. - -## Thread Methods -Java provides several methods for controlling and managing threads: - -- **start()**: - - Starts a thread and calls the `run()` method. -- **run()**: - - Contains the code to be executed by the thread. -- **sleep(long millis)**: - - Causes the current thread to sleep for the specified number of milliseconds. -- **join()**: - - Waits for a thread to die. -- **interrupt()**: - - Interrupts a sleeping or waiting thread. -- **isAlive()**: - - Checks if a thread is alive. - -```java -class MyRunnable implements Runnable { - @Override - public void run() { - try { - Thread.sleep(1000); // Sleep for 1 second - System.out.println("Thread running after 1-second sleep"); - } catch (InterruptedException e) { - System.out.println("Thread interrupted"); - } - } -} - -public class Main { - public static void main(String[] args) throws InterruptedException { - Thread thread = new Thread(new MyRunnable()); - thread.start(); - thread.join(); // Main thread waits for thread to finish - System.out.println("Main thread execution complete"); - } -} -``` - -## Thread Synchronization -In multithreading, if multiple threads access a shared resource simultaneously, it can lead to data inconsistency. **Synchronization** is the solution for this issue. It allows only one thread at a time to access a shared resource. - -Java provides various ways to achieve synchronization: -- **Synchronized Methods** -- **Synchronized Blocks** -- **Static Synchronization** -```java -class Counter { - private int count = 0; - - public synchronized void increment() { - count++; - } - - public int getCount() { - return count; - } -} - -public class Main { - public static void main(String[] args) { - Counter counter = new Counter(); - - Thread t1 = new Thread(() -> { - for (int i = 0; i < 1000; i++) counter.increment(); - }); - - Thread t2 = new Thread(() -> { - for (int i = 0; i < 1000; i++) counter.increment(); - }); - - t1.start(); - t2.start(); - - try { - t1.join(); - t2.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - System.out.println("Final count: " + counter.getCount()); // Should print 2000 - } -} -``` - -## Inter-Thread Communication -Java provides methods like wait(), notify(), and notifyAll() to facilitate communication between threads. - -- **wait()**: Tells the current thread to wait until another thread calls notify(). -- **notify()**: Wakes up a single thread that is waiting on the object's monitor. -- **notifyAll()**: Wakes up all threads that are waiting on the object's monitor. -```java -class SharedResource { - private boolean flag = false; - - public synchronized void produce() throws InterruptedException { - while (flag) { - wait(); - } - System.out.println("Produced an item"); - flag = true; - notify(); - } - - public synchronized void consume() throws InterruptedException { - while (!flag) { - wait(); - } - System.out.println("Consumed an item"); - flag = false; - notify(); - } -} - -public class Main { - public static void main(String[] args) { - SharedResource resource = new SharedResource(); - - Thread producer = new Thread(() -> { - try { - for (int i = 0; i < 5; i++) { - resource.produce(); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - }); - - Thread consumer = new Thread(() -> { - try { - for (int i = 0; i < 5; i++) { - resource.consume(); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - }); - - producer.start(); - consumer.start(); - } -} -``` - -## Summary -Multithreading is a powerful feature in Java that allows concurrent execution of tasks, making programs more efficient and responsive. Java provides a rich set of APIs to create and manage threads, handle synchronization, and facilitate inter-thread communication. Properly understanding and utilizing threads can greatly improve the performance and responsiveness of Java applications. diff --git a/docs/languages/java/java-1.md b/docs/languages/java/java-1.md deleted file mode 100644 index 44c7c124e..000000000 --- a/docs/languages/java/java-1.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: datatypes-in-java -sidebar_position: 1 -title: "Datatypes in Java" -sidebar_label: "Datatypes in Java" ---- - -Hey there! In this guide, we'll explore the different data types available in Java. Understanding data types is crucial for writing efficient and clear Java code. Let's dive in! - -* In Java, variables are containers that hold data and are defined by specifying a type followed by the variable name. -* Variables must be declared before use and can hold various data types. - -## 1. Declaring Variables in Java - -- To declare a variable in Java, you specify its type, followed by the variable's name. -```java -int age; -double salary; -char grade; -``` - -## 2. Initializing Variables in Java - - -* Variables can be initialized with a value at the time of declaration. - -```java -int age = 25; -double salary = 45000.50; -char grade = 'A'; -``` - -## 3. Types of Variables in Java - -### a. Integer Variables (`int`, `byte`, `short`, `long`) - -* Holds whole numbers, both positive and negative. - -```java -int x = 10; byte y = 20; // Range: -128 to 127 -short z = 30000; // Range: -32,768 to 32,767 -long w = 123456789L; // Suffix 'L' for long literals -``` - -### b. Floating-Point Variables (`float`, `double`) - -* Represents real numbers, with `float` using less precision than `double`. - -```java -float pi = 3.14f; // Suffix 'f' for float literals -double gravity = 9.81; -``` - -### c. Character Variables (`char`) - -* Stores a single character enclosed in single quotes. - -```java -char initial = 'A'; -``` - -### d. Boolean Variables (`boolean`) - -* Holds either `true` or `false` values. - -```java -boolean isSunny = true; -boolean isRaining = false; -``` - -### e. String Variables (`String`) - -* Represents a sequence of characters, enclosed in double quotes. - -```java -String greeting = "Hello, World!"; -``` - -## 4. Variable Scope - -* The scope of a variable refers to the region of the program where the variable is accessible. -* **Local Variables:** Declared inside methods or blocks, only accessible within that block. -* **Global Variables (Instance Variables):** Declared inside a class but outside any method and accessible from any method in the class. - -### a. Local Variable Example: - -```java -void myMethod() { - int localVar = 10; // Only accessible inside myMethod -} -``` - -### b. Global Variable Example: - -```java -class MyClass { int globalVar = 20; // Accessible throughout the MyClass - void myMethod() { - globalVar = 30; // Modifying globalVar - } } -``` - -## 5. Constant Variables - -* Variables declared as `final` cannot be modified after initialization. - - -```java -final int MAX_AGE = 100; -``` - -## 6. Type Conversion - -Java allows conversion between data types either implicitly or explicitly (using type casting). - -### a. Implicit Type Conversion - -* Java automatically converts one type to another when necessary. - - -```java -int x = 10; -double y = x; // Implicit conversion from int to double -``` - -### b. Explicit Type Conversion (Casting) - -* You can explicitly convert a variable's type using type casting. - -```java -double pi = 3.14; -int intPi = (int) pi; // Cast double to int -``` - -## 7. Dynamic Variables - -* Variables that are allocated memory during runtime using references. Java manages memory allocation and deallocation automatically through garbage collection. - - -```java -int[] arr = new int[5]; // Dynamically allocate memory for an array of integers -arr[0] = 5; -``` \ No newline at end of file diff --git a/docs/languages/java/java-10.md b/docs/languages/java/java-10.md deleted file mode 100644 index b5aec80c1..000000000 --- a/docs/languages/java/java-10.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -id: Polymorphism-in-java -sidebar_position: 10 -title: "Polymorphism in Java" -sidebar_label: "Polymorphism in Java" ---- -# Polymorphism in Java - -Welcome to the Java Programming repository! This section focuses on one of the core Object-Oriented Programming (OOP) concepts: **Polymorphism**. - -Polymorphism allows methods to perform different tasks based on the object calling them, providing flexibility and reusable code. In Java, polymorphism is mainly achieved through **method overriding** and **method overloading**. - -## Table of Contents -- [Introduction to Polymorphism](#introduction-to-polymorphism) -- [Types of Polymorphism](#types-of-polymorphism) - - [Compile-Time Polymorphism (Method Overloading)](#compile-time-polymorphism-method-overloading) - - [Run-Time Polymorphism (Method Overriding)](#run-time-polymorphism-method-overriding) -- [Code Examples](#code-examples) -- [Conclusion](#conclusion) - ---- - -## Introduction to Polymorphism - -Polymorphism, a Greek term meaning "many forms," allows Java methods to take on multiple forms. This means a single function can handle different data types or perform different tasks based on the context, enhancing code flexibility and scalability. - -Polymorphism in Java can be divided into two main types: - -1. **Compile-Time Polymorphism**: Achieved through method overloading. -2. **Run-Time Polymorphism**: Achieved through method overriding. - -## Types of Polymorphism - -### 1. Compile-Time Polymorphism (Method Overloading) - -**Method Overloading** allows multiple methods in the same class to have the same name but different parameters. The compiler determines the correct method to call based on the method signature (number and type of parameters). - -Example: -```java -public class Calculator { - // Method to add two integers - public int add(int a, int b) { - return a + b; - } - - // Method to add three integers - public int add(int a, int b, int c) { - return a + b + c; - } -} -``` -In the `Calculator` class, we have two `add` methods: - -- `add(int a, int b)` adds two integers. -- `add(int a, int b, int c)` adds three integers. - -### 2. Run-Time Polymorphism (Method Overriding) - -**Method Overriding** occurs when a subclass provides a specific implementation of a method already defined in its superclass. This type of polymorphism enables a child class to alter the behavior of its parent class. - -Example: - -```java -class Animal { - // Method to describe sound of an animal - public void sound() { - System.out.println("Some generic animal sound"); - } -} - -class Dog extends Animal { - // Method to describe sound of a dog (overrides the parent method) - @Override - public void sound() { - System.out.println("Woof Woof"); - } -} - -class Cat extends Animal { - // Method to describe sound of a cat (overrides the parent method) - @Override - public void sound() { - System.out.println("Meow Meow"); - } -} -``` -In this example: - -- The `Animal` class has a method `sound()` that prints a generic message. -- The `Dog` and `Cat` classes override the `sound()` method with their unique implementations. - -### Run-Time Polymorphism in Action: - -```java -public class Main { - public static void main(String[] args) { - Animal myDog = new Dog(); // Polymorphic object - Animal myCat = new Cat(); // Polymorphic object - - myDog.sound(); // Outputs: Woof Woof - myCat.sound(); // Outputs: Meow Meow - } -} -``` -Here, the method that gets executed depends on the object type at runtime.` myDog` calls the `Dog` class's version of `sound()`, while `myCat` calls the `Cat` class's version. - -## Conclusion -Polymorphism is a powerful feature in Java that increases flexibility and readability. By using method overloading and overriding, we can write more dynamic and adaptable code. Try experimenting with these examples to deepen your understanding of how polymorphism works in Java! - -Happy Coding (✿◠‿◠) diff --git a/docs/languages/java/java-2.md b/docs/languages/java/java-2.md deleted file mode 100644 index da4aee363..000000000 --- a/docs/languages/java/java-2.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -id: operators-in-java -sidebar_position: 2 -title: "Operators in Java" -sidebar_label: "Operators in Java" ---- - -Hey there! In this guide, we'll explore operators in Java. Operators are symbols that instruct the compiler to perform specific operations on variables or values. Java supports a variety of operators, including arithmetic, relational, logical, bitwise, and more. Let's dive in! - -- Operators are symbols that instruct the compiler to perform specific operations on variables or values. -- Java supports a variety of operators, including arithmetic, relational, logical, bitwise, and more. - -## 1. Arithmetic Operators - -Arithmetic operators perform mathematical operations such as addition, subtraction, multiplication, and division. - -| Operator | Description | Example | -| -------- | ------------------- | ------- | -| + | Addition | x + y | -| - | Subtraction | x - y | -| * | Multiplication | x * y | -| / | Division | x / y | -| % | Modulus (remainder) | x % y | - -#### Example: - -```java -int x = 10, y = 5; -System.out.println(x + y); // Output: 15 -System.out.println(x - y); // Output: 5 -System.out.println(x * y); // Output: 50 -System.out.println(x / y); // Output: 2 -System.out.println(x % y); // Output: 0 -``` - -## 2. Relational Operators - - -Relational operators compare two values and return a boolean result (`true` or `false`). - -| Operator | Description | Example | -| --- | --- | --- | -| \== | Equal to | x == y | -| != | Not equal to | x != y | -| > | Greater than | x > y | -| \< | Less than | x \< y | -| >= | Greater than or equal to | x >= y | -| \<= | Less than or equal to | x \<= y | - -#### Example: - -```java -int x = 10, y = 5; System.out.println(x == y); // Output: false -System.out.println(x != y); // Output: true -System.out.println(x > y); // Output: true -System.out.println(x < y); // Output: false -System.out.println(x >= y); // Output: true -System.out.println(x <= y); // Output: false -``` - -## 3. Logical Operators - -Logical operators are used to perform logical operations and combine multiple conditions. - -| Operator | Description | Example | -| --- | --- | --- | -| && | Logical AND | (x > 5 && y \< 10) | -| \|\| | Logical OR | (x > 5 \|\| y \< 10) | -| ! | Logical NOT | !(x > 5) | - -#### Example: -```java -int x = 10, y = 5; System.out.println(x > 5 && y < 10); // Output: true -System.out.println(x > 5 || y > 10); // Output: true -System.out.println(!(x > 5)); // Output: false -``` - -## 4. Assignment Operators -Assignment operators are used to assign values to variables. - -| Operator | Description | Example | -| --- | --- | --- | -| \= | Assigns value | x = y | -| += | Adds and assigns | x += y | -| -= | Subtracts and assigns | x -= y | -| *= | Multiplies and assigns | x *= y | -| /= | Divides and assigns | x /= y | -| %= | Modulus and assigns | x %= y | - -#### Example: - -```java -int x = 10, y = 5; x += y; // Equivalent to x = x + y -System.out.println(x); // Output: 15 -``` - -## 5. Increment and Decrement Operators - - -Increment and decrement operators are used to increase or decrease a variable's value by 1. - -| Operator | Description | Example | -| --- | --- | --- | -| ++ | Increments value | ++x or x++ | -| -- | Decrements value | --x or x-- | - -#### Example: - -```java -int x = 10; System.out.println(++x); // Output: 11 (Pre-increment) -System.out.println(x--); // Output: 11 (Post-decrement) -System.out.println(x); // Output: 10 -``` - -## 6. Bitwise Operators - -Bitwise operators operate on bits and perform bit-level operations. - -| Operator | Description | Example | -| --- | --- | --- | -| & | Bitwise AND | x & y | -| \| | Bitwise OR | \| | -| ^ | Bitwise XOR | x ^ y | -| ~ | Bitwise NOT | ~x | -| >> | Right shift | x >> 2 | -| \<\< | Left shift | x \<\< 2 | - -#### Example: - -```java -int x = 10, y = 5; System.out.println(x & y); // Output: 0 -System.out.println(x | y); // Output: 15 -``` - -## 7. Ternary Operator - - -The ternary operator is a shorthand for an if-else statement. - -| Operator | Description | Example | -| --- | --- | --- | -| ?: | Ternary | condition ? expr1 : expr2 | - -#### Example: -```java -int x = 10; int result = (x > 5) ? 100 : 200; -System.out.println(result); // Output: 100 -``` \ No newline at end of file diff --git a/docs/languages/java/java-3.md b/docs/languages/java/java-3.md deleted file mode 100644 index d9848b5ea..000000000 --- a/docs/languages/java/java-3.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -id: decision-making-in-java -sidebar_position: 3 -title: "Decision Making in Java" -sidebar_label: "Decision Making in Java" ---- - -Hey there! In this guide, we'll explore decision-making in Java. Decision-making structures allow you to execute different blocks of code based on certain conditions. Let's dive in! - -* Decision-making structures allow you to execute different blocks of code based on certain conditions. -* Java provides several constructs for decision-making, including `if`, `else`, `else if`, and `switch`. - -## 1. The `if` Statement - -### Syntax: -```java -if (condition) { - // code to be executed if condition is true -} -``` -### Example: -```java -int num = 10; if (num > 0) { - System.out.println("The number is positive."); } -``` - -## 2\. The `if...else` Statement - -### Syntax: -```java -if (condition1) { // code to be executed if condition1 is true - } else { // code to be executed if condition1 is false - } -``` - -### Example: - -```java -int num = -5; if (num > 0) { - System.out.println("The number is positive."); } - else { - System.out.println("The number is not positive."); } -``` - -## 3\. The `if...else if...else` Statement - - -### Syntax: - -```java -if (condition1) { // code to be executed if condition1 is true - } else if (condition2) { // code to be executed if condition2 is true - } else { // code to be executed if both conditions are false - } -``` - -### Example: -```java -int num = 0; if (num > 0) { - System.out.println("The number is positive."); } - else if (num < 0) { - System.out.println("The number is negative."); } - else { - System.out.println("The number is zero."); } -``` - -## 4\. The `switch` Statement - - -### Syntax: - -```java -switch (expression) { - case value1: // code to be executed if expression == value1 - break; - case value2: // code to be executed if expression == value2 - break; - default: // code to be executed if expression doesn't match any case - } -``` - -### Example: - -```java -int day = 3; switch (day) { - case 1: - System.out.println("Monday"); - break; - case 2: - System.out.println("Tuesday"); - break; - case 3: - System.out.println("Wednesday"); - break; - default: - System.out.println("Not a valid day"); } -``` - -## 5\. Nested `if` Statements - -### Example: - -```java -int num = 15; if (num > 10) { - System.out.println("The number is greater than 10."); - if (num > 20) { - System.out.println("The number is also greater than 20."); - } } -``` - -## 6\. Conditional Operators - - -Java also supports conditional operators for compact decision-making. - -### Ternary Operator - -### Syntax: - -```java -(condition) ? expression1 : expression2; -``` - -### Example: - -```java -int num = 10; String result = (num > 0) ? "Positive" : "Non-positive"; -System.out.println(result); -``` - ------- - -Understanding decision-making structures in Java is crucial for controlling the flow of your program and executing different actions based on conditions. Happy coding! \ No newline at end of file diff --git a/docs/languages/java/java-4.md b/docs/languages/java/java-4.md deleted file mode 100644 index 3276850d0..000000000 --- a/docs/languages/java/java-4.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -id: loops-in-java -sidebar_position: 4 -title: "Loops In Java" -sidebar_label: "Loops In Java" ---- - -Hey there! In this guide, we'll explore loops in Java. Loops are used to execute a block of code repeatedly based on specific conditions. Let's dive in! - -* Java provides several types of loops that allow you to execute a block of code multiple times based on specific conditions. -* The main types of loops in Java are `for`, `while`, and `do-while`. - -## 1. For Loop -The for loop is used when you know how many times you want to execute a statement or a block of statements. -#### Syntax: -```java -for (initialization; condition; increment/decrement) { - // code to be executed -} - -``` -#### Example: -```java -public class Main { - public static void main(String[] args) { - for (int i = 0; i < 5; i++) { - System.out.println("Iteration " + i); - } - } -} - -``` - -#### Output: -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -## 2. While Loop -The `while` loop is used when you want to execute a block of code as long as a specified condition is true. -#### Syntax: -```java -while(condition) { - // code to be executed -} - -``` -#### Example: -```java -public class Main { - public static void main(String[] args) { - int i = 0; - while (i < 5) { - System.out.println("Iteration " + i); - i++; - } - } -} - -} -``` - -#### Output: -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -## 3. Do-While Loop -The `do-while` loop is similar to the `while` loop, except that it guarantees that the code block will be executed at least once before the condition is tested. - -#### Syntax: -```java -do { - // code to be executed -} while(condition); -``` -#### Example: -```java -public class Main { - public static void main(String[] args) { - int i = 0; - do { - System.out.println("Iteration " + i); - i++; - } while (i < 5); - } -} - -``` - -#### Output: -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - - -## 4. Nested Loops -You can also use loops inside other loops, which are called nested loops. - -#### Example: -```java -public class Main { - public static void main(String[] args) { - for (int i = 1; i <= 3; i++) { - for (int j = 1; j <= 2; j++) { - System.out.println("Outer Loop: " + i + ", Inner Loop: " + j); - } - } - } -} - -``` - -``` -Outer Loop: 1, Inner Loop: 1 -Outer Loop: 1, Inner Loop: 2 -Outer Loop: 2, Inner Loop: 1 -Outer Loop: 2, Inner Loop: 2 -Outer Loop: 3, Inner Loop: 1 -Outer Loop: 3, Inner Loop: 2 - -``` - -## 5. Break and Continue Statements - -### a. Break Statement -The `break` statement is used to exit a loop prematurely. - -#### Example: -```java -public class Main { - public static void main(String[] args) { - for (int i = 0; i < 10; i++) { - if (i == 5) { - break; // Exit the loop when i equals 5 - } - System.out.println("Iteration " + i); - } - } -} - -``` - -#### Output: -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - -### b. Continue Statement -The `continue` statement skips the current iteration and proceeds to the next one. - -#### Example: -```java -public class Main { - public static void main(String[] args) { - for (int i = 0; i < 5; i++) { - if (i == 2) { - continue; // Skip the iteration when i equals 2 - } - System.out.println("Iteration " + i); - } - } -} - -``` - -#### Output: -``` -Iteration 0 -Iteration 1 -Iteration 2 -Iteration 3 -Iteration 4 - -``` - ---- - -Loops are essential for controlling the flow of execution in your Java programs, enabling you to perform repetitive tasks efficiently. Understanding how to use them effectively will greatly enhance your programming skills! \ No newline at end of file diff --git a/docs/languages/java/java-5-1.md b/docs/languages/java/java-5-1.md deleted file mode 100644 index 49c6ddd12..000000000 --- a/docs/languages/java/java-5-1.md +++ /dev/null @@ -1,320 +0,0 @@ ---- -id: strings-in-java -sidebar_position: 5 -title: "Strings In Java" -sidebar_label: "Strings In Java" ---- - -Hello! In this guide, we'll explore how to work with strings in Java. Strings are a crucial part of Java programming as they allow you to manipulate and process text easily. Let's dive in! - -## 1. Java Strings - -In Java, strings are objects of the `String` class, which is part of the Java standard library. Unlike C-style strings, Java strings are immutable, meaning once a string object is created, it cannot be changed. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String greeting = "Hello, World!"; - System.out.println(greeting); - } -} -``` - -#### Output: - -``` -Hello, World! -``` - ---- - -## 2. Common String Operations - -### 2.1 String Length - -To get the length of a string, you can use the `.length()` method. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String greeting = "Hello, World!"; - System.out.println("Length: " + greeting.length()); - } -} -``` - -#### Output: - -``` -Length: 13 -``` - ---- - -### 2.2 String Concatenation - -You can concatenate two strings using the `+` operator or the `.concat()` method. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String firstName = "John"; - String lastName = "Doe"; - String fullName = firstName + " " + lastName; - System.out.println(fullName); - } -} -``` - -#### Output: - -``` -John Doe -``` - ---- - -### 2.3 Accessing Characters in a String - -You can access individual characters in a string using the `.charAt()` method. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String greeting = "Hello"; - System.out.println(greeting.charAt(0)); // Output: H - } -} -``` - -#### Output: - -``` -H -``` - ---- - -## 3. Modifying Strings - -### 3.1 Changing Characters - -Since strings in Java are immutable, you can't modify the string directly, but you can create a new string with the desired changes. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String greeting = "Hello"; - String modifiedGreeting = "J" + greeting.substring(1); - System.out.println(modifiedGreeting); // Output: Jello - } -} -``` - -#### Output: - -``` -Jello -``` - ---- - -### 3.2 Substrings - -You can extract a substring from a string using the `.substring()` method. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String greeting = "Hello, World!"; - String sub = greeting.substring(0, 5); // Extracts "Hello" - System.out.println(sub); - } -} -``` - -#### Output: - -``` -Hello -``` - ---- - -### 3.3 String Comparison - -You can compare two strings using the `.equals()` method or comparison operators. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String str1 = "Hello"; - String str2 = "World"; - - if (str1.equals(str2)) { - System.out.println("Strings are equal"); - } else { - System.out.println("Strings are not equal"); - } - } -} -``` - -#### Output: - -``` -Strings are not equal -``` - ---- - -## 4. String Input - -You can input strings from the user using `Scanner`. - -#### Example: - -```java -import java.util.Scanner; - -public class Main { - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - System.out.print("Enter your name: "); - String name = sc.nextLine(); - System.out.println("Hello, " + name); - } -} -``` - -#### Output: - -``` -Enter your name: John Doe -Hello, John Doe -``` - ---- - -## 5. String Functions - -Java provides several methods to manipulate strings. Some common ones include: - -### 5.1 `indexOf()` - -Finds the first occurrence of a substring. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String str = "Hello, World!"; - int pos = str.indexOf("World"); - - if (pos != -1) { - System.out.println("Found at position: " + pos); - } else { - System.out.println("Not found!"); - } - } -} -``` - -#### Output: - -``` -Found at position: 7 -``` - ---- - -### 5.2 `replace()` - -Replaces part of the string with another string. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String str = "Hello, World!"; - String newStr = str.replace("World", "Universe"); - System.out.println(newStr); - } -} -``` - -#### Output: - -``` -Hello, Universe! -``` - ---- - -### 5.3 `toUpperCase()` and `toLowerCase()` - -Converts a string to uppercase or lowercase. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String str = "Hello"; - System.out.println(str.toUpperCase()); // Output: HELLO - System.out.println(str.toLowerCase()); // Output: hello - } -} -``` - -#### Output: - -``` -HELLO -hello -``` - ---- - -### 5.4 `trim()` - -Removes leading and trailing whitespaces. - -#### Example: - -```java -public class Main { - public static void main(String[] args) { - String str = " Hello, World! "; - System.out.println("Before trim: '" + str + "'"); - System.out.println("After trim: '" + str.trim() + "'"); - } -} -``` - -#### Output: - -``` -Before trim: ' Hello, World! ' -After trim: 'Hello, World!' -``` - ---- - -Strings are a fundamental part of Java programming, and mastering them will significantly enhance your ability to handle text-based data. Happy coding! diff --git a/docs/languages/java/java-6.md b/docs/languages/java/java-6.md deleted file mode 100644 index 2b4ac8b65..000000000 --- a/docs/languages/java/java-6.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -id: classes-in-java -sidebar_position: 7 -title: Classes in Java -sidebar_label: Classes ---- - -## Overview -In Java, classes are the fundamental building blocks of object-oriented programming (OOP). A class is essentially a blueprint or template that defines the properties (fields) and behaviors (methods) of objects. It provides a way to encapsulate data and functions together, allowing for code modularity, reuse, and better organization. - -Classes in Java define the structure and behavior of objects, specifying what data they can hold and what operations they can perform. Each instance of a class (known as an object) represents a specific implementation of that class. - -## What Is a Class? -A class in Java is a user-defined data type that serves as a blueprint for creating objects. It encapsulates data for the object and methods to manipulate that data. Classes contain: -- **Fields (Instance Variables)**: These represent the state or attributes of an object. -- **Methods**: These define the actions or behaviors of the object. -- **Constructors**: Special methods used for initializing objects. - -## Syntax -The basic syntax for defining a class in Java is as follows: - -```java -access_modifier class ClassName { - // Fields (attributes) - data_type fieldName; - - // Methods (behaviors) - return_type methodName(parameters) { - // Method body - } - - // Constructor - ClassName(parameters) { - // Constructor body - } -} -``` -## Key Points -- **Encapsulation:** Classes encapsulate data (fields) and behavior (methods), promoting data hiding and modularity. -- **Constructors:** Special methods that initialize the object’s fields. If no constructor is defined, Java provides a default constructor. -- **Access Modifiers:** Classes can have different access levels (public, private, etc.) to control their visibility. - -## Conclusion -Classes are a core concept in Java’s object-oriented programming model, allowing developers to define the structure and behavior of objects. Understanding how to define, instantiate, and manipulate classes is essential for building Java applications. By mastering classes, you lay the foundation for using advanced OOP concepts like inheritance, polymorphism, and encapsulation. diff --git a/docs/languages/java/java-7.md b/docs/languages/java/java-7.md deleted file mode 100644 index 1c33ed1c5..000000000 --- a/docs/languages/java/java-7.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -id: objects-in-java -sidebar_position: 8 -title: Objects in Java -sidebar_label: Objects ---- - -## Overview -In Java, objects are fundamental to the concept of object-oriented programming (OOP). They represent real-world entities with attributes (properties) and behaviors (methods). Objects provide a way to model and organize code by grouping related data and functionality. Understanding how to create and work with objects is crucial for mastering Java and OOP principles. - -## What Are Objects? -An object is an instance of a class, which is a blueprint or template that defines the properties (fields) and behaviors (methods) of that object. While a class specifies what an object will look like and how it will behave, an object is a concrete realization of that class. In simpler terms, if a class is a blueprint for a house, then an object is an actual house built using that blueprint. - -Objects in Java have: -- **State**: The data or attributes of the object, represented by instance variables. -- **Behavior**: The operations or functionalities the object can perform, represented by methods. -- **Identity**: A unique reference that distinguishes each object from others. - -## Creating Objects -To create an object in Java, you need to: -1. **Define a class**: The class must be defined first, specifying the attributes and methods. -2. **Use the `new` keyword**: Create an instance of the class using the `new` keyword. -3. **Assign the object to a reference variable**: This variable will hold the memory address of the created object. - -### Example: Creating an Object -Here’s an example of defining a class and creating an object in Java: - -```java -// Class definition -public class Car { - // Attributes (state) - String model; - int year; - - // Method (behavior) - public void displayDetails() { - System.out.println("Model: " + model + ", Year: " + year); - } -} - -// Main class to create objects -public class Main { - public static void main(String[] args) { - // Creating an object of the Car class - Car myCar = new Car(); - // Setting the attributes - myCar.model = "Toyota"; - myCar.year = 2022; - // Calling the method - myCar.displayDetails(); // Output: Model: Toyota, Year: 2022 - } -} -``` -## Key Points -- **Multiple Objects:** You can create multiple objects from the same class, each with its own set of attribute values. -- **Reference Variables:** The reference variable holds the memory address where the object is stored, not the actual object. -- **Accessing Members:** Use the dot (.) operator to access the attributes and methods of the object (e.g., myCar.model). -- **Garbage Collection:** Java has automatic memory management. When an object is no longer referenced, it is eligible for garbage collection, freeing up memory. - -## Conclusion -Objects are essential in Java, serving as instances of classes that bring data and behavior together. By creating objects, developers can model real-world entities and organize code in a modular, reusable way. Understanding how to define classes, instantiate objects, and manipulate their properties is a foundational skill in Java programming. Practice creating and using objects to strengthen your grasp of OOP principles. diff --git a/docs/languages/java/java-8.md b/docs/languages/java/java-8.md deleted file mode 100644 index 9b37913f8..000000000 --- a/docs/languages/java/java-8.md +++ /dev/null @@ -1,303 +0,0 @@ ---- -id: inheritance-in-java -sidebar_position: 8 -title: "Inheritance in Java" -sidebar_label: "Inheritance in Java" ---- - -Hey there! In this guide, we'll explore the concept of inheritance in Java. Inheritance allows one class to inherit fields and methods from another class, promoting code reusability and organization. Let's dive in! - - - -## 1. What is Inheritance? - -Inheritance is a mechanism in object-oriented programming that allows one class (called the **subclass** or **child class**) to inherit properties and behaviors (fields and methods) from another class (called the **superclass** or **parent class**). - -## 2. Syntax of Inheritance - -In Java, the `extends` keyword is used to inherit a class. - -**Example:** - -```java -// Superclass -class Animal { - void eat() { - System.out.println("This animal is eating."); - } -} - -// Subclass -class Dog extends Animal { - void bark() { - System.out.println("The dog is barking."); - } -} - -public class Main { - public static void main(String[] args) { - Dog myDog = new Dog(); - myDog.eat(); // Inherited from the Animal class - myDog.bark(); // Defined in the Dog class - } -} -``` - -**Output:** - -``` -This animal is eating. -The dog is barking. -``` - -In this example, the `Dog` class inherits the `eat()` method from the `Animal` class. - - - -## 3. Types of Inheritance - -### 3.1 Single Inheritance - -Single inheritance occurs when a subclass inherits from a single superclass. - -**Example:** - -```java -class A { - void show() { - System.out.println("Class A method"); - } -} - -class B extends A { - void display() { - System.out.println("Class B method"); - } -} - -public class Main { - public static void main(String[] args) { - B obj = new B(); - obj.show(); - obj.display(); - } -} -``` - -**Output:** - -``` -Class A method -Class B method -``` - - - -### 3.2 Multilevel Inheritance - -Multilevel inheritance occurs when a class is derived from a class that is also derived from another class. - -**Example:** - -```java -class A { - void show() { - System.out.println("Class A method"); - } -} - -class B extends A { - void display() { - System.out.println("Class B method"); - } -} - -class C extends B { - void print() { - System.out.println("Class C method"); - } -} - -public class Main { - public static void main(String[] args) { - C obj = new C(); - obj.show(); - obj.display(); - obj.print(); - } -} -``` - -**Output:** - -``` -Class A method -Class B method -Class C method -``` - - - -### 3.3 Hierarchical Inheritance - -In hierarchical inheritance, multiple classes inherit from a single superclass. - -**Example:** - -```java -class A { - void show() { - System.out.println("Class A method"); - } -} - -class B extends A { - void display() { - System.out.println("Class B method"); - } -} - -class C extends A { - void print() { - System.out.println("Class C method"); - } -} - -public class Main { - public static void main(String[] args) { - B obj1 = new B(); - C obj2 = new C(); - - obj1.show(); - obj1.display(); - - obj2.show(); - obj2.print(); - } -} -``` - -**Output:** - -``` -Class A method -Class B method -Class A method -Class C method -``` - - - -## 4. The `super` Keyword - -The `super` keyword is used to refer to the immediate superclass's methods or constructors. - -### 4.1 Using `super` to Call Superclass Methods - -**Example:** - -```java -class Animal { - void sound() { - System.out.println("Animal is making a sound"); - } -} - -class Dog extends Animal { - void sound() { - super.sound(); // Call the superclass method - System.out.println("Dog is barking"); - } -} - -public class Main { - public static void main(String[] args) { - Dog myDog = new Dog(); - myDog.sound(); - } -} -``` - -**Output:** - -``` -Animal is making a sound -Dog is barking -``` - - - -### 4.2 Using `super` to Call Superclass Constructors - -You can also use `super()` to call a superclass constructor. - -**Example:** - -```java -class Animal { - Animal() { - System.out.println("Animal is created"); - } -} - -class Dog extends Animal { - Dog() { - super(); // Call superclass constructor - System.out.println("Dog is created"); - } -} - -public class Main { - public static void main(String[] args) { - Dog myDog = new Dog(); - } -} -``` - -**Output:** - -``` -Animal is created -Dog is created -``` - - - -## 5. Method Overriding - -Method overriding allows a subclass to provide a specific implementation of a method that is already defined in its superclass. - -**Example:** - -```java -class Animal { - void sound() { - System.out.println("Animal makes a sound"); - } -} - -class Cat extends Animal { - @Override - void sound() { - System.out.println("Cat meows"); - } -} - -public class Main { - public static void main(String[] args) { - Cat myCat = new Cat(); - myCat.sound(); // Calls the overridden method in the Cat class - } -} -``` - -**Output:** - -``` -Cat meows -``` - - -## 6. Final Thoughts - -Inheritance is a fundamental concept in Java that helps you reuse code, establish relationships between classes, and create well-structured applications. By understanding inheritance and how to use it effectively, you can create more modular and maintainable Java applications. diff --git a/docs/languages/java/java-9.md b/docs/languages/java/java-9.md deleted file mode 100644 index f73d04438..000000000 --- a/docs/languages/java/java-9.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -id: interfaces-in-java -sidebar_position: 9 -title: "Interfaces in Java" -sidebar_label: "Interfaces in Java" ---- - -# Interfaces in Java - -Hey there! In this guide, we'll explore the concept of interfaces in Java. Interfaces are used to define abstract methods that classes can implement, allowing for multiple inheritance and flexibility in designing systems. Let's get started! - ---- - -## 1. What is an Interface? - -An interface in Java is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. The methods in interfaces are abstract by default, meaning they do not have a body. - ---- - -## 2. Defining an Interface - -In Java, you define an interface using the `interface` keyword. - -#### Example: - -```java -// Defining an interface -interface Animal { - void sound(); // abstract method -} -``` - ---- - -## 3. Implementing an Interface - -A class implements an interface using the `implements` keyword. The class must provide implementations for all the methods declared in the interface. - -#### Example: - -```java -interface Animal { - void sound(); // abstract method -} - -class Dog implements Animal { - public void sound() { - System.out.println("The dog barks"); - } -} - -public class Main { - public static void main(String[] args) { - Dog myDog = new Dog(); - myDog.sound(); // Calls the sound method - } -} -``` - -#### Output: - -``` -The dog barks -``` - -In this example, the `Dog` class implements the `Animal` interface and provides the implementation for the `sound` method. - ---- - -## 4. Multiple Interfaces - -A class can implement multiple interfaces, which is one way Java allows multiple inheritance. - -#### Example: - -```java -interface Animal { - void sound(); -} - -interface Pet { - void play(); -} - -class Dog implements Animal, Pet { - public void sound() { - System.out.println("The dog barks"); - } - - public void play() { - System.out.println("The dog plays fetch"); - } -} - -public class Main { - public static void main(String[] args) { - Dog myDog = new Dog(); - myDog.sound(); - myDog.play(); - } -} -``` - -#### Output: - -``` -The dog barks -The dog plays fetch -``` - ---- - -## 5. Default Methods in Interfaces - -Java 8 introduced default methods, which allow methods in interfaces to have a default implementation. Classes that implement the interface can use these methods without overriding them. - -#### Example: - -```java -interface Animal { - void sound(); - - default void eat() { - System.out.println("This animal is eating"); - } -} - -class Dog implements Animal { - public void sound() { - System.out.println("The dog barks"); - } -} - -public class Main { - public static void main(String[] args) { - Dog myDog = new Dog(); - myDog.sound(); - myDog.eat(); // Calls the default method - } -} -``` - -#### Output: - -``` -The dog barks -This animal is eating -``` - ---- - -## 6. Static Methods in Interfaces - -Java interfaces can also have static methods. These methods can be called without creating an instance of the interface. - -#### Example: - -```java -interface Animal { - static void info() { - System.out.println("Animals are living beings"); - } -} - -public class Main { - public static void main(String[] args) { - Animal.info(); // Calls the static method - } -} -``` - -#### Output: - -``` -Animals are living beings -``` - ---- - -## 7. Extending Interfaces - -An interface can extend another interface, allowing it to inherit the abstract methods of the parent interface. - -#### Example: - -```java -interface Animal { - void sound(); -} - -interface Mammal extends Animal { - void run(); -} - -class Dog implements Mammal { - public void sound() { - System.out.println("The dog barks"); - } - - public void run() { - System.out.println("The dog runs fast"); - } -} - -public class Main { - public static void main(String[] args) { - Dog myDog = new Dog(); - myDog.sound(); - myDog.run(); - } -} -``` - -#### Output: - -``` -The dog barks -The dog runs fast -``` - ---- - -## 8. Final Thoughts - -Interfaces are a crucial part of Java's approach to achieving abstraction and multiple inheritance. They provide a flexible way to define the behaviors that different classes must implement. By using interfaces, you can create more modular and extensible applications. - -Happy coding! diff --git a/docs/languages/javascript/_category_.json b/docs/languages/javascript/_category_.json deleted file mode 100644 index a9f6b8fa2..000000000 --- a/docs/languages/javascript/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "JavaScript", - "position": 1, - "link": { - "type": "generated-index", - "description": "JavaScript is a programming language that conforms to the ECMAScript specification. JavaScript is high-level, often just-in-time compiled, and multi-paradigm." - } - } \ No newline at end of file diff --git a/docs/languages/javascript/js-0.md b/docs/languages/javascript/js-0.md deleted file mode 100644 index c090be685..000000000 --- a/docs/languages/javascript/js-0.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: introduction-to-javascript -sidebar_position: 1 -title: Introduction to JavaScript -sidebar_label: JavaScript Introduction ---- - -Hey, everyone! In this guide, we'll take a journey into **JavaScript**, one of the most popular programming languages used for web development. JavaScript allows you to create interactive, dynamic, and feature-rich web applications. Let's dive into the basics! - - - -## 1. What is JavaScript? - -JavaScript, often abbreviated as **JS**, is a high-level, dynamic, and versatile programming language used primarily for web development. It allows developers to create interactive web pages, handle user events, and manipulate the Document Object Model (DOM). - -### Key Features of JavaScript: - -- **Client-side scripting**: Runs directly in the browser, enabling dynamic content. -- **Interactivity**: Handles user interactions, such as clicks, form submissions, and animations. -- **Cross-platform**: Compatible with all major web browsers. -- **Event-driven**: Reacts to user inputs and events like clicks, hovers, or keypresses. - -:::tip Fun Fact -JavaScript was created in just **10 days** by Brendan Eich in 1995, and despite its rushed creation, it has grown to become the most widely-used language on the web! -::: - - - -## 2. How Does JavaScript Work? - -JavaScript runs in the web browser. When a web page loads, the browser's JavaScript engine interprets and executes the script to make the page interactive. - -### JavaScript Workflow - -```mermaid -graph LR - A[User Requests Web Page] -->|HTML, CSS, JS Sent| B[Browser Receives Files] - B -->|JS Engine Executes Script| C[Interactive Web Page] - C -->|User Interacts| D[JavaScript Handles Event] - D -->|Manipulates| E[DOM Updates] -``` - - -## 3. JavaScript in Action: Example -Here’s an example of how JavaScript can enhance a web page by responding to user input and dynamically updating the content. - - -```html - - - - Simple JS Example - - -

    Welcome!

    - - - - - -``` -What happens here? -HTML: Provides the structure (a heading and a button). -JavaScript: Adds interactivity. When the button is clicked, the heading's text is changed to "Hello, JavaScript!". - - - -## 4. Where is JavaScript Used? -JavaScript is everywhere! From simple web pages to complex applications, here are some areas where it's commonly used: - -4.1. Front-End Web Development -JavaScript brings static HTML pages to life by enabling interaction. Popular JavaScript frameworks like React, Vue, and Angular have revolutionized the way we build modern web applications. - -4.2. Back-End Web Development -JavaScript is not limited to the browser. With Node.js, you can run JavaScript on servers, enabling you to build full-stack web applications using a single language! - -4.3. Mobile and Desktop Apps -Frameworks like React Native (for mobile) and Electron (for desktop) allow developers to build apps for multiple platforms using JavaScript. - -4.4. Game Development -Using libraries like Phaser and Three.js, JavaScript can even be used to create 2D and 3D games that run directly in the browser. - -## 5. Adding JavaScript to Your Web Page - -To include JavaScript in a web page, you can embed it directly within the HTML using the tag. - -### 5.1. Inline JavaScript -You can add JavaScript code directly inside your HTML: - -```html - -``` - -### 5.2. External JavaScript -For larger projects, it's better to keep your JavaScript in a separate file: -```html - -``` - -### 5.3. Best Practice - -- **Separation of Concerns**: Keep your HTML, CSS, and JavaScript separate for better organization. -- **Asynchronous Loading**: Use the `defer` attribute to load scripts asynchronously without blocking the page rendering. - -```html - -``` - -## 6. Conclusion - -JavaScript is a powerful language that drives the interactivity of the web. By learning JavaScript, you can create dynamic web applications, interactive games, and much more. Stay tuned for more JavaScript guides and tutorials! \ No newline at end of file diff --git a/docs/languages/javascript/js-1.md b/docs/languages/javascript/js-1.md deleted file mode 100644 index 02ff30a26..000000000 --- a/docs/languages/javascript/js-1.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -id: variables-in-javascript -sidebar_position: 1 -title: Variables in JavaScript -sidebar_label: Variables in JS ---- - -Hey, everyone! In this guide, we'll explore the concept of variables in JavaScript. Variables are essential in programming, allowing you to store and manipulate data dynamically. Let's dive in! - - - -## 1. What are Variables? - -In the world of programming, variables act as containers. Think of them like labeled boxes that hold various types of information in your program. These containers allow you to store, retrieve, and manipulate data, providing the foundation for dynamic and interactive code. - -### Visualizing Variables - -```mermaid -graph TD - subgraph Variables - style Variables fill:#f57,stroke:#333,stroke-width:2px, stroke:#262626; - A(Variable) - end - - B["Data Type (e.g., Number, String)"] - C["Variable Name (e.g., age, name)"] - - A -->|Stores| B - A -->|Named| C - - B -->|Assigned Value| D["Value (e.g., 25, 'John')"] - C -->|Used in Code| E["Code (e.g., age = 25; console.log(name);)"] -``` - -In JavaScript, we use variables to store and manage data, representing numbers, text, or more complex structures. - -```mermaid -graph TD - subgraph Variables - style Variables fill:#f9f,stroke:#333,stroke-width:2px; - A[Variable] - end - - BoxStyle(e.g., var, let, const) - style BoxStyle fill:#fff,stroke:#333,stroke-width:2px; - - B["Number"] - C["String"] - D["Boolean"] - E["Array"] - F["Object"] - - A -->|=| B["10"] - A -->|=| C["'Hello, World!'"] - A -->|=| D["true"] - A -->|=| E["[1, 2, 3]"] - A -->|=| F["{ key: 'value', age: 25 }"] -``` - - - -:::tip Definition -In JavaScript, variables are containers that hold information, allowing you to reference and manipulate values within your code. Variables are fundamental to programming, enabling you to work with data dynamically. - -In programming, variables are used to store and manage data. They act as symbolic names for values. In JavaScript, you can declare variables using the `var`, `let`, or `const` keywords. - -1. `var`: - - - Historically used for variable declaration, but it has some scoping issues. - - Variables declared with `var` are function-scoped, meaning they are only accessible within the function where they are declared. - -2. `let`: - - - Introduced in ECMAScript 6 (ES6) to address the scoping issues of `var`. - - `let` allows block-scoping, meaning the variable is limited to the block (enclosed by curly braces) where it is defined. - -3. `const`: - - - Also introduced in ES6, `const` is used to declare constants. - - Constants cannot be reassigned after declaration. - - They are block-scoped like variables declared with let. -::: - - - -## 2. Variable Declaration and Types - -Now, let's explore how to declare variables and the different types available in JavaScript. - -### Variable Declaration - -```mermaid -graph TD - subgraph Variables - style Variables fill:#f9f,stroke:#333,stroke-width:2px; - A[let age = 18;] - end - - B["if (age >= 18) {"] - C[" console.log('You are an adult.');"] - D["} else {"] - E[" console.log('You are a minor.');"] - - A -->|Variable Declaration| B - B -->|Condition Check| C - B -->|Alternative Path| D - D -->|Alternative Output| E -``` - -In JavaScript, you can declare variables using 'var,' 'let,' or 'const.' While 'var' has been around for a while, ES6 introduced 'let' and 'const.' - -**Comparison of 'var,' 'let,' and 'const':** - -```javascript -// Using var (function-scoped) -var x = 10; - -// Using let (block-scoped, reassignable) -let y = 'Hello'; - -// Using const (block-scoped, not reassignable) -const pi = 3.14; -``` - -### Variable Assignment and Dynamic Typing - -Once a variable is declared, you can assign values to it. JavaScript's dynamic typing allows the type of a variable to change during runtime. - -**Example of Variable Assignment and Dynamic Typing:** - - - -This flexibility is powerful, but it's crucial to be aware of the data types your variables hold to avoid unexpected behavior. - - - -## 3. Scope and Hoisting - -Understanding the scope of variables is crucial for writing robust and error-free code. JavaScript has function-scoped variables with 'var' and block-scoped variables with 'let' and 'const.' - -### Scope - -Scope defines the context in which variables are accessible. Let's explore function and block scope. - -```javascript -function exampleScope() { - if (true) { - var localVar = "I'm accessible inside the function"; - let blockVar = "I'm accessible only in this block"; - } - console.log(localVar); // Accessible - console.log(blockVar); // Error: blockVar is not defined -} -``` - -### Hoisting - -Variable and function declarations are hoisted to the top of their containing scope during compilation. - -```javascript -console.log(hoistedVar); // Outputs undefined -var hoistedVar = "I am hoisted!"; -``` - -## 4. Save Code - -To organize and reuse code effectively, consider saving reusable portions as functions or modules. This approach promotes maintainability and helps avoid redundancy. - -```javascript -// Example function -function greet(name) { - return `Hello, ${name}!`; -} - -// Using the function -let message = greet("Algo"); -console.log(message); // Outputs: Hello, Algo! -``` - - - -## 5. Best Practices - -Before we wrap up, let's discuss some best practices for working with variables in JavaScript. - -### Use `const` by Default - -In modern JavaScript, it's recommended to use `const` by default. If you know the value will change, then use `let`. - -```js -const maxAttempts = 3; -let currentAttempts = 0; -``` - -### Avoid `var - -The `var` keyword is outdated and can lead to unexpected issues. Prefer `let` and `const` for better-scoped variables. - -```js -var oldWay = "I'm using var."; - -let modernWay = "I'm using let."; -``` - -***Congratulations! You've now gained a comprehensive understanding of variables in JavaScript.*** \ No newline at end of file diff --git a/docs/languages/javascript/js-10.md b/docs/languages/javascript/js-10.md deleted file mode 100644 index 229509285..000000000 --- a/docs/languages/javascript/js-10.md +++ /dev/null @@ -1,243 +0,0 @@ ---- -id: objects-in-javascript -sidebar_position: 10 -title: "Objects In JavaScript" -sidebar_label: "Objects In JavaScript" ---- - -Hey there! In this guide, we'll explore how to work with objects in JavaScript. Objects are collections of properties, and they play a crucial role in JavaScript programming. Let’s dive into it! - - - -## 1. Creating an Object - -In JavaScript, objects can be created using object literals or constructors. - -### 1.1 Using Object Literals - -This is the most straightforward way to create an object in JavaScript. - -**Example:** - -```javascript -const person = { - firstName: "John", - lastName: "Doe", - age: 30, - greet: function () { - console.log("Hello, " + this.firstName); - }, -}; - -console.log(person.firstName); // Output: John -person.greet(); // Output: Hello, John -``` - - - -### 1.2 Using the `new Object()` Syntax - -Another way to create an object is by using the `new Object()` syntax. - -**Example:** - -```javascript -const person = new Object(); -person.firstName = "Jane"; -person.lastName = "Doe"; -person.age = 25; - -console.log(person.firstName); // Output: Jane -``` - -## 2. Accessing Object Properties - -You can access object properties using either dot notation or bracket notation. - -### 2.1 Dot Notation - -**Example:** - -```javascript -const car = { - make: "Toyota", - model: "Camry", - year: 2020, -}; - -console.log(car.make); // Output: Toyota -``` - -### 2.2 Bracket Notation - -**Example:** - -```javascript -const car = { - make: "Toyota", - model: "Camry", - year: 2020, -}; - -console.log(car["model"]); // Output: Camry -``` - - - -## 3. Modifying Object Properties - -You can modify object properties by assigning a new value to them. - -**Example:** - -```javascript -const book = { - title: "The Great Gatsby", - author: "F. Scott Fitzgerald", - year: 1925, -}; - -book.year = 1926; // Modify the year -console.log(book.year); // Output: 1926 -``` - -## 4. Adding and Deleting Properties - -### 4.1 Adding Properties - -You can add properties to an existing object at any time. - -**Example:** - -```javascript -const student = { - name: "Alice", -}; - -student.age = 22; // Adding a new property -console.log(student.age); // Output: 22 -``` - - - -### 4.2 Deleting Properties - -You can delete a property using the `delete` operator. - -**Example:** - -```javascript -const student = { - name: "Alice", - age: 22, -}; - -delete student.age; // Delete the age property -console.log(student.age); // Output: undefined -``` - - - -## 5. Methods in Objects - -Object methods are functions stored as object properties. - -**Example:** - -```javascript -const person = { - firstName: "John", - lastName: "Doe", - fullName: function () { - return this.firstName + " " + this.lastName; - }, -}; - -console.log(person.fullName()); // Output: John Doe -``` - ---- - -## 6. Looping Through Object Properties - -You can loop through the properties of an object using a `for...in` loop. - -**Example:** - -```javascript -const car = { - make: "Toyota", - model: "Camry", - year: 2020, -}; - -for (let key in car) { - console.log(key + ": " + car[key]); -} -``` - -#### Output: - -``` -make: Toyota -model: Camry -year: 2020 -``` - - - -## 7. Nested Objects - -Objects can contain other objects as properties. - -**Example:** - -```javascript -const employee = { - name: "John", - position: "Developer", - contact: { - email: "john@example.com", - phone: "123-456-7890", - }, -}; - -console.log(employee.contact.email); // Output: john@example.com -``` - -## 8. Checking for Properties - -You can check if an object has a specific property using the `in` operator or `hasOwnProperty()` method. - -**Example:** - -```javascript -const car = { - make: "Toyota", - model: "Camry", -}; - -console.log("make" in car); // Output: true -console.log(car.hasOwnProperty("model")); // Output: true -``` - -## 9. Object Destructuring - -Object destructuring allows you to unpack properties from an object into variables. - -**Example:** - -```javascript -const user = { - name: "John", - age: 30, -}; - -const { name, age } = user; -console.log(name); // Output: John -console.log(age); // Output: 30 -``` - - - -Objects are the backbone of JavaScript, allowing you to model real-world entities and organize your code more effectively. Understanding how to use objects will significantly enhance your JavaScript skills. \ No newline at end of file diff --git a/docs/languages/javascript/js-11.md b/docs/languages/javascript/js-11.md deleted file mode 100644 index c136c9202..000000000 --- a/docs/languages/javascript/js-11.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: closures-in-javascript -sidebar_position: 11 -title: Closures in JavaScript -sidebar_label: Closures in JavaScript ---- - -Closures are a fundamental concept in JavaScript, enabling functions to retain access to variables from their outer scope even after the outer function has finished execution. This behavior is crucial in many advanced JavaScript patterns like callbacks, event handlers, and function factories. - - - -## What is a Closure? - -A **closure** is created when a function is defined inside another function and that inner function has access to the outer function's variables. The inner function "remembers" the environment in which it was created, even after the outer function has returned. - -## Key Concepts: -1. **Lexical Scope**: Functions can access variables from their parent scope. -2. **Retention of Variables**: Inner functions retain access to variables in the outer function, even after the outer function has completed. - -## Example: Basic Closure - -```javascript -function outer() { - let count = 0; // outer function variable - return function inner() { // inner function - count++; // modifying the outer variable - console.log(count); - }; -} - -const counter = outer(); -counter(); // Output: 1 -counter(); // Output: 2 -``` - -In this example, the inner function inner retains access to the variable count from the outer function outer, even after outer has returned. - - - -## Real-World Use Cases: -- Private Variables: Encapsulating data and exposing only what’s necessary. -- Callback Functions: Retaining state within event handlers or asynchronous operations. -- Function Factories: Creating customized functions. - -## Example: Closure for Private Variables - -```javascript -function createCounter() { - let count = 0; // private variable - return { - increment: function() { - count++; - console.log(count); - }, - reset: function() { - count = 0; - console.log("Counter reset"); - } - }; -} - -const myCounter = createCounter(); -myCounter.increment(); // Output: 1 -myCounter.increment(); // Output: 2 -myCounter.reset(); // Output: Counter reset -``` - -In this example, count remains private to the createCounter function but can be manipulated through the increment and reset methods. - -## Benefits of Closures: - -1. **Encapsulation**: Hiding implementation details and exposing an interface. -2. **Data Privacy**: Protecting variables from external modification. -3. **State Retention**: Preserving state across function calls. -4. **Customization**: Creating specialized functions with shared state. -5. **Memory Efficiency**: Sharing common variables across multiple function calls. -6. **Callback Handling**: Managing asynchronous operations and event listeners. -7. **Function Factories**: Generating functions with pre-configured settings. -8. **Currying**: Partially applying functions for reusability. -9. **Memoization**: Caching results for performance optimization. - -Closures are a powerful feature in JavaScript that enables developers to write more expressive and efficient code. Understanding closures is essential for mastering advanced JavaScript concepts and patterns. \ No newline at end of file diff --git a/docs/languages/javascript/js-12.md b/docs/languages/javascript/js-12.md deleted file mode 100644 index 68881c1fb..000000000 --- a/docs/languages/javascript/js-12.md +++ /dev/null @@ -1,261 +0,0 @@ ---- -id: inheritance-in-javascript -sidebar_position: 12 -title: "Inheritance in JavaScript" -sidebar_label: "Inheritance In JavaScript" ---- - -Hello! In this guide, we'll explore how inheritance works in JavaScript. Inheritance is a core concept in object-oriented programming (OOP) and allows one class to inherit properties and methods from another. JavaScript, being a prototype-based language, implements inheritance through prototypes. Let’s dive in! - - - -## 1. Prototypal Inheritance - -JavaScript objects have a special hidden property called `[[Prototype]]`, which is either `null` or references another object. This object is referred to as the prototype. When trying to access a property on an object, JavaScript will first look for it on the object itself. If it's not found, it will look for the property in the prototype chain. - -**Example:** - -```javascript -let animal = { - eats: true, -}; - -let rabbit = { - jumps: true, -}; - -rabbit.__proto__ = animal; // Set animal as the prototype of rabbit - -console.log(rabbit.eats); // true (inherited from animal) -console.log(rabbit.jumps); // true (own property) -``` - -#### Output: - -``` -true -true -``` - ---- - -## 2. Using `Object.create()` - -The `Object.create()` method creates a new object with the specified prototype object and properties. - -#### Example: - -```javascript -let animal = { - eats: true, -}; - -let rabbit = Object.create(animal); -rabbit.jumps = true; - -console.log(rabbit.eats); // true (inherited from animal) -console.log(rabbit.jumps); // true (own property) -``` - -#### Output: - -``` -true -true -``` - ---- - -## 3. ES6 Classes and Inheritance - -In ES6, JavaScript introduced the `class` syntax, which is a more convenient way to work with inheritance. - -### 3.1 Defining Classes - -Classes are defined using the `class` keyword, and inheritance is established using the `extends` keyword. - -#### Example: - -```javascript -class Animal { - constructor(name) { - this.name = name; - } - - speak() { - console.log(`${this.name} makes a noise.`); - } -} - -class Dog extends Animal { - speak() { - console.log(`${this.name} barks.`); - } -} - -let dog = new Dog("Rex"); -dog.speak(); // Rex barks. -``` - -#### Output: - -``` -Rex barks. -``` - ---- - -### 3.2 Super Keyword - -The `super` keyword is used to call the constructor or methods of the parent class. - -#### Example: - -```javascript -class Animal { - constructor(name) { - this.name = name; - } - - speak() { - console.log(`${this.name} makes a noise.`); - } -} - -class Dog extends Animal { - constructor(name, breed) { - super(name); // Call parent constructor - this.breed = breed; - } - - speak() { - super.speak(); // Call parent method - console.log(`${this.name} barks.`); - } -} - -let dog = new Dog("Rex", "Labrador"); -dog.speak(); -``` - -#### Output: - -``` -Rex makes a noise. -Rex barks. -``` - ---- - -## 4. Checking Inheritance - -You can check if an object inherits from another object using the `instanceof` operator or the `isPrototypeOf()` method. - -### 4.1 Using `instanceof` - -The `instanceof` operator checks if an object is an instance of a class. - -#### Example: - -```javascript -class Animal {} -class Dog extends Animal {} - -let dog = new Dog(); - -console.log(dog instanceof Dog); // true -console.log(dog instanceof Animal); // true -console.log(dog instanceof Object); // true -``` - -#### Output: - -``` -true -true -true -``` - ---- - -### 4.2 Using `isPrototypeOf()` - -The `isPrototypeOf()` method checks if an object exists in another object's prototype chain. - -#### Example: - -```javascript -let animal = {}; -let rabbit = Object.create(animal); - -console.log(animal.isPrototypeOf(rabbit)); // true -``` - -#### Output: - -``` -true -``` - ---- - -## 5. Overriding Methods - -In JavaScript, a subclass can override the methods of its superclass. This is often done to provide specialized behavior. - -#### Example: - -```javascript -class Animal { - speak() { - console.log("Animal speaks"); - } -} - -class Dog extends Animal { - speak() { - console.log("Dog barks"); - } -} - -let dog = new Dog(); -dog.speak(); // Dog barks (method overridden) -``` - -#### Output: - -``` -Dog barks -``` - ---- - -## 6. Static Methods and Properties - -JavaScript classes can also have static methods and properties, which are called on the class itself, not on instances. - -#### Example: - -```javascript -class Animal { - static category = "Mammal"; - - static info() { - console.log("Animals are multicellular organisms."); - } -} - -console.log(Animal.category); // Mammal -Animal.info(); // Animals are multicellular organisms. -``` - -#### Output: - -``` -Mammal -Animals are multicellular organisms. -``` - ---- - -JavaScript inheritance, through prototypes or the `class` syntax, allows for powerful code reuse and logical organization. By mastering inheritance, you can create more flexible and efficient code. Happy coding! diff --git a/docs/languages/javascript/js-13.md b/docs/languages/javascript/js-13.md deleted file mode 100644 index 74083dedf..000000000 --- a/docs/languages/javascript/js-13.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -id: modules-in-javascript -sidebar_position: 13 -title: "Modules in JavaScript" -sidebar_label: "Modules In JavaScript" ---- - -# Modules in JavaScript - -Hello! In this guide, we’ll explore how modules work in JavaScript. Modules are an essential part of modern JavaScript development, allowing developers to break code into reusable pieces and manage dependencies. Let’s get started! - ---- - -## 1. What Are Modules? - -Modules in JavaScript are reusable blocks of code, encapsulated within their own scope. They allow developers to divide the code into smaller, manageable files and export functionality from one module to be used in other modules. - ---- - -## 2. Exporting and Importing Modules - -### 2.1 Exporting - -There are two types of exports in JavaScript modules: - -#### Named Exports - -You can export multiple things from a module using named exports. - -#### Example: - -```javascript -// math.js -export function add(x, y) { - return x + y; -} - -export function subtract(x, y) { - return x - y; -} -``` - -#### Exporting an Object: - -```javascript -// utility.js -const utilities = { - greet: function (name) { - return `Hello, ${name}`; - }, - farewell: function (name) { - return `Goodbye, ${name}`; - }, -}; - -export { utilities }; -``` - -#### Default Export - -You can export a single value, class, or function as the default export from a module. - -#### Example: - -```javascript -// logger.js -export default function log(message) { - console.log(message); -} -``` - ---- - -### 2.2 Importing - -To use exported functions, variables, or classes from a module, you can import them using the `import` statement. - -#### Example: - -```javascript -// main.js -import { add, subtract } from "./math.js"; - -console.log(add(2, 3)); // 5 -console.log(subtract(5, 3)); // 2 -``` - -#### Importing Default Export: - -```javascript -// main.js -import log from "./logger.js"; - -log("This is a log message."); // This is a log message. -``` - -#### Importing Everything from a Module: - -You can import all named exports at once using the `*` syntax. - -#### Example: - -```javascript -// main.js -import * as math from "./math.js"; - -console.log(math.add(2, 3)); // 5 -console.log(math.subtract(5, 3)); // 2 -``` - ---- - -## 3. Dynamic Imports - -Dynamic imports allow you to load modules dynamically as needed using the `import()` function. - -#### Example: - -```javascript -// main.js -import("./math.js").then((math) => { - console.log(math.add(2, 3)); // 5 -}); -``` - ---- - -## 4. Benefits of Using Modules - -- **Encapsulation:** Code is kept in separate files, reducing global scope pollution. -- **Reusability:** Modules can be reused across different projects. -- **Maintainability:** Dividing code into modules makes it easier to maintain and scale. -- **Lazy Loading:** Using dynamic imports, modules can be loaded on demand, improving performance. - ---- - -## 5. CommonJS vs ES Modules - -Before the introduction of ES Modules (ECMAScript modules), JavaScript relied on CommonJS for modularity in Node.js. - -### 5.1 CommonJS - -CommonJS modules use `require()` to import and `module.exports` to export. - -#### Example: - -```javascript -// math.js (CommonJS) -function add(x, y) { - return x + y; -} - -module.exports = { add }; -``` - -#### Importing in CommonJS: - -```javascript -// main.js -const { add } = require("./math.js"); - -console.log(add(2, 3)); // 5 -``` - -### 5.2 ES Modules - -ES Modules use `import` and `export` statements, and they work in both browser and Node.js environments (with Node.js 12+). - ---- - -JavaScript modules make your code cleaner, more maintainable, and reusable. Whether you're using CommonJS or ES Modules, understanding how to work with modules is key to modern JavaScript development. Happy coding! diff --git a/docs/languages/javascript/js-14.md b/docs/languages/javascript/js-14.md deleted file mode 100644 index 4a5e66d6e..000000000 --- a/docs/languages/javascript/js-14.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -id: promises-in-javascript -sidebar_position: 14 -title: "Promises in JavaScript" -sidebar_label: "Promises In JavaScript" ---- - -# Promises in JavaScript - -Hello! In this guide, we’ll explore how **Promises** work in JavaScript. Promises are used to handle asynchronous operations and are an essential part of modern JavaScript programming. Let's dive in! - ---- - -## 1. What is a Promise? - -A Promise in JavaScript is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises can be in one of three states: - -- **Pending:** The initial state, neither fulfilled nor rejected. -- **Fulfilled:** The operation completed successfully. -- **Rejected:** The operation failed. - ---- - -## 2. Creating a Promise - -A Promise is created using the `new Promise()` constructor, which takes a function (known as the executor) that contains two callback functions: `resolve` and `reject`. - -#### Example: - -```javascript -let promise = new Promise(function (resolve, reject) { - // some async operation - let success = true; - - if (success) { - resolve("Operation successful!"); - } else { - reject("Operation failed!"); - } -}); -``` - -In this example, the Promise will call `resolve` if the operation succeeds and `reject` if it fails. - ---- - -## 3. Consuming a Promise - -Once a Promise is created, you can use `.then()`, `.catch()`, and `.finally()` to handle its result. - -### 3.1 `.then()` - -The `.then()` method is used to handle a fulfilled Promise. - -#### Example: - -```javascript -promise.then(function (result) { - console.log(result); // "Operation successful!" -}); -``` - -### 3.2 `.catch()` - -The `.catch()` method is used to handle a rejected Promise. - -#### Example: - -```javascript -promise.catch(function (error) { - console.log(error); // "Operation failed!" -}); -``` - -### 3.3 `.finally()` - -The `.finally()` method is executed once the Promise is settled (either fulfilled or rejected), regardless of the outcome. - -#### Example: - -```javascript -promise.finally(function () { - console.log("Promise is settled."); -}); -``` - ---- - -## 4. Chaining Promises - -You can chain multiple `.then()` calls together. Each `.then()` receives the result of the previous `.then()`. - -#### Example: - -```javascript -let promise = new Promise(function (resolve, reject) { - resolve(10); -}); - -promise - .then(function (result) { - return result * 2; - }) - .then(function (result) { - return result + 5; - }) - .then(function (result) { - console.log(result); // 25 - }); -``` - ---- - -## 5. Promise Methods - -JavaScript provides several built-in methods to work with multiple Promises. - -### 5.1 `Promise.all()` - -The `Promise.all()` method takes an array of Promises and returns a new Promise that resolves when all the input Promises resolve, or rejects if any of the Promises reject. - -#### Example: - -```javascript -let promise1 = Promise.resolve(5); -let promise2 = Promise.resolve(10); - -Promise.all([promise1, promise2]).then(function (results) { - console.log(results); // [5, 10] -}); -``` - -### 5.2 `Promise.race()` - -The `Promise.race()` method returns a Promise that resolves or rejects as soon as one of the input Promises resolves or rejects. - -#### Example: - -```javascript -let promise1 = new Promise(function (resolve) { - setTimeout(() => resolve("First Promise"), 500); -}); - -let promise2 = new Promise(function (resolve) { - setTimeout(() => resolve("Second Promise"), 100); -}); - -Promise.race([promise1, promise2]).then(function (result) { - console.log(result); // "Second Promise" -}); -``` - -### 5.3 `Promise.allSettled()` - -The `Promise.allSettled()` method returns a Promise that resolves when all of the input Promises settle (either fulfilled or rejected). - -#### Example: - -```javascript -let promise1 = Promise.resolve(10); -let promise2 = Promise.reject("Error"); - -Promise.allSettled([promise1, promise2]).then(function (results) { - console.log(results); - // [ - // {status: "fulfilled", value: 10}, - // {status: "rejected", reason: "Error"} - // ] -}); -``` - ---- - -## 6. Async/Await - -The `async` and `await` keywords allow you to work with Promises in a more readable way, avoiding the need for chaining `.then()`. - -#### Example: - -```javascript -async function fetchData() { - try { - let result = await promise; - console.log(result); // "Operation successful!" - } catch (error) { - console.log(error); // "Operation failed!" - } -} - -fetchData(); -``` - ---- - -Promises are essential in managing asynchronous operations in JavaScript, whether you're handling API calls, timers, or other async tasks. By mastering Promises, you can write cleaner and more efficient asynchronous code. Happy coding! diff --git a/docs/languages/javascript/js-15.md b/docs/languages/javascript/js-15.md deleted file mode 100644 index fb00d193e..000000000 --- a/docs/languages/javascript/js-15.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -id: async-await-in-javascript -sidebar_position: 15 -title: "Async/Await in JavaScript" -sidebar_label: "Async/Await In JavaScript" ---- - -# Async/Await in JavaScript - -Hello! In this guide, we’ll explore how the `async` and `await` keywords work in JavaScript. These features make it easier to work with Promises and asynchronous code. Let’s dive into the details! - ---- - -## 1. What is `async`/`await`? - -`async` and `await` are syntactic sugar built on top of Promises. They make asynchronous code look and behave like synchronous code, improving readability and maintainability. - -### 1.1 `async` Keyword - -The `async` keyword is used to define an asynchronous function. An `async` function always returns a Promise. - -#### Example: - -```javascript -async function fetchData() { - return "Data fetched!"; -} - -fetchData().then((result) => console.log(result)); // Data fetched! -``` - -### 1.2 `await` Keyword - -The `await` keyword can only be used inside an `async` function. It pauses the execution of the function until the Promise resolves. - -#### Example: - -```javascript -async function fetchData() { - let result = await Promise.resolve("Data fetched!"); - console.log(result); // Data fetched! -} - -fetchData(); -``` - ---- - -## 2. Error Handling with `try`/`catch` - -You can use `try`/`catch` blocks to handle errors in `async` functions, making it easier to manage rejected Promises. - -#### Example: - -```javascript -async function fetchData() { - try { - let result = await Promise.reject("Error occurred!"); - } catch (error) { - console.log(error); // Error occurred! - } -} - -fetchData(); -``` - ---- - -## 3. Using `await` with Multiple Promises - -You can use `await` to handle multiple Promises by awaiting each one sequentially, or you can use `Promise.all()` to await all Promises in parallel. - -### 3.1 Sequential Promise Handling - -#### Example: - -```javascript -async function fetchSequential() { - let result1 = await Promise.resolve("First result"); - let result2 = await Promise.resolve("Second result"); - - console.log(result1); // First result - console.log(result2); // Second result -} - -fetchSequential(); -``` - -### 3.2 Parallel Promise Handling with `Promise.all()` - -#### Example: - -```javascript -async function fetchParallel() { - let [result1, result2] = await Promise.all([ - Promise.resolve("First result"), - Promise.resolve("Second result"), - ]); - - console.log(result1); // First result - console.log(result2); // Second result -} - -fetchParallel(); -``` - ---- - -## 4. Async Functions Return Promises - -Even if an `async` function doesn’t explicitly return a Promise, it will still return one implicitly. - -#### Example: - -```javascript -async function fetchData() { - return "Data fetched!"; -} - -console.log(fetchData()); // Promise {: "Data fetched!"} -``` - ---- - -## 5. Handling Timeouts with `await` - -You can simulate a delay or timeout using `await` by combining it with `setTimeout()` wrapped in a Promise. - -#### Example: - -```javascript -function delay(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -async function fetchData() { - console.log("Fetching data..."); - await delay(2000); // Wait for 2 seconds - console.log("Data fetched!"); -} - -fetchData(); -``` - -#### Output: - -``` -Fetching data... -(Data is fetched after 2 seconds) -Data fetched! -``` - ---- - -## 6. Avoiding `await` Pitfalls - -Using `await` inside loops can cause performance issues if not used carefully. To avoid delays, use `Promise.all()` to run Promises in parallel when possible. - -#### Example of Sequential Delay (Not Recommended): - -```javascript -async function fetchItemsSequential() { - const items = [1, 2, 3]; - - for (let item of items) { - await delay(1000); - console.log(`Fetched item ${item}`); - } -} - -fetchItemsSequential(); -// Takes 3 seconds total, 1 second for each item. -``` - -#### Example of Parallel Execution (Recommended): - -```javascript -async function fetchItemsParallel() { - const items = [1, 2, 3]; - - await Promise.all( - items.map(async (item) => { - await delay(1000); - console.log(`Fetched item ${item}`); - }) - ); -} - -fetchItemsParallel(); -// Takes 1 second total, runs all fetches in parallel. -``` - ---- - -`async` and `await` make it easier to write and manage asynchronous JavaScript code. They provide a clean, readable alternative to Promises while still maintaining the same functionality. Mastering these features will help you handle async tasks like API calls, timeouts, and more efficiently. Happy coding! diff --git a/docs/languages/javascript/js-16.md b/docs/languages/javascript/js-16.md deleted file mode 100644 index 623da49ac..000000000 --- a/docs/languages/javascript/js-16.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -id: datetime-in-javascript -sidebar_position: 16 -title: "Date and Time in JavaScript" -sidebar_label: "Date and Time" ---- - -# Date and Time in JavaScript - -Working with date and time in JavaScript is essential for creating applications that involve scheduling, logging events, or simply displaying the current time. JavaScript provides the `Date` object for handling dates and times. This guide will cover how to use the `Date` object, including creating dates, formatting them, and performing date arithmetic. - ---- - -## 1. Creating a `Date` Object - -You can create a `Date` object using various methods: - -### 1.1 Creating a Date for the Current Time - -The simplest way to create a `Date` object is to call the constructor without arguments, which creates a date representing the current date and time. - -```javascript -let currentDate = new Date(); -console.log(currentDate); // Current date and time -``` - -### 1.2 Creating a Date with Specific Values - -You can also create a `Date` object by passing specific values for the year, month, day, hour, minute, second, and millisecond. - -```javascript -let specificDate = new Date(2024, 10, 3, 14, 30, 0); // November 3, 2024, 14:30:00 -console.log(specificDate); -``` - -> **Note**: Months are zero-based, meaning January is `0` and December is `11`. - -### 1.3 Creating a Date from a String - -You can also create a date by passing a date string: - -```javascript -let dateFromString = new Date("2024-11-03T14:30:00"); -console.log(dateFromString); // November 3, 2024, 14:30:00 -``` - -### 1.4 Creating a Date Using Timestamps - -The `Date` constructor can also take a timestamp (milliseconds since January 1, 1970, 00:00:00 UTC). - -```javascript -let dateFromTimestamp = new Date(1709591400000); -console.log(dateFromTimestamp); // Date corresponding to the given timestamp -``` - ---- - -## 2. Getting Date and Time Components - -You can extract different components of a `Date` object using various methods: - -```javascript -let currentDate = new Date(); - -console.log(currentDate.getFullYear()); // Year (e.g., 2024) -console.log(currentDate.getMonth()); // Month (0-11) -console.log(currentDate.getDate()); // Day of the month (1-31) -console.log(currentDate.getDay()); // Day of the week (0-6, where 0 is Sunday) -console.log(currentDate.getHours()); // Hours (0-23) -console.log(currentDate.getMinutes()); // Minutes (0-59) -console.log(currentDate.getSeconds()); // Seconds (0-59) -console.log(currentDate.getMilliseconds()); // Milliseconds (0-999) -``` - -> **Tip**: `getMonth()` returns a zero-based month, so you may need to add `1` for display purposes. - ---- - -## 3. Formatting Dates - -Formatting dates in JavaScript can be done manually or using libraries like `Intl.DateTimeFormat` for internationalization. - -### 3.1 Manual Formatting - -You can create custom date formats by combining the components: - -```javascript -let currentDate = new Date(); -let formattedDate = `${currentDate.getDate()}/${currentDate.getMonth() + 1}/${currentDate.getFullYear()}`; -console.log(formattedDate); // e.g., "3/11/2024" -``` - -### 3.2 Using `Intl.DateTimeFormat` - -The `Intl.DateTimeFormat` object provides an easy way to format dates: - -```javascript -let currentDate = new Date(); -let formatter = new Intl.DateTimeFormat("en-US", { dateStyle: "full", timeStyle: "short" }); -console.log(formatter.format(currentDate)); // e.g., "Sunday, November 3, 2024, 2:30 PM" -``` - -> **Options**: Customize the `dateStyle` and `timeStyle` for different formats (`"short"`, `"medium"`, `"long"`, `"full"`). - ---- - -## 4. Date Arithmetic - -You can perform arithmetic operations like adding or subtracting days, hours, or minutes. - -### 4.1 Adding Days - -```javascript -let currentDate = new Date(); -currentDate.setDate(currentDate.getDate() + 5); // Add 5 days -console.log(currentDate); -``` - -### 4.2 Subtracting Days - -```javascript -let currentDate = new Date(); -currentDate.setDate(currentDate.getDate() - 5); // Subtract 5 days -console.log(currentDate); -``` - -### 4.3 Calculating Time Differences - -You can calculate the difference between two dates in milliseconds and convert it to days or other units. - -```javascript -let date1 = new Date("2024-11-03"); -let date2 = new Date("2024-12-03"); - -let differenceInMs = date2 - date1; -let differenceInDays = differenceInMs / (1000 * 60 * 60 * 24); -console.log(differenceInDays); // Difference in days -``` - ---- - -## 5. Working with Time Zones - -JavaScript `Date` objects are based on the browser's local time zone. You can work with time zones using `toUTCString()` or libraries like `moment-timezone`. - -### 5.1 Converting to UTC - -```javascript -let currentDate = new Date(); -console.log(currentDate.toUTCString()); // Convert to UTC time -``` - -### 5.2 Getting the Time Zone Offset - -```javascript -let currentDate = new Date(); -console.log(currentDate.getTimezoneOffset()); // Time zone difference in minutes -``` - ---- - -## 6. Using Date Libraries - -Libraries like **Moment.js**, **date-fns**, and **Luxon** provide additional functionality and simplify date manipulation. - -### 6.1 Example Using `date-fns` - -```javascript -import { format, addDays } from "date-fns"; - -let currentDate = new Date(); -let newDate = addDays(currentDate, 5); // Add 5 days -console.log(format(newDate, "yyyy-MM-dd")); // Format date as "2024-11-08" -``` - ---- - -## 7. Common Pitfalls and Best Practices - -1. **Month Indexing**: Remember that months are zero-based, so always add `1` when displaying them. -2. **Time Zone Issues**: Be cautious when dealing with dates across different time zones. Use libraries for better handling. -3. **Immutable Operations**: `Date` methods like `setDate` modify the original `Date` object. Make a copy if you need to retain the original date. diff --git a/docs/languages/javascript/js-17.md b/docs/languages/javascript/js-17.md deleted file mode 100644 index 67a444d77..000000000 --- a/docs/languages/javascript/js-17.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -id: exception-handling-in-javascript -sidebar_position: 17 -title: "Exception Handling in JavaScript" -sidebar_label: "Exception Handling in JavaScript" ---- - - -# Exception Handling in JavaScript - -Exception handling is essential for writing robust JavaScript code that can handle errors gracefully, ensuring your application doesn’t crash unexpectedly. JavaScript provides the `try`, `catch`, `finally`, and `throw` constructs to manage exceptions effectively. - ---- - -## 1. What is Exception Handling? - -Exception handling in JavaScript allows you to manage and respond to runtime errors. Errors can occur for various reasons, such as network failures, invalid input, or unexpected behavior. Using exception handling, you can handle these errors gracefully and continue executing code or log necessary details for debugging. - ---- - -## 2. Using `try` and `catch` - -The `try` block contains code that might throw an error, and the `catch` block contains code to handle the error. - -### Syntax: - -```javascript -try { - // Code that might throw an error -} catch (error) { - // Code to handle the error -} -``` - -### Example: - -```javascript -try { - let result = riskyFunction(); - console.log(result); -} catch (error) { - console.log("An error occurred:", error.message); -} -``` - -In this example, if `riskyFunction()` throws an error, the `catch` block will log the error message. - ---- - -## 3. The `finally` Block - -The `finally` block contains code that will always execute, regardless of whether an error was thrown or not. It is typically used for cleanup operations, such as closing files or releasing resources. - -### Syntax: - -```javascript -try { - // Code that might throw an error -} catch (error) { - // Code to handle the error -} finally { - // Code that will always execute -} -``` - -### Example: - -```javascript -try { - let data = fetchData(); - console.log("Data fetched successfully:", data); -} catch (error) { - console.log("Failed to fetch data:", error.message); -} finally { - console.log("Cleanup operations complete."); -} -``` - -> **Note**: The `finally` block runs even if there’s a `return` statement in the `try` or `catch` block. - ---- - -## 4. Throwing Custom Errors with `throw` - -You can use the `throw` statement to create and throw custom errors. This is useful for validating data or handling specific error conditions. - -### Syntax: - -```javascript -throw new Error("Custom error message"); -``` - -### Example: - -```javascript -function validateAge(age) { - if (age < 18) { - throw new Error("Age must be 18 or older."); - } - return "Age is valid."; -} - -try { - console.log(validateAge(16)); // Throws an error -} catch (error) { - console.log("Validation error:", error.message); -} -``` - ---- - -## 5. Catching Specific Errors - -You can use the `instanceof` operator to differentiate between different types of errors and handle them appropriately. - -### Example: - -```javascript -try { - // Simulate a reference error - let result = nonExistentFunction(); -} catch (error) { - if (error instanceof ReferenceError) { - console.log("Reference error caught:", error.message); - } else if (error instanceof TypeError) { - console.log("Type error caught:", error.message); - } else { - console.log("An unexpected error occurred:", error.message); - } -} -``` - -This approach allows you to handle different types of errors in different ways. - ---- - -## 6. Nested `try`/`catch` Blocks - -You can nest `try`/`catch` blocks to handle errors at different levels of your application. - -### Example: - -```javascript -try { - try { - riskyOperation(); - } catch (error) { - console.log("Handled in inner catch:", error.message); - throw error; // Rethrow the error to the outer catch - } -} catch (error) { - console.log("Handled in outer catch:", error.message); -} -``` - ---- - -## 7. Using `catch` Without an `error` Parameter - -Since ES10 (ECMAScript 2019), you can omit the `error` parameter if you don’t need to use it. - -### Example: - -```javascript -try { - throw new Error("Something went wrong!"); -} catch { - console.log("Error caught without using the error object."); -} -``` - ---- - -## 8. Best Practices for Exception Handling - -1. **Use Specific Error Messages**: Throw errors with descriptive messages to make debugging easier. -2. **Avoid Swallowing Errors**: Make sure to log errors or handle them appropriately, instead of suppressing them silently. -3. **Handle Known Errors**: Use `instanceof` to handle known error types differently if needed. -4. **Graceful Degradation**: Use `try`/`catch` to allow your application to continue running even if an error occurs. -5. **Clean Up Resources**: Use the `finally` block for cleanup operations like closing database connections or releasing file handles. - ---- - -## 9. Common Use Cases for Exception Handling - -### 9.1 Handling Network Errors - -```javascript -async function fetchData(url) { - try { - let response = await fetch(url); - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); - } - let data = await response.json(); - console.log("Data fetched:", data); - } catch (error) { - console.log("Failed to fetch data:", error.message); - } -} - -fetchData("https://api.example.com/data"); -``` - -### 9.2 Validating User Input - -```javascript -function processUserInput(input) { - try { - if (input.trim() === "") { - throw new Error("Input cannot be empty."); - } - console.log("Processing input:", input); - } catch (error) { - console.log("Input error:", error.message); - } -} - -processUserInput(" "); // Input error: Input cannot be empty. -``` - ---- - -## 10. Summary - -- Use `try`/`catch` to handle runtime errors gracefully. -- Use `finally` for cleanup operations that should always run. -- Use `throw` to create custom errors for validation and control flow. -- Always ensure you provide meaningful error messages for easier debugging. - -Exception handling in JavaScript makes your code more robust and easier to maintain. Make sure to use it effectively to build resilient and user-friendly applications! - -Happy coding! \ No newline at end of file diff --git a/docs/languages/javascript/js-2.md b/docs/languages/javascript/js-2.md deleted file mode 100644 index 835ccab3f..000000000 --- a/docs/languages/javascript/js-2.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -id: datatype-in-javascript -sidebar_position: 2 -title: Data Type in JavaScript -sidebar_label: Data Type in JS ---- - -Data types are an essential concept in programming languages like JavaScript. They define the type of data that can be stored and manipulated in a program. Understanding data types is crucial for writing efficient and bug-free code. Let's explore the different data types in JavaScript: - - - -## 1. **Primitive Data Types:** - -These are the basic building blocks of data. - -### String: - -- A sequence of characters. -- Defined with single (' ') or double (" ") quotes. - -```javascript -let greeting = "Hello, World!"; -``` - -- Template Literals / Template strings - - - A special type of strings created using backticks(`) - - ```javascript - let info = `Know more about Template Literals`; - ``` - - - Allows multi-line strings - - ```javascript - let example = `This is an application - of template literals - in JavaScript `; - ``` - - - Allows string interpolation :- Template literals allow embedding variables and expressions directly into strings using '${}' - - ```javascript - let num = 7, - name = "Kim"; - let interpolatedString = `${name}'s lucky number is ${2 * num}`; - //Kim's lucky number is 14 - ``` - -### Number: - -- Represents both integers and floating-point numbers. -- No distinction between integers and floats. - -```javascript -let age = 25; -let price = 19.99; -``` - -### Boolean: - -- Represents either `true` or `false`. - -```javascript -let isStudent = true; -``` - -### Undefined: - -- Variable declared but not assigned. - -```javascript -let undefinedVar; -``` - -### Null: - -- Represents the intentional absence of any object value. - -```javascript -let nullVar = null; -``` - -### Symbol (ES6 and later): - -- Provides a unique value, often used as identifiers. - -```javascript -let id = Symbol("id"); -``` - -## 2. **Composite Data Types:** - -These are used to store collections of data. - -### Array: - -- Ordered list of values, accessed by index. - -```javascript -let colors = ["red", "green", "blue"]; -``` - -### Object: - -- Unordered collection of key-value pairs. - -```javascript -let person = { - name: "John", - age: 30, - isStudent: false, -}; -``` - - - -## 3. **Special Data Types:** - -### Function: - -- A reusable block of code. - -```javascript -function addNumbers(a, b) { - return a + b; -} -``` - -## 4. **Type Coercion:** - -- JavaScript automatically converts one data type to another when needed. - -```javascript -let numString = "10"; -let num = 5; - -console.log(numString + num); // "105" (string concatenation) -``` - -## 5. **Checking Data Types:** - -- Use `typeof` operator to check the data type of a variable. - -```javascript -let name = "John"; -console.log(typeof name); // "string" -``` - -Understanding these data types is crucial for effective programming in JavaScript. They help you organize and manipulate data in your applications. diff --git a/docs/languages/javascript/js-3.md b/docs/languages/javascript/js-3.md deleted file mode 100644 index e4e32d381..000000000 --- a/docs/languages/javascript/js-3.md +++ /dev/null @@ -1,344 +0,0 @@ ---- -id: operator-in-javascript -sidebar_position: 3 -title: Operator in JavaScript -sidebar_label: Operator in JS ---- - -Operators are symbols that perform operations on operands. JavaScript supports various types of operators, including arithmetic, assignment, comparison, logical, and more. Let's explore some common operators used in JavaScript: - - - -## 1. **Arithmetic Operators:** - -Arithmetic operators are used to perform mathematical calculations. - -### Addition (`+`): - -The addition operator is used to add two operands. - -```javascript -let sum = 10 + 5; // sum = 15 -``` - -### Subtraction (`-`): - -The subtraction operator is used to subtract the second operand from the first. - -```javascript -let difference = 20 - 8; // difference = 12 -``` - -### Multiplication (`*`): - -The multiplication operator is used to multiply two operands. - -```javascript -let product = 5 * 4; // product = 20 -``` - -### Division (`/`): - -The division operator is used to divide the first operand by the second. - -```javascript -let quotient = 50 / 10; // quotient = 5 -``` - -### Modulus (`%`): - -The modulus operator returns the remainder of the division operation. - -```javascript -let remainder = 15 % 4; // remainder = 3 -``` - - - -## 2. **Assignment Operators:** - -Assignment operators are used to assign values to variables. - -### Assignment (`=`): - -The assignment operator assigns the value on the right to the variable on the left. - -```javascript -let x = 10; // x = 10 -``` - -### Addition Assignment (`+=`): - -The addition assignment operator adds the value on the right to the variable's current value. - -```javascript -let y = 5; -y += 3; // y = 8 -``` - -### Subtraction Assignment (`-=`): - -The subtraction assignment operator subtracts the value on the right from the variable's current value. - -```javascript -let z = 10; -z -= 2; // z = 8 -``` - - - -## 3. **Comparison Operators:** - -Comparison operators are used to compare two values. - -### Equal (`==`): - -The equal operator checks if two values are equal. But it does not consider the data type. - -```javascript -let isEqual = 5 == '5'; // isEqual = true -``` - -### Strict Equal (`===`): - -The strict equal operator checks if two values are equal and of the same data type. - -```javascript -let isStrictEqual = 5 === '5'; // isStrictEqual = false -``` - -### Not Equal (`!=`): - -The not equal operator checks if two values are not equal. - -```javascript -let isNotEqual = 10 != 5; // isNotEqual = true -``` - -### Greater Than (`>`): - -The greater than operator checks if the left operand is greater than the right operand. - -```javascript -let isGreaterThan = 15 > 10; // isGreaterThan = true -``` - -### Less Than (`<`): - -The less than operator checks if the left operand is less than the right operand. - -```javascript -let isLessThan = 5 < 10; // isLessThan = true -``` - - - -## 4. **Logical Operators:** - -Logical operators are used to combine multiple conditions. - -### Logical AND (`&&`): - -The logical AND operator returns `true` if both conditions are `true`. - -```javascript -let condition1 = true; -let condition2 = false; - -let result = condition1 && condition2; // result = false -``` - -### Logical OR (`||`): - -The logical OR operator returns `true` if at least one condition is `true`. - -```javascript -let condition1 = true; -let condition2 = false; - -let result = condition1 || condition2; // result = true -``` - -### Logical NOT (`!`): - -The logical NOT operator returns the opposite of the condition. - -```javascript -let condition = true; - -let result = !condition; // result = false -``` - - - -## 5. **Ternary Operator:** - -The ternary operator is a shorthand for an `if...else` statement. - -```javascript -let age = 20; - -let message = age >= 18 ? 'You can vote' : 'You are too young to vote'; -``` - -## 6. **Typeof Operator:** - -The `typeof` operator is used to determine the data type of a variable. - -```javascript -let num = 10; -let str = 'Hello, World!'; - -console.log(typeof num); // number -console.log(typeof str); // string -``` - -## 7. **Increment and Decrement Operators:** - -Increment (`++`) and decrement (`--`) operators are used to increase or decrease the value of a variable by `1`. - -```javascript -let count = 5; - -count++; // count = 6 -count--; // count = 5 -``` - - - -## 8. **Bitwise Operators:** - -Bitwise operators perform operations on binary representations of numbers. - -### Bitwise AND (`&`): - -Performs a bitwise AND operation on two numbers. - -```javascript -let result = 5 & 3; // result = 1 -``` - -### Bitwise OR (`|`): - -Performs a bitwise OR operation on two numbers. - -```javascript -let result = 5 | 3; // result = 7 -``` - -### Bitwise XOR (`^`): - -Performs a bitwise XOR operation on two numbers. - -```javascript -let result = 5 ^ 3; // result = 6 -``` - -### Bitwise NOT (`~`): - -Performs a bitwise NOT operation on a number. - -```javascript -let result = ~5; // result = -6 -``` - -### Left Shift (`<<`): - -Shifts the bits of a number to the left. - -```javascript -let result = 5 << 1; // result = 10 -``` - -### Right Shift (`>>`): - -Shifts the bits of a number to the right. - -```javascript -let result = 5 >> 1; // result = 2 -``` - -### Zero-fill Right Shift (`>>>`): - -Shifts the bits of a number to the right, filling the leftmost bits with zeros. - -```javascript -let result = 5 >>> 1; // result = 2 -``` - - - -## 9. **Conditional Operator:** - -The conditional operator (`?:`) is a ternary operator that evaluates a condition and returns one of two values based on the result. - -```javascript -let age = 20; - -let message = age >= 18 ? 'You can vote' : 'You are too young to vote'; -``` - - - -## 10. **Comma Operator:** - -The comma operator allows multiple expressions to be evaluated in a single statement. - -```javascript -let x = 1, y = 2, z = 3; -``` - -## 11. **Void Operator:** - -The void operator evaluates an expression and returns `undefined`. - -```javascript -let result = void 0; // result = undefined -``` - -## 12. **Delete Operator:** - -The delete operator is used to delete an object's property. - -```javascript -let person = { - name: 'John', - age: 30 -}; - -delete person.age; // Removes the 'age' property -``` - -## 13. **In Operator:** - -The `in` operator checks if a property exists in an object. - -```javascript -let person = { - name: 'John', - age: 30 -}; - -let hasAge = 'age' in person; // hasAge = true -``` - -## 14. **Instanceof Operator:** - -The `instanceof` operator checks if an object is an instance of a specific class. - -```javascript -let date = new Date(); - -let isDate = date instanceof Date; // isDate = true -``` - - - -## More Resources: - -- [MDN Web Docs: Expressions and Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators) -- [JavaScript Operator Precedence Table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) -- [W3Schools: JavaScript Operators](https://www.w3schools.com/js/js_operators.asp) -- [JavaScript.info: Operators](https://javascript.info/operators) - -Operators are an essential part of JavaScript programming. Understanding how to use them effectively will help you write more efficient and concise code. Experiment with different operators to see how they work and how you can use them in your projects. \ No newline at end of file diff --git a/docs/languages/javascript/js-4.md b/docs/languages/javascript/js-4.md deleted file mode 100644 index a224c7080..000000000 --- a/docs/languages/javascript/js-4.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: decision-making-in-javascript -sidebar_position: 4 -title: Decision Making in JavaScript -sidebar_label: Decision Making in JavaScript ---- - -Hey everyone! Today, we're going to explore how decision-making works in JavaScript. Whether you're just starting or need a refresher, this guide will help you understand the key decision-making structures in JavaScript. Let's dive right in! - - - - -* JavaScript provides several decision-making structures that allow you to execute code based on certain conditions. - -* The most common decision-making statements are `if`, `if-else`, `else if`, and `switch` statements. - -## 1. If Statements - - -The simplest structure for decision-making is an `if` statement, which executes a block of code if the specified condition is true. -```javascript -let num = 10; // Define a variable 'num' with a value of 10 -if (num > 0) { // Check if 'num' is greater than 0 - console.log('The number is positive.'); // Print a message if the condition is true -} -``` - - - -## 2. If-Else Statements - - -The `if-else` statement allows you to execute an alternate block of code if the `if` condition evaluates to false. -```javascript -let num = 7; // Define a variable 'num' with a value of 7 -if (num % 2 === 0) { // Check if 'num' is even - console.log('The number is even.'); // Print a message if the number is even -} else { // If the condition is false, execute the 'else' block - console.log('The number is odd.'); // Print a message if the number is odd -} -``` -## 3. Else If Statements - - -The `else if` statement allows you to check multiple conditions and execute different blocks of code based on the first condition that is true. -```javascript -let num = 15; // Define a variable 'num' with a value of 15 -if (num > 20) { // Check if 'num' is greater than 20 - console.log('The number is greater than 20.'); // Print this message if the condition is true -} else if (num === 15) { // Check if 'num' is equal to 15 - console.log('The number is 15.'); // Print this message if 'num' is 15 -} else { // If none of the above conditions are true, execute the 'else' block - console.log('The number is less than 20.'); // Print this message if 'num' is less than 20 -} -``` -## 4. Switch Statements - - -The `switch` statement allows you to perform different actions based on different conditions. It's an alternative to using multiple `else if` statements. -```javascript -let day = 3; // Define a variable 'day' with a value of 3 -switch (day) { // Switch based on the value of 'day' - case 1: // Check if 'day' is equal to 1 - console.log('Monday'); // Print 'Monday' if 'day' is 1 - break; // Break out of the switch after this case - case 2: // Check if 'day' is equal to 2 - console.log('Tuesday'); // Print 'Tuesday' if 'day' is 2 - break; // Break out of the switch after this case - case 3: // Check if 'day' is equal to 3 - console.log('Wednesday'); // Print 'Wednesday' if 'day' is 3 - break; // Break out of the switch after this case - default: // If none of the cases match, execute the default block - console.log('Invalid day'); // Print 'Invalid day' if 'day' doesn't match any case -} -``` - - - -## 5. Ternary Operator - - -The ternary operator is a shorthand for the `if-else` statement and is commonly used for simple conditional expressions. -```javascript -let age = 18; // Define a variable 'age' with a value of 18 -let canVote = (age >= 18) ? 'Yes' : 'No'; // Use the ternary operator to check if 'age' is 18 or more -console.log(canVote); // Print 'Yes' if 'age' is 18 or more, otherwise print 'No' -``` diff --git a/docs/languages/javascript/js-5.md b/docs/languages/javascript/js-5.md deleted file mode 100644 index 1a48fc930..000000000 --- a/docs/languages/javascript/js-5.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -id: loops-in-javascript -sidebar_position: 5 -title: Loops in JavaScript -sidebar_label: Loops in JavaScript ---- - -Hey everyone! Today, we will explore loops in JavaScript, a key concept for automating repetitive tasks. Whether you're just starting or need a quick refresher, this guide will help you understand how loops work in JavaScript. Let's get started! - - - -* Loops allow you to execute a block of code repeatedly while a specified condition is true. - -* JavaScript provides several types of loops, such as `for`, `while`, and `do-while` loops. - -## 1. For Loop - -The `for` loop is the most commonly used loop in JavaScript. It repeats a block of code for a set number of times. -```javascript -for (let i = 0; i < 5; i++) { // Loop from 0 to 4 - console.log(i); // Print the current value of 'i' -} -``` - -## 2. For-In Loop - -The `for-in` loop is used to iterate over the properties of an object. -```javascript -let person = {name: 'John', age: 30}; // Object with 'name' and 'age' properties -for (let key in person) { // Iterate over each property in the 'person' object - console.log(key + ': ' + person[key]); // Print the property and its value -} -``` - - - -## 3. For-Of Loop - -The `for-of` loop is used to iterate over iterable objects like arrays or strings. -```javascript -let numbers = [1, 2, 3, 4, 5]; // Array of numbers -for (let num of numbers) { // Iterate over each number in the 'numbers' array - console.log(num); // Print the current number -} -``` - -## 4. While Loop - -The `while` loop executes a block of code as long as the specified condition is true. -```javascript -let count = 0; // Initialize 'count' to 0 -while (count < 5) { // Continue looping while 'count' is less than 5 - console.log(count); // Print the current value of 'count' - count++; // Increment 'count' by 1 -} -``` - - - -## 5. Do-While Loop - -The `do-while` loop is similar to the `while` loop but ensures the code is executed at least once before checking the condition. -```javascript -let count = 0; // Initialize 'count' to 0 -do { // Execute the loop body at least once - console.log(count); // Print the current value of 'count' - count++; // Increment 'count' by 1 -} while (count < 5); // Continue looping while 'count' is less than 5 -``` - -## 6. Break Statement - -The `break` statement is used to exit a loop prematurely. -```javascript -for (let i = 0; i < 10; i++) { // Loop from 0 to 9 - if (i === 5) { // Check if 'i' equals 5 - break; // Exit the loop when 'i' is 5 - } - console.log(i); // Print numbers from 0 to 4 -} -``` - -## 7. Continue Statement - -The `continue` statement skips the current iteration of the loop and moves to the next iteration. -```javascript -for (let i = 0; i < 5; i++) { // Loop from 0 to 4 - if (i === 3) { // Check if 'i' equals 3 - continue; // Skip the iteration when 'i' is 3 - } - console.log(i); // Print numbers except 3 -} -``` - -## 8. Nested Loops - -In JavaScript, you can use loops inside other loops. These are called nested loops and are useful for iterating over multi-dimensional arrays. -```javascript -for (let i = 1; i <= 3; i++) { // Outer loop from 1 to 3 - for (let j = 1; j <= 2; j++) { // Inner loop from 1 to 2 - console.log(`i: ${i}, j: ${j}`); // Print the values of 'i' and 'j' - } -} -``` - - - -## 9. Loop Control Statements - -Loop control statements allow you to control the flow of loops. Here are some common loop control statements in JavaScript: - -* `break`: Exits the loop immediately. -* `continue`: Skips the current iteration and moves to the next one. -* `return`: Exits the loop and the enclosing function. - -## 10. Infinite Loops - -An infinite loop is a loop that runs indefinitely. It occurs when the loop condition is always true or the loop lacks an exit condition. -```javascript -while (true) { // Infinite loop - console.log('This is an infinite loop!'); -} -``` - -## Conclusion - -Loops are essential for automating repetitive tasks in JavaScript. By using loops effectively, you can iterate over data structures, perform calculations, and execute code based on conditions. Practice writing loops to enhance your programming skills and build efficient applications. \ No newline at end of file diff --git a/docs/languages/javascript/js-6.md b/docs/languages/javascript/js-6.md deleted file mode 100644 index e77d6d7f2..000000000 --- a/docs/languages/javascript/js-6.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: type-casting-in-javascript -sidebar_position: 6 -title: Type Casting in JavaScript -sidebar_label: Type Casting in JavaScript ---- - -Hey everyone! Today, we will explore Type Casting in JavaScript, an essential concept for converting data types and ensuring smooth operations in your code. Whether you're a beginner or just need a quick refresher, this guide will help you understand how to effectively change between different types in JavaScript. Let's dive in! - - - -## Q. Why do we need Type Casting? - -* **JavaScript** is a loosely-typed language, meaning variables aren't tied to any specific data type. -* However, there are scenarios where you'll need to change the type of a variable to perform certain operations. -* Hence, type casting is essential for accurate, efficient, and error-free handling of data in JavaScript applications. - -## Types of Type Casting - - -JavaScript supports two types of type casting: - 1. Implicit Type Casting (Type Coercion) - 2. Explicit Type Casting - -```mermaid -graph TD - A["Type Conversion"] --> B["Implicit Conversion"] - A --> C["Explicit Conversion"] - - style A fill:#f57,stroke:#333,stroke-width:2px; - style B fill:#fdfd96,stroke:#333,stroke-width:2px; - style C fill:#fdfd96,stroke:#333,stroke-width:2px; -``` - -### 1. Implicit Type Casting : - -- Also known as **Type Coercion** -- In implicit type casting, JavaScript automatically converts one data type to another. -- This happens when you perform operations between values of different types, and JavaScript tries to make them compatible. -- Example: - -```javascript -let result = '5' + 3; // "53" (number 3 is converted to string) -let difference = '10' - 2; // 8 (string "10" is converted to number) -let truthy = '5' == 5; // true (type coercion between string and number) -``` - -- Explanation: - - In the first example, JavaScript converts the `number` `3` to a `string` before concatenating it with `"5"`. - - In the second example, `"10"` (`string`) is automatically converted to a `number` to perform subtraction. - - In the third example, JavaScript compares a `string` and a `number` by converting the `string` to a `number`. - -### 2. Explicit Type Casting : - -Unlike implicit type casting, explicit type casting requires you to manually convert a value from one type to another. JavaScript provides built-in methods to facilitate this process. - -**Common Methods for Explicit Type Casting with Examples:** - -1. `Number()` – Converts a value to a number. - -```javascript -// Converting string to number -let strNum = '42'; -let num = Number(strNum); // 42 -``` - -2. `Boolean()` – Converts a value to a boolean ( true or false ). - -```javascript -// Converting string to boolean -let strBool = ''; -let boolValue = Boolean(strBool); // false (empty string is falsy) -``` - -3. `ParseInt()` – Parse a string and return an integer. - -```javascript -// Converting string to integer -let decimalString = '3.14'; -let intValue = parseInt(decimalString); // 3 (truncates decimal part) -``` - -4. `ParseFloat()` – Parse a string and return a float - -```javascript -// Converting string to integer -let decimalString = '4.48'; -let floatValue = parseFloat(decimalString); // 4.48 -``` - -5. `String()` – Converts a value to a string. - -```javascript -// Converting number to string -let numberValue = 100; -let str = String(numberValue); // "100" -``` - -## Conclusion - -Type casting is a crucial aspect of JavaScript programming, allowing you to convert data types for seamless operations. By understanding implicit and explicit type casting, you can handle data effectively and ensure your code runs smoothly. Practice these concepts to enhance your programming skills and build robust applications. \ No newline at end of file diff --git a/docs/languages/javascript/js-7.md b/docs/languages/javascript/js-7.md deleted file mode 100644 index bc55ee4b5..000000000 --- a/docs/languages/javascript/js-7.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: arrays-in-javascript -sidebar_position: 7 -title: Arrays in JavaScript -sidebar_label: Arrays in JavaScript ---- - -Hey everyone! Today, we're diving into Arrays in JavaScript, one of the most fundamental and powerful data structures. Let's jump in and explore the different ways arrays can be used to store, manipulate, and access data! - - - -## What is an Array? - -- An `array` in JavaScript is a special type of `object` used to store multiple values in a single variable. -- Arrays can hold a collection of items, such as *numbers*, *strings*, *objects*, or even *other arrays*. -- Each element in an array is stored at a specific `index`, starting from `0`, which allows for easy access and manipulation of the data. - -## Key Features of Arrays: - -- Arrays can hold values of different data types. -- They have a *dynamic size*, meaning elements can be added or removed. -- Elements are accessed via their `index`, starting from `0`. - -## Example of an Array: - -```javascript -let fruits = ['apple', 'banana', 'cherry']; // array of fruits -console.log(fruits[0]); // Output: 'apple' -console.log(fruits[2]); // Output: 'cherry' -``` -In this example, the array `fruits` contains three string elements, and we access the first and third items using their indices. - - - -## Visual representation: - -![image](https://github.com/user-attachments/assets/01a5cd05-4975-4ee4-af4b-2e16741d5a54) - - -## Array methods: - -1. `Push()`: add item to end -2. `Pop()`: delete item from start and return -3. `toString()`: converts array to `String` -4. `Concat()` : joins multiple arrays & returns result -5. `Unshift()` : add item to start -6. `shift()` : delete item from start & return -7. `Slice()` : returns a piece of the array slice( startldx, endldx ) -8. `Splice()` : change original array (add, remove, replace) splice( startldx, delCount, newE11... ) - -## Array Iteration Methods: - -### 1. `forEach()`: -- The `forEach()` method calls a function (a callback function) once for each array element. -- Example: -```javascript -const numbers = [45, 4, 9, 16, 25]; -numbers.forEach((element)=>{ - console.log(element); -}); -``` -- Note: the function takes 3 arguments: - - The item value - - The item index - - The array itself - -### 2. `map()`: - -- The `map()` method creates a new array by performing a function on each array element. -- The `map()` method does not execute the function for array elements without values. -- The `map()` method does not change the original array. - -- **Example:** -```javascript -const numbers = [45, 4, 9, 16, 25]; -numbers.map((element)=>{ - console.log(element); -}); -``` - -### 3. `filter()`: - -- The `filter()` method creates a new array with array elements that pass a test. -- Example: -```javascript -const numbers = [45, 4, 9, 16, 25]; -const over18 = numbers.filter(myFunction); - -function myFunction(value, index, array) { - return value > 18; -} -``` - -### 4. `reduce()`: - -- The `reduce()` method reduces the array to a single value. -- The `reduce()` method executes a provided function for each value of the array (from left-to-right). - -- **Example:** -```javascript -const numbers = [45, 4, 9, 16, 25]; -const sum = numbers.reduce(myFunction); - -function myFunction(total, value, index, array) { - return total + value; -} -``` - -### 5. `find()`: - -- The `find()` method returns the value of the first array element that passes a test function. -- The `find()` method returns `undefined` if no elements pass the test. -- Example: -```javascript -const numbers = [45, 4, 9, 16, 25]; -const first = numbers.find(myFunction); - -function myFunction(value, index, array) { - return value > 18; -} -``` - - - -### 6. `findIndex()`: - -- The `findIndex()` method returns the index of the first array element that passes a test function. -- The `findIndex()` method returns `-1` if no elements pass the test. -- Example: -```javascript -const numbers = [45, 4, 9, 16, 25]; -const first = numbers.findIndex(myFunction); - -function myFunction(value, index, array) { - return value > 18; -} -``` - -## Conclusion: - -Arrays are a versatile and powerful data structure in JavaScript, allowing you to store, manipulate, and access multiple values efficiently. By understanding the key features and methods of arrays, you can leverage them to build complex applications and solve a wide range of problems. \ No newline at end of file diff --git a/docs/languages/javascript/js-8.md b/docs/languages/javascript/js-8.md deleted file mode 100644 index 5cb1b9b23..000000000 --- a/docs/languages/javascript/js-8.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: functions-in-javascript -sidebar_position: 8 -title: Functions in JavaScript -sidebar_label: Functions in JS ---- - -A function in JavaScript is similar to a procedure—a set of statements that performs a task or calculates a value, but for a procedure to qualify as a function, it should take some input and return an output where there is some obvious relationship between the input and the output. - - - -## **Functions Declaration** - -Function Declarations also known as function statement or function definition consists of function keyword, function name, parameters separated by commas and function body enclosed by curly braces ```{ /*function body*/ }``` - - -```javascript -function printName(name) { - return name; -} -``` - -In the example above, the function ```printName``` takes one parameter called ```name```. The function body consist of one statement that returns the name. - - - -## **Function Expressions** - -Function expressions are a way to define a function as part of an expression. Unlike function declarations, which define a function with a name, function expressions can be anonymous (without a name) or named. - -## 1. **Anonymous Function Expression** -An anonymous function expression is a function that doesn't have a name. It can be assigned to a variable, passed as an argument to another function, or returned from another function. - -```javascript -const greet = function() { - console.log("Hello!"); -}; - -greet(); -``` - -## 2. **Named Function Expression** -A named function expression includes a name. This can be useful for recursion or for better debugging. - -```javascript -const greet = function sayHello() { - console.log("Hello!"); -}; - -greet(); -``` - -## 3. **IIFE (Immediately Invoked Function Expression)** -An IIFE is a function that runs as soon as it is defined. It’s often used to create a local scope. - -```javascript -(function() { - console.log("This runs immediately!"); -})(); -``` - - - -## **Function Call** - -Calling a function means executing the code defined within it. There are various ways to call a function. - -```javascript -const greet = function(name) { - console.log("Hello ", name); -}; - -greet("World!"); //Output: Hello World! -``` - -The above example is calling a function with argument - - -```javascript -const obj = { - greet: function() { - console.log("Hello from an object!"); - } -}; - -obj.greet(); // Output: Hello from an object! -``` - -The above example is calling a method of an object - -```javascript -const multiply = (x, y) => x * y; - -console.log(multiply(2, 3)); // Output: 6 -``` - -The above example is of calling an arrow function - - -## More Resources: - -- [MDN Web Docs: Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions) -- [W3Schools: JavaScript Functions](https://www.w3schools.com/js/js_functions.asp) diff --git a/docs/languages/javascript/js-9.md b/docs/languages/javascript/js-9.md deleted file mode 100644 index 3e1e1eb87..000000000 --- a/docs/languages/javascript/js-9.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -id: recursion-in-javascript -sidebar_position: 9 -title: Recursion in JavaScript -sidebar_label: Recursion in JavaScript ---- - -Recursion is a powerful concept in programming where a function calls itself to solve smaller instances of the same problem. This approach is especially useful for tasks that can be broken down into similar sub-tasks, such as traversing trees, calculating factorials, or working with recursive data structures like nested arrays. - - - -## What is Recursion? - -In JavaScript, recursion occurs when a function calls itself until it reaches a base condition, at which point it stops calling itself and returns a value. - -## Key Concepts: -1. **Base Case**: The condition under which the recursion stops. -2. **Recursive Case**: The function calls itself with a modified argument, moving toward the base case. - -## Example: Factorial Function - -```javascript -function factorial(n) { - if (n === 0) { // Base case - return 1; - } - return n * factorial(n - 1); // Recursive case -} - -console.log(factorial(5)); // Output: 120 -``` - - - -## Visualizing Recursion - -Recursion can be visualized as a series of function calls, each building on the previous one until the base case is reached. - -```mermaid -graph TD - subgraph Recursion - style Recursion fill:#f57,stroke:#333,stroke-width:2px, stroke:#262626; - A(Recursion) - end - - B["Base Case"] - C["Recursive Case"] - - A -->|Stops| B - A -->|Calls Itself| C -``` - -In the example above, the `factorial` function calculates the factorial of a number by calling itself with a modified argument until it reaches the base case (`n === 0`). - -## Benefits of Recursion: - -1. **Simplicity**: Recursion can simplify complex problems by breaking them down into smaller, more manageable sub-problems. -2. **Readability**: Recursive solutions often mirror the problem's description, making the code easier to understand. -3. **Versatility**: Recursion can be applied to a wide range of problems, from mathematical calculations to tree traversal. -4. **Efficiency**: In some cases, recursive solutions can be more efficient than iterative ones. - -## Considerations: - -1. **Base Case**: Ensure that the base case is well-defined and reachable to prevent infinite recursion. -2. **Stack Usage**: Recursion consumes stack space for each function call, which can lead to stack overflow errors for deeply nested calls. -3. **Performance**: Recursive solutions may not always be the most performant due to the overhead of function calls. - -By understanding recursion and its applications, you can leverage this powerful technique to solve a variety of problems in JavaScript and other programming languages. - -```javascript -function factorial(n) { - if (n === 0) { // Base case - return 1; - } - return n * factorial(n - 1); // Recursive case -} - -console.log(factorial(5)); // Output: 120 -``` - -## Conclusion - -Recursion is a fundamental concept in programming that enables elegant solutions to complex problems. By mastering recursion, you can write concise, efficient code that leverages the power of self-referential functions to solve a wide range of tasks. Practice implementing recursive solutions to enhance your problem-solving skills and deepen your understanding of JavaScript. \ No newline at end of file diff --git a/docs/languages/python/_category_.json b/docs/languages/python/_category_.json deleted file mode 100644 index 7eb205535..000000000 --- a/docs/languages/python/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Python", - "position": 3, - "link": { - "type": "generated-index", - "description": "Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991, Python's design philosophy emphasizes code readability with its notable use of significant whitespace." - } - } \ No newline at end of file diff --git a/docs/languages/python/py-1.md b/docs/languages/python/py-1.md deleted file mode 100644 index 5efae6cb2..000000000 --- a/docs/languages/python/py-1.md +++ /dev/null @@ -1,179 +0,0 @@ ---- -id: datatypes-in-python -sidebar_position: 2 -title: Datatypes in Python -sidebar_label: Datatypes in Python ---- - -Hey there! In this guide, we'll explore the different data types available in Python. Understanding data types is crucial for writing efficient and clear Python code. Let's dive in! - -# Python Data Types - -* Python provides several built-in data types that allow you to work with different kinds of data. -* These data types can be categorized as primitive or non-primitive. - -## 1. Primitive Data Types - -### a. Integers (`int`) -- Represents whole numbers, both positive and negative. -```python -x = 4 -y = -21 -``` - -### b. Floating-Point Numbers (`float`) -- Represents real numbers with a decimal point. -```python -x = 6.3 -y = -5.2 -``` - -### c. Complex Numbers (`complex`) -- Represents complex numbers with a real and imaginary part. -```python -x = 1 + 2j -y = 3 - 4j -``` - -### d. Boolean (`bool`) -- Represents truth values, either `True` or `False`. -```python -is_python_fun = True -is_sky_green = False -``` - -### e. Strings (`str`) -- Represents a sequence of characters enclosed in quotes. -```python -name = "Python" -greeting = 'Hello, World!' -``` - -## 2. Non-Primitive Data Types - -### a. Lists (`list`) -- Ordered, mutable collections of elements. -```python -numbers = [1, 2, 3, 4, 5] -mixed = [1, "orange", True, 4.5] -``` - -### b. Tuples (`tuple`) -- Ordered, immutable collections of elements. -```python -coordinates = (30, 20) -empty_tuple = () -``` - -### c. Sets (`set`) -- Unordered, mutable collections of unique elements. -```python -unique_numbers = {1, 2, 3, 4, 5} -``` - -### d. Dictionaries (`dict`) -- Unordered collections of key-value pairs. -```python -person = {"name": "John Wick", "age": 60, "city": "New York"} -``` - -## 3. Type Conversion -You can convert between data types using built-in functions: -- `int()` -- `float()` -- `str()` -- `bool()` -- `list()` -- `tuple()` -- `set()` - -### a.Integer to String : - -```python -# Example -num = 10 -num_str = str(num) -print(num_str) # Output: '10' -print(type(num_str)) # Output: -``` - -### b.String to Integer : - -```python -num_str = "123" -num = int(num_str) -print(num) # Output: 123 -print(type(num)) # Output: -``` -### c.String to Float : - -```python -num_str = "12.34" -num = float(num_str) -print(num) # Output: 12.34 -print(type(num)) # Output: -``` - -### d.Float to Integer : - -```python -num = 12.56 -num_int = int(num) -print(num_int) # Output: 12 -print(type(num_int)) # Output: -``` -### e.List to Tuple : - -```python -my_list = [1, 2, 3] -my_tuple = tuple(my_list) -print(my_tuple) # Output: (1, 2, 3) -print(type(my_tuple)) # Output: -``` - -### f.Tuple to List : - -```python -my_tuple = (4, 5, 6) -my_list = list(my_tuple) -print(my_list) # Output: [4, 5, 6] -print(type(my_list)) # Output: -``` -### g.List to Set : - -```python -my_list = [1, 2, 2, 3] -my_set = set(my_list) -print(my_set) # Output: {1, 2, 3} -print(type(my_set)) # Output: -``` - -### h.Set to List : - -```python -my_set = {4, 5, 6} -my_list = list(my_set) -print(my_list) # Output: [4, 5, 6] -print(type(my_list)) # Output: -``` - -### i.Boolean to Integer : - -```python -val = True -val_int = int(val) -print(val_int) # Output: 1 -print(type(val_int)) # Output: -``` - -### j.Integer to Boolean : - -```python -num = 0 -bool_val = bool(num) -print(bool_val) # Output: False -print(type(bool_val)) # Output: -``` ---- - -These data types are the foundation of Python, and understanding them is key to writing efficient and clear Python code. diff --git a/docs/languages/python/py-10.md b/docs/languages/python/py-10.md deleted file mode 100644 index 4fc3c4195..000000000 --- a/docs/languages/python/py-10.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: defaultdict-and-counter-in-python -sidebar_position: 10 -title: defaultdict and Counter in Python -sidebar_label: defaultdict & Counter in Python ---- - -Hey everyone! Today we are going to dive into two powerful utilities in Python's `collections` module – `defaultdict` and `Counter`. These data structures can significantly simplify certain tasks, especially when working with dictionaries and counting elements. Let's explore how they work and their advantages. -# defaultdict in Python - - -* `defaultdict` is a subclass of Python's built-in `dict` class. - -* It overrides the default behavior of the `dict` class by providing a default value for a nonexistent key. - -This is particularly useful when you want to avoid `KeyError` exceptions. -## 1. Using defaultdict - - -To use `defaultdict`, you must import it from the `collections` module: -```python -from collections import defaultdict # Importing defaultdict from collections module - -# Example: Counting occurrences of letters in a word -word = 'programming' # Define a word -letter_count = defaultdict(int) # Create defaultdict with default value as int (0) - -for letter in word: # Iterate over each letter in the word - letter_count[letter] += 1 # Increment the count of each letter - -print(letter_count) # Output: defaultdict(, {'p': 1, 'r': 2, 'o': 1, 'g': 2, 'a': 1, 'm': 2, 'i': 1, 'n': 1}) -``` -## 2. Advantages of defaultdict - - -Here are some of the key advantages of using `defaultdict`: -- **Avoids KeyError**: You don't have to check whether a key exists before using it. -- **Simplifies code**: Reduces the need for conditional logic to handle missing keys. -- **Customizable defaults**: You can define any default factory function (like `int`, `list`, `str`, etc.). -# Counter in Python - - -* `Counter` is a subclass of `dict` designed to count hashable objects like elements in a list or characters in a string. - -* It makes it easy to tally occurrences without writing manual loops. -## 1. Using Counter - - -To use `Counter`, you must also import it from the `collections` module: -```python -from collections import Counter # Importing Counter from collections module - -# Example: Counting the frequency of characters in a word -word = 'banana' # Define a word -char_count = Counter(word) # Create Counter to count characters in the word - -print(char_count) # Output: Counter({'a': 3, 'n': 2, 'b': 1}) -``` -## 2. Advantages of Counter - - -Here are some of the key advantages of using `Counter`: -- **Efficient counting**: Automatically counts elements without explicit loops. -- **Built-in operations**: Supports common tasks like finding the most common elements (`most_common()`). -- **Works with all iterables**: Can be used with strings, lists, tuples, and more. -## 3. Common Counter Methods - - -Here are a few useful methods provided by the `Counter` class: -```python -# Example: Using the most_common() method -from collections import Counter # Importing Counter - -word = 'mississippi' # Define a word -char_count = Counter(word) # Create Counter for character count - -# Get the two most common characters -print(char_count.most_common(2)) # Output: [('i', 4), ('s', 4)] - -# Example: Subtracting counts using subtract() -other_word = 'issippi' # Define another word -other_count = Counter(other_word) # Create Counter for second word - -char_count.subtract(other_count) # Subtract counts from the second Counter -print(char_count) # Output: Counter({'m': 1, 'i': 1, 's': 0, 'p': 0}) -``` \ No newline at end of file diff --git a/docs/languages/python/py-11.md b/docs/languages/python/py-11.md deleted file mode 100644 index 953a8815d..000000000 --- a/docs/languages/python/py-11.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: usage-of-lists-in-python -sidebar_position: 11 -title: Lists in Python -sidebar_label: Lists in Python ---- - -Hey there! In this guide, we'll explore lists in Python. Lists are ordered, mutable collections of elements that allow you to store and manipulate data efficiently. Let's dive in! - ---- - -## Python Lists - -- **Ordered**: Elements have a defined order and can be accessed via indices. -- **Mutable**: Lists can be modified after creation (add, remove, or change elements). - -- **Heterogeneous**: Lists can store elements of different data types (e.g., integers, strings, booleans). - -- **Supports nesting**: Lists can contain other lists as elements (nested lists). -- **Dynamic sizing**: Lists can grow or shrink as you add or remove elements. - -- **Common methods**: Includes methods like `append()`, `extend()`, `insert()`, `pop()`, `remove()`, `sort()`, and `reverse()`. - ---- - -## 1. Creating a List - -You can create a list using square brackets `[]` or the `list()` function. - -```python -my_list = [1, 2, 3, 4, 5] # Create a list using square brackets -another_list = list(('apple', 'banana', 'cherry')) # Create a list using the list() function -print(my_list) # Output: [1, 2, 3, 4, 5] -print(another_list) # Output: ['apple', 'banana', 'cherry'] -``` - -## 2. Accessing Elements - -You can access elements in a list using their index. Python uses zero-based indexing. - -```python -my_list = [10, 20, 30, 40, 50] -print(my_list[0]) # Access the first element, Output: 10 -print(my_list[3]) # Access the fourth element, Output: 40 -``` - -## 3. Adding Elements - -You can add new elements to a list using methods like `append()`, `insert()`, or `extend()`. - -```python -my_list = [1, 2, 3] -my_list.append(4) # Add an element to the end of the list -print(my_list) # Output: [1, 2, 3, 4] - -my_list.insert(1, 5) # Insert an element at index 1 -print(my_list) # Output: [1, 5, 2, 3, 4] - -another_list = [6, 7] -my_list.extend(another_list) # Extend the list by adding elements from another list -print(my_list) # Output: [1, 5, 2, 3, 4, 6, 7] -``` - -## 4. Removing Elements - -You can remove elements from a list using `remove()`, `pop()`, or `del`. - -```python -my_list = [1, 2, 3, 4, 5] -my_list.remove(3) # Remove the first occurrence of a value -print(my_list) # Output: [1, 2, 4, 5] - -popped_element = my_list.pop(1) # Remove and return the element at index 1 -print(popped_element) # Output: 2 -print(my_list) # Output: [1, 4, 5] - -del my_list[0] # Delete the element at index 0 -print(my_list) # Output: [4, 5] -``` - -## 5. List Methods - -Lists have several built-in methods for manipulation. - -```python -my_list = [3, 1, 4, 2, 5] - -my_list.sort() # Sort the list in ascending order -print(my_list) # Output: [1, 2, 3, 4, 5] - -my_list.reverse() # Reverse the order of the list -print(my_list) # Output: [5, 4, 3, 2, 1] - -length = len(my_list) # Get the length of the list -print(length) # Output: 5 -``` diff --git a/docs/languages/python/py-12.md b/docs/languages/python/py-12.md deleted file mode 100644 index e548c5926..000000000 --- a/docs/languages/python/py-12.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -id: usage-of-tuples-in-python -sidebar_position: 12 -title: Tuples in Python -sidebar_label: Tuples in Python ---- - -Hey there! In this guide, we'll explore tuples in Python. Tuples are ordered, immutable collections of elements that allow you to store and manipulate data efficiently. Let's dive in! - ---- - -## Python Tuples - -- **Ordered**: Elements have a defined order and can be accessed via indices. -- **Immutable**: Once created, elements in a tuple cannot be changed. -- **Heterogeneous**: Tuples can store elements of different data types (e.g., integers, strings, booleans). -- **Supports nesting**: Tuples can contain other tuples or lists as elements. - ---- - -## 1. Creating a Tuple - -You can create a tuple using parentheses `()` or the `tuple()` function. - -```python -my_tuple = (1, 2, 3, 4, 5) # Create a tuple using parentheses -another_tuple = tuple(('apple', 'banana', 'cherry')) # Create a tuple using the tuple() function -print(my_tuple) # Output: (1, 2, 3, 4, 5) -print(another_tuple) # Output: ('apple', 'banana', 'cherry') -``` - -## 2. Accessing Elements - -You can access elements in a tuple using their index. Python uses zero-based indexing. - -```python -my_tuple = (10, 20, 30, 40, 50) -print(my_tuple[0]) # Access the first element, Output: 10 -print(my_tuple[3]) # Access the fourth element, Output: 40 -``` - -## 3. Unpacking Tuples - -You can unpack a tuple by assigning its elements to multiple variables. - -```python -my_tuple = (1, 2, 3) -a, b, c = my_tuple # Unpacking tuple elements -print(a) # Output: 1 -print(b) # Output: 2 -print(c) # Output: 3 -``` - -## 4. Tuple Methods - -Tuples have only two built-in methods: `count()` and `index()`. - -```python -my_tuple = (1, 2, 2, 3, 4, 2) - -count_of_twos = my_tuple.count(2) # Count the number of occurrences of a value -print(count_of_twos) # Output: 3 - -index_of_three = my_tuple.index(3) # Get the index of the first occurrence of a value -print(index_of_three) # Output: 3 -``` - -## 5. Nested Tuples - -Tuples can contain other tuples or lists as elements. - -```python -nested_tuple = (1, (2, 3), [4, 5]) # A tuple with a nested tuple and a list -print(nested_tuple) # Output: (1, (2, 3), [4, 5]) -``` diff --git a/docs/languages/python/py-13.md b/docs/languages/python/py-13.md deleted file mode 100644 index f074f4fb2..000000000 --- a/docs/languages/python/py-13.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: usage-of-strings-in-python -sidebar_position: 13 -title: Strings in Python -sidebar_label: Strings in Python ---- - -Hey there! In this guide, we'll explore strings in Python. Strings are sequences of characters that allow you to store and manipulate text efficiently. Let's dive in! - ---- - -## Python Strings - -- **Immutable**: Strings are immutable, meaning that once created, their contents cannot be changed. -- **Indexed**: Strings are ordered collections of characters, and you can access individual characters using their index. -- **Supports concatenation**: You can concatenate strings using the `+` operator. -- **Supports various methods**: Python provides many built-in methods to manipulate strings. - ---- - -## 1. Creating a String - -You can create a string using single quotes `'`, double quotes `"`, or triple quotes `'''` or `"""` for multi-line strings. - -```python -my_string = 'Hello, World!' # Create a string using single quotes -another_string = "Python is awesome!" # Create a string using double quotes -multi_line_string = '''This is a -multi-line string.''' # Create a string using triple quotes - -print(my_string) # Output: Hello, World! -print(another_string) # Output: Python is awesome! -print(multi_line_string) # Output: This is a - # multi-line string. -``` - -## 2. Accessing Characters - -You can access characters in a string using their index. Python uses zero-based indexing. - -```python -my_string = "Hello, World!" -print(my_string[0]) # Access the first character, Output: H -print(my_string[7]) # Access the eighth character, Output: W -``` - -## 3. String Methods - -Python provides various built-in methods to manipulate strings. - -```python -my_string = "Python" - -length = len(my_string) # Get the length of the string -print(length) # Output: 6 - -upper_string = my_string.upper() # Convert to uppercase -print(upper_string) # Output: PYTHON - -lower_string = my_string.lower() # Convert to lowercase -print(lower_string) # Output: python - -replaced_string = my_string.replace("P", "J") # Replace a substring -print(replaced_string) # Output: Jython -``` - -## 4. String Concatenation - -You can concatenate strings using the `+` operator. - -```python -string1 = "Hello" -string2 = "World" -combined_string = string1 + ", " + string2 + "!" # Concatenate strings -print(combined_string) # Output: Hello, World! -``` - -## 5. String Slicing - -You can slice a string to get a substring. - -```python -my_string = "Hello, World!" -substring = my_string[0:5] # Get a substring -print(substring) # Output: Hello - -substring2 = my_string[7:] # Get substring from index 7 to end -print(substring2) # Output: World! -``` diff --git a/docs/languages/python/py-14.md b/docs/languages/python/py-14.md deleted file mode 100644 index 9a4882b71..000000000 --- a/docs/languages/python/py-14.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -id: usage-of-modules-in-python -sidebar_position: 14 -title: Modules in Python -sidebar_label: Modules in Python ---- - -Hey there! In this guide, we'll explore modules in Python. Modules are files containing Python code that can define functions, classes, and variables. They allow you to organize your code logically and reuse code across different programs. Let's dive in! - ---- - -## Python Modules - -- **Code Organization**: Modules help organize code into manageable sections, making it easier to maintain. -- **Reusability**: You can reuse code in multiple programs without rewriting it. -- **Standard Library**: Python comes with a standard library of modules that provide useful functions and tools. - ---- - -## 1. Creating a Module - -You can create a module by simply creating a new Python file (with a `.py` extension) and defining functions or variables in it. - -```python -# my_module.py -def greet(name): - return f"Hello, {name}!" - -PI = 3.14159 -``` - -## 2. Importing a Module - -You can import a module using the `import` statement. You can import the entire module or specific functions or variables. - -```python -import my_module # Import the entire module -from my_module import greet # Import specific function - -print(my_module.PI) # Output: 3.14159 -print(greet("Alice")) # Output: Hello, Alice! -``` - -## 3. Importing with Aliases - -You can give a module or function an alias using the `as` keyword to simplify its usage. - -```python -import my_module as mm - -print(mm.PI) # Output: 3.14159 -print(mm.greet("Bob")) # Output: Hello, Bob! -``` - -## 4. The `__name__` Variable - -The `__name__` variable allows you to check if a module is being run as the main program or if it is being imported. - -```python -# my_module.py -def greet(name): - return f"Hello, {name}!" - -if __name__ == "__main__": - print(greet("Main")) # This code runs only if the module is executed directly -``` - -## 5. Using Standard Library Modules - -Python's standard library provides many built-in modules you can use in your programs. - -```python -import math - -print(math.sqrt(16)) # Output: 4.0 -print(math.pi) # Output: 3.141592653589793 -``` diff --git a/docs/languages/python/py-15.md b/docs/languages/python/py-15.md deleted file mode 100644 index b1f1689ff..000000000 --- a/docs/languages/python/py-15.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -id: usage-of-decorators-in-python -sidebar_position: 15 -title: Decorators in Python -sidebar_label: Decorators in Python ---- - -Hey there! In this guide, we'll explore decorators in Python. Decorators are a powerful and flexible way to modify the behavior of functions or methods. They allow you to add functionality to existing code in a clean and readable way. Let's dive in! - ---- - -## Python Decorators - -- **Function Modification**: Decorators allow you to extend or modify the behavior of functions or methods without changing their code. -- **Higher-Order Functions**: Decorators are often implemented as higher-order functions, meaning they take another function as an argument. - ---- - -## 1. Defining a Simple Decorator - -You can define a simple decorator by creating a function that takes another function as an argument and returns a new function. - -```python -def my_decorator(func): - def wrapper(): - print("Something is happening before the function is called.") - func() - print("Something is happening after the function is called.") - return wrapper -``` - -## 2. Applying a Decorator - -You can apply a decorator to a function using the `@decorator_name` syntax above the function definition. - -```python -@my_decorator -def say_hello(): - print("Hello!") - -say_hello() # Output: -# Something is happening before the function is called. -# Hello! -# Something is happening after the function is called. -``` - -## 3. Decorators with Arguments - -You can create decorators that accept arguments by defining another level of nested functions. - -```python -def repeat(num_times): - def decorator_repeat(func): - def wrapper(*args, **kwargs): - for _ in range(num_times): - func(*args, **kwargs) - return wrapper - return decorator_repeat - -@repeat(3) -def greet(name): - print(f"Hello, {name}!") - -greet("Alice") # Output: -# Hello, Alice! -# Hello, Alice! -# Hello, Alice! -``` - -## 4. Using `functools.wraps` - -When creating decorators, it's a good practice to use `functools.wraps` to preserve the original function's metadata. - -```python -from functools import wraps - -def my_decorator(func): - @wraps(func) - def wrapper(*args, **kwargs): - print("Something is happening before the function is called.") - return func(*args, **kwargs) - return wrapper - -@my_decorator -def say_hello(): - """This function says hello.""" - print("Hello!") - -print(say_hello.__name__) # Output: say_hello -print(say_hello.__doc__) # Output: This function says hello. -``` - -## 5. Chaining Decorators - -You can apply multiple decorators to a single function by stacking them. - -```python -def decorator_one(func): - def wrapper(): - print("Decorator One") - func() - return wrapper - -def decorator_two(func): - def wrapper(): - print("Decorator Two") - func() - return wrapper - -@decorator_one -@decorator_two -def say_hello(): - print("Hello!") - -say_hello() # Output: -# Decorator One -# Decorator Two -# Hello! -``` diff --git a/docs/languages/python/py-16.md b/docs/languages/python/py-16.md deleted file mode 100644 index c8a5f4145..000000000 --- a/docs/languages/python/py-16.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -id: usage-of-generators-in-python -sidebar_position: 16 -title: Generators in Python -sidebar_label: Generators in Python ---- - -Hey there! In this guide, we'll explore generators in Python. Generators are a special type of iterable that allow you to create iterators in a very concise and efficient way. They are useful for managing large datasets and for situations where you want to yield results incrementally. Let's dive in! - ---- - -## Python Generators - -- **Iterators**: Generators are a type of iterator that generate values on the fly and do not store them in memory. -- **Yield Statement**: Generators use the `yield` statement to produce a value and pause the function’s state, allowing it to resume later. - ---- - -## 1. Defining a Simple Generator - -You can define a generator function using the `yield` keyword. - -```python -def simple_generator(): - yield 1 - yield 2 - yield 3 - -gen = simple_generator() # Create a generator object -print(next(gen)) # Output: 1 -print(next(gen)) # Output: 2 -print(next(gen)) # Output: 3 -# print(next(gen)) # Raises StopIteration error -``` - -## 2. Using a Generator in a Loop - -Generators can be used in a loop to retrieve values until the generator is exhausted. - -```python -def countdown(n): - while n > 0: - yield n - n -= 1 - -for number in countdown(5): - print(number) # Output: 5, 4, 3, 2, 1 -``` - -## 3. Generator Expressions - -You can create generators using a generator expression, which is similar to list comprehensions but uses parentheses instead of brackets. - -```python -squared_numbers = (x**2 for x in range(5)) - -for square in squared_numbers: - print(square) # Output: 0, 1, 4, 9, 16 -``` - -## 4. Advantages of Generators - -- **Memory Efficiency**: Generators do not store the entire list in memory, making them more memory-efficient than lists. -- **Lazy Evaluation**: Values are computed on-the-fly, allowing for more efficient use of resources. - -## 5. Practical Use Case: Fibonacci Sequence - -Here’s an example of a generator that produces Fibonacci numbers. - -```python -def fibonacci(n): - a, b = 0, 1 - for _ in range(n): - yield a - a, b = b, a + b - -for num in fibonacci(10): - print(num) # Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 -``` diff --git a/docs/languages/python/py-17.md b/docs/languages/python/py-17.md deleted file mode 100644 index d62b5f25a..000000000 --- a/docs/languages/python/py-17.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -id: regular-expression-in-python -sidebar_position: 17 -title: RegEx(Regular Expression) in Python -sidebar_label: RegEx(Regular Expression) in Python ---- - -Hey there! In this guide, we'll explore RegEx or Regular Expression in Python. A Regular Expression or RegEx is a special sequence of characters that uses a search pattern to find a string or set of strings. Let's dive in! - ---- - -## Regular Expression - -Regular expressions (regex) are a powerful tool for working with text by allowing you to define patterns that match specific character sequences.Regex is commonly used for tasks like: - -- Searching for specific patterns within a string -- Validating inputs (e.g., email addresses, phone numbers) -- Extracting or replacing parts of text - ---- - -## 1. RegEx Module in Python - -Python has a built-in module named `re` that is used for regular expressions in Python. We can import this module by using the import statement. - -Example: - -```python -# importing re module -import re -``` - -After importing the module you can start using the various function provided . - - -### 2. Metacharaters -Metacharacters are the characters with special meaning.These are used for pattern making. Below is a list of few Metacharacters with their descriptions - -| Metacharacter | Description | -|---------------|----------------------------------------------------------------------------------------------------------| -| `.` | Matches any character except a newline. | -| `^` | Matches the start of a string. | -| `$` | Matches the end of a string. | -| `*` | Matches 0 or more repetitions of the preceding character or group. | -| `+` | Matches 1 or more repetitions of the preceding character or group. | -| `?` | Matches 0 or 1 occurrence of the preceding character or group (makes it optional). | -| `{}` | Specifies the exact number of repetitions `{n}`, a range `{n,m}`, or a minimum `{n,}`. | -| `[]` | Matches any single character inside the brackets. | -| `\|` | Acts as an OR operator between expressions (e.g., `a|b` matches `a` or `b`). | -| `()` | Groups multiple expressions together and captures the matched text. | -| `\` | Escapes special characters (e.g., `\.` matches a literal `.`) or introduces special sequences like `\d`(We will learn `Special Sequences` in the next section). | - - - - -## 3. Special Sequences -Special Sequence in regex are shorthand notations that match specific types of characters, like digits, whitespace, or word characters, making patterns more concise and readable. -Table below shows various examples Special Sequence, their description and examples - -| Special Sequence | Description | Example | -|------------------|-------------------------------------------------------|----------------------------------| -| `\d` | Matches any digit (equivalent to `[0-9]`). | `\d{3}` matches `123` in `abc123`| -| `\D` | Matches any non-digit character. | `\D+` matches `abc` in `abc123` | -| `\w` | Matches any alphanumeric character or underscore. | `\w+` matches `abc123` in `abc123` | -| `\W` | Matches any non-alphanumeric character. | `\W+` matches `!@#` in `abc!@#` | -| `\s` | Matches any whitespace character (space, tab, newline).| `\s+` matches spaces in `a b c` | -| `\S` | Matches any non-whitespace character. | `\S+` matches `abc123` in `abc123` | -| `\b` | Matches a word boundary. | `\bword\b` matches `word` in `word!` but not in `sword` | -| `\B` | Matches a non-word boundary. | `\Bword\B` matches `word` in `swordplay` but not `word` alone | -| `\A` | Matches the start of the string. | `\Aabc` matches `abc` in `abc123` | -| `\Z` | Matches the end of the string. | `123\Z` matches `123` in `abc123` | -| `\` | Escapes special characters. | `\.` matches a literal `.` in `3.14` | -| `\t` | Matches a tab character. | `a\tb` matches `a b` (tab) | -| `\n` | Matches a newline character. | `a\nb` matches `a b` with newline | - - -## 3. RegEx Functions - -Regex functions in Python, available through the re module, provide powerful tools to search, match, split, replace, and manipulate text based on specified patterns, making it easy to handle complex text processing tasks. - -| Function | Description | Example Usage | -|----------------|-----------------------------------------------------------------------------------------------|---------------------------------------------| -| `re.search()` | Searches for the first occurrence of the pattern within the string and returns a match object if found. | `re.search(r"\d+", "Age: 25")` finds `25`. | -| `re.match()` | Checks if the pattern matches only at the beginning of the string. Returns a match object if found. | `re.match(r"Hello", "Hello World")` matches `Hello`. | -| `re.findall()` | Finds all non-overlapping matches of the pattern in the string and returns them as a list. | `re.findall(r"\w+", "Hello World")` returns `['Hello', 'World']`. | -| `re.split()` | Splits the string by occurrences of the pattern and returns a list of substrings. | `re.split(r"\s", "Split this sentence")` returns `['Split', 'this', 'sentence']`. | -| `re.sub()` | Replaces occurrences of the pattern in the string with a specified replacement. | `re.sub(r"\d", "#", "Phone: 123-456")` returns `Phone: ###-###`. | -| `re.compile()` | Compiles a regex pattern into a regex object for reuse, which can then use `search()`, `match()`, etc. | `pattern = re.compile(r"\d+"); pattern.search("ID: 789")` finds `789`. | - -Example: -```python -import re - -pattern = r"\b[A-Za-z]+\b" # matches any word consisting of letters only -text = "Hello, Algo world!" -matches = re.findall(pattern, text) -print(matches) # Output: ['Hello', 'Algo', 'world'] - -``` - -## 4. Practical Use Case: Password Validator - -Here’s an example of a Python Program to check the validity of password input by the user. - -```python -import re - -def validate_password(password): - # Define the regex pattern for password validation - pattern = r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$" - - # Check if the password matches the pattern - if re.match(pattern, password): - return "Password is valid" - else: - return "Password is invalid" - -# Test the function -print(validate_password("Password123!")) # Output: Password is valid -print(validate_password("Pass123")) # Output: Password is invalid (too short, no special character) - -``` diff --git a/docs/languages/python/py-18.md b/docs/languages/python/py-18.md deleted file mode 100644 index 138128d3e..000000000 --- a/docs/languages/python/py-18.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: lambda-function-in-python -sidebar_position: 18 -title: Lambda Function in Python -sidebar_label: Lambda Function in Python ---- - -Hey there! In this guide, we'll explore Lambda Function in Python.A lambda function can take n number of arguments at a time. But it returns only one argument at a time. Its useful for simple, quick operations and can replace small function definitions where full def functions might feel excessive. Let's dive it! - ---- - -## Lambda Function - -Lambda functions in Python, also known as `anonymous` functions, are small, one-line functions defined with the `lambda` keyword. - ---- - -## 1. Syntax - -```python -lambda arguments: expression -``` - -This function accepts any count of inputs but only evaluates and returns one expression. That means it takes many inputs but returns only one -output. - -## 2. Why Use Lambda Instead of Def? - -Using lambda instead of def can be beneficial in certain situations where brevity and inline functionality are preferred. - -The code defines a Square function using both the `def` keyword and a `lambda` function. -Example: - -```python -#using def -def square(num): - return num*num - -num1=2 -print(square(num1)) #Output:4 - - -#using lambda -lambda_square=lambda x:x*x -print(lambda_square(3)) #Output:9 - -``` - -Both of these give the correct output for the square of a -given number without employing Lambda. However, while -using `def` we were also required to use the return -keyword to provide the output from wherever the function -was invoked after being executed.Instead of a "return" -statement, Lambda definitions always include a statement -given at output. - -The convenience of lambda functions lies in their -flexibility.We dont need to allocate a lambda expression to a variable because we can put it at any place a function is required. - -## 3. Practical Use cases of Lambda Function - -- #### Using Lambda Function with filter() - -A program to filter a list of integers that are divisible by 3 -using Lambda function from given list of integers. - -```python - -numbers = [10, 15, 22, 33, 42, 55, 60, 71, 81] - -divisible_by_3 = list(filter(lambda x: x % 3 == 0, numbers)) - -print("Numbers divisible by 3:", divisible_by_3) - -#Output: Numbers divisible by 3: [15, 33, 42, 60, 81] - -``` - ---- - -- #### Using Lambda Function with map() - -A program to cube every number in a given list of -integers using Lambda function. - -```python - -input=[ 1, 2, 3, 4, 5] - -cube=list(map(lambda n:n**3,input)) - -print("Cube every number of the input is",cube) - -#Output: Cube every number of the input is [1, 8, 27, 64, 125] - -``` - ---- - -- #### Using Lambda Function with reduce() - -A program to calculate the product of all numbers in a list - -```python -from functools import reduce - -numbers = [1, 2, 3, 4] - -product = reduce(lambda x, y: x * y, numbers) - -print(product) # Output: 24 - - -``` - ---- - -- #### Using Lambda Function in List Comprehension - A program to filter a list of integers that are divisible by 3 - using Lambda function from given list of integers. - -```python - -numbers = [10, 15, 22, 33, 42, 55, 60, 71, 81] - -divisible_by_3 = [x for x in numbers if (lambda x: x % 3 == 0)(x)] - -print("Numbers divisible by 3:", divisible_by_3) - -#Output: Numbers divisible by 3: [15, 33, 42, 60, 81] - - -``` - ---- - -- #### Using Lambda Function with if-else - -A Program using lambda function to check if a number is even or odd - -```python - -even_or_odd = lambda x: "Even" if x % 2 == 0 else "Odd" - -print(even_or_odd(10)) # Output: Even -print(even_or_odd(7)) # Output: Odd - -``` - ---- - -- #### Using Lambda Function with Multiple Statements - -A Program using lambda function to for sorting the sublists and find the third largest number from every sublist - -```python - -my_List = [ [3, 5, 8, 6], [23, 54, 12, 87], [1, 2, 4, 12, 5] ] - -sort_List = lambda num: [sorted(n) for n in num] - -#sorted list : [[3, 5, 6, 8],[12, 23, 54, 87],[1, 2, 4, 5, 12]] - -third_Largest = lambda num, func: [l[-3] for l in func(num) if len(l) >= 3] - -result = third_Largest(my_List, sort_List) - -print('The third largest number from every sublist is:', result) - -#Output:The third largest number from every sublist is: [5, 23, 4] - -``` - ---- - -## 4. Conclusion - -Lambda functions in Python provide a concise way to create small, anonymous functions for temporary use, enhancing readability and enabling -functional programming. While more intricate logic, traditional `def` functions are preferred for better maintainability, `lambda` is ideal -for simple tasks, they should be used judiciously, as complex expressions can reduce clarity. Undersatnding corret usage of both the function -can make your code clean and effective. - -Happy Learning! - diff --git a/docs/languages/python/py-2.md b/docs/languages/python/py-2.md deleted file mode 100644 index 4b33a1c0d..000000000 --- a/docs/languages/python/py-2.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: variables-in-python -sidebar_position: 1 -title: Variables in Python -sidebar_label: Variables in Python ---- - - -Hey there! In this guide, we'll explore the concept of variables in Python. Variables are essential in programming, allowing you to store and manipulate data dynamically. Let's dive in! - -# Variables in Python - -## Introduction - -* Variables in Python are containers that hold data. -* They are used to store values that can be referenced and manipulated throughout a program. -* Python is dynamically typed, which means you do not need to declare the type of a variable when creating one. - -## Variable Declaration -In Python, variables are created when you assign a value to them. No explicit declaration is required. - -```python -x = 7 # Integer variable -y = 3.14 # Float variable -name = "Ben" # String variable -is_active = True # Boolean variable -``` - -## Naming Conventions - -* Variable names can contain letters, digits, and underscores. -* They must start with a letter or an underscore (_). -* They cannot start with a number. -* Python is case-sensitive, so age and Age are different variables. - -## Valid variable names - -```python -my_var = 25 -_name = "Mike" -age2 = 22 -``` - -## Invalid variable names - -```python -2name = "Rohan" # Cannot start with a number -my-var = 21 # Hyphen (-) is not allowed -``` -## Variable Types -Python supports several data types that can be assigned to variables: - -* Integers (int): Whole numbers -* Floating-Point Numbers (float): Numbers with decimals -* Strings (str): Text enclosed in single or double quotes -* Booleans (bool): True or False -* Lists (list): Ordered collections of items -* Tuples (tuple): Immutable ordered collections -* Dictionaries (dict): Key-value pairs - -Example: - -```python -age = 50 # Integer -height = 5.11 # Float -name = "John Doe" # String -is_student = False # Boolean -fruits = ["cherry", "orange"] # List -coordinates = (10.0, 20.0) # Tuple -person = {"name": "John", "age": 30} # Dictionary - -``` -## Dynamic Typing -Python is dynamically typed, meaning the same variable can hold values of different types at different points in the program. - -```python -x = 5 # Initially an integer -x = "Hello" # Now a string -``` -## Multiple Variable Assignment -You can assign multiple variables at once in a single line - -```python -a, b, c = 5, 10, 15 -``` -You can also assign same value to multiple variables - -```python -x = y = z = 0 -``` -## Variable Scope - -* Local Variables: Defined inside a function and can only be used within that function. -* Global Variables: Defined outside all functions and can be accessed throughout the program. - -```python -x = "global variable" - -def my_function(): - x = "local variable" - print(x) # Output: local variable - -my_function() -print(x) # Output: global variable -``` - -## Swapping Variables -In Python you can easily swap the values of two variables without needing any temporary variable - -```python -a = 5 -b = 10 -a, b = b, a -print(a) # Output: 10 -print(b) # Output: 5 -``` -## Constants in Python - -By convention, variables that should not change are written in uppercase. -However, Python does not have built-in support for constants, so it's up to the programmer to treat such variables as constant. - -```python -PI = 3.14159 -MAX_SPEED = 120 -``` -## Deleting Variables -You can delete a variable using `del` statement - -```python -x = 12 -del x # Deletes the variable 'x' -``` - -## Best Practices -- Use descriptive names that make it clear what the variable represents. -- Follow standard naming conventions (snake_case for variable names). -- Keep variable scope as limited as possible to avoid conflicts. - - - - diff --git a/docs/languages/python/py-3.md b/docs/languages/python/py-3.md deleted file mode 100644 index 9eaf504f8..000000000 --- a/docs/languages/python/py-3.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: loops-in-python -sidebar_position: 4 -title: Loops in Python -sidebar_label: Loops in Python ---- - -Hey there! In this guide, we'll explore loops in Python. Loops are used to execute a block of code repeatedly based on a condition. Let's dive in! - -# Python Loops - -* Loops allow you to repeatedly execute a block of code while certain conditions are true. - -* Python provides two primary types of loops: `for` loops and `while` loops. -## 1. For Loop - - -The `for` loop in Python is used to iterate over a sequence (like a list, tuple, or string) and execute a block of code for each element. -```python -numbers = [1, 2, 3, 4, 5] # List of numbers to iterate over -for num in numbers: # Begin a 'for' loop over the 'numbers' list - print(num) # Print each number in the list -``` -## 2. For Loop with Range - - -You can also use the `range()` function to iterate over a sequence of numbers, especially when you want to loop for a specific number of times. -```python -for i in range(1, 6): # Loop through numbers from 1 to 5 (range excludes 6) - print(i) # Print each number in the range -``` -## 3. While Loop - - -The `while` loop in Python allows you to execute a block of code as long as a condition is true. -```python -count = 1 # Initialize a variable 'count' with value 1 -while count <= 5: # Continue looping while 'count' is less than or equal to 5 - print(count) # Print the current value of 'count' - count += 1 # Increment 'count' by 1 in each iteration -``` -## 4. Break Statement - - -The `break` statement is used to exit a loop prematurely, even if the loop condition is still true. -```python -for num in range(1, 11): # Loop through numbers 1 to 10 - if num == 5: # Check if 'num' equals 5 - break # Exit the loop when 'num' is 5 - print(num) # Print numbers from 1 to 4 -``` -## 5. Continue Statement - - -The `continue` statement skips the current iteration of the loop and moves to the next iteration. -```python -for num in range(1, 6): # Loop through numbers from 1 to 5 - if num == 3: # Check if 'num' equals 3 - continue # Skip the current iteration when 'num' is 3 - print(num) # Print numbers except 3 -``` -## 6. Nested Loops - - -In Python, you can use loops inside other loops. These are called nested loops and are useful for iterating over multi-dimensional data structures. -```python -for i in range(1, 4): # Outer loop from 1 to 3 - for j in range(1, 3): # Inner loop from 1 to 2 - print(f'Outer: {i}, Inner: {j}') # Print values of outer and inner loops -``` -## 7. Loop Else Clause - - -Python also provides an `else` clause that can be used with loops. The block under `else` is executed if the loop completes without hitting a `break` statement. -```python -for num in range(1, 4): # Loop through numbers from 1 to 3 - print(num) # Print the current value of 'num' -else: # Execute after the loop ends - print('Loop completed successfully.') # Print a success message -``` \ No newline at end of file diff --git a/docs/languages/python/py-4.md b/docs/languages/python/py-4.md deleted file mode 100644 index e2a3e9e4a..000000000 --- a/docs/languages/python/py-4.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: decision-making-in-python -sidebar_position: 3 -title: Decision Making in Python -sidebar_label: Decision Making in Python ---- - -Hey there! In this guide, we'll explore decision-making in Python. Decision-making constructs allow you to execute code based on certain conditions. Let's dive in! - -## Decision Making - -* Python supports several decision-making constructs that allow you to execute code based on conditions. - -* We will go over the different decision-making options available in Python. -## 1. If Statements - - -The simplest decision-making structure in Python is the if statement, which executes a block of code if a certain condition is met. -```python -num = 8 # Initialize variable 'num' with a value of 8 -if num > 0: # Check if the value of 'num' is greater than 0 - print('The number is positive.') # Print a message if the condition is true -``` -## 2. If-Else Statements - - -The if-else statement allows you to execute one block of code if the condition is true, and another if the condition is false. -```python -num = 11 # Initialize variable 'num' with a value of 11 -if num % 2 == 0: # Check if 'num' is even - print('The number is even.') # Print this message if 'num' is even -else: # Otherwise, execute this block - print('The number is odd.') # Print this message if 'num' is odd -``` -## 3. Else If (Elif) Statements - - -The elif statement (short for else if) allows you to check multiple conditions in sequence and execute the first block of code where the condition is true. -```python -num = 15 # Initialize variable 'num' with a value of 15 -if num > 20: # Check if 'num' is greater than 20 - print('The number is greater than 20.') # Print this message if 'num' is greater than 20 -elif num == 15: # Check if 'num' is equal to 15 - print('The number is 15.') # Print this message if 'num' is equal to 15 -else: # Otherwise, execute this block - print('The number is less than 20.') # Print this message if 'num' is less than 20 -``` -## 4. Nested If Statements - - -You can use if statements inside other if statements, known as nested if statements, to evaluate more complex conditions. -```python -num = 7 # Initialize variable 'num' with a value of 7 -if num > 0: # Check if 'num' is positive - if num < 10: # Check if 'num' is less than 10 - print('The number is positive and less than 10.') # Print this message if both conditions are true -``` -## 5. Ternary Operator - - -Python also supports a shorthand for the if-else statement, called the ternary operator. -```python -age = 18 # Initialize variable 'age' with a value of 18 -can_vote = 'Yes' if age >= 18 else 'No' # Use the ternary operator to check if 'age' is 18 or older -print(can_vote) # Output: 'Yes' -``` -## 6. Switch Statements (Python 3.10+) - - -From Python 3.10, the match-case statement is introduced, which works similarly to a switch statement in other languages. -```python -day = 2 # Initialize variable 'day' with a value of 2 -match day: # Use match-case to determine the day of the week - case 1: - print('Monday') # Execute if 'day' is 1 - case 2: - print('Tuesday') # Execute if 'day' is 2 - case 3: - print('Wednesday') # Execute if 'day' is 3 - case _: # Default case - print('Invalid day') # Execute if none of the above cases match -``` \ No newline at end of file diff --git a/docs/languages/python/py-5.md b/docs/languages/python/py-5.md deleted file mode 100644 index 36a9bfb63..000000000 --- a/docs/languages/python/py-5.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: usage-of-sets-in-python -sidebar_position: 5 -title: Sets in Python -sidebar_label: Sets in Python ---- - -Hey there! In this guide, we'll explore sets in Python. Sets are unordered collections of unique elements that allow you to perform various operations like union, intersection, and difference. Let's dive in! - -# Python Sets - - -* Sets are unordered collections of unique elements. - -* They are mutable, which means you can change their contents after creation. -## 1. Creating a Set - - -You can create a set using curly braces `{}` or the `set()` function. -```python -my_set = {1, 2, 3, 4} # Create a set using curly braces -another_set = set([3, 4, 5, 6]) # Create a set using the set() function -print(my_set) # Output: {1, 2, 3, 4} -print(another_set) # Output: {3, 4, 5, 6} -``` -## 2. Accessing Elements - - -Sets do not support indexing, but you can check for the existence of an element using the `in` keyword. -```python -my_set = {1, 2, 3, 4} # Define a set -print(2 in my_set) # Check if 2 is in the set, Output: True -print(5 in my_set) # Check if 5 is in the set, Output: False -``` -## 3. Adding Elements - - -You can add elements to a set using the `add()` method. -```python -my_set.add(5) # Add an element to the set -print(my_set) # Output: {1, 2, 3, 4, 5} -``` -## 4. Removing Elements - - -To remove elements, you can use the `remove()` method or the `discard()` method. -```python -my_set.remove(3) # Remove an element (raises error if not found) -print(my_set) # Output: {1, 2, 4, 5} -my_set.discard(2) # Remove an element (does not raise error if not found) -print(my_set) # Output: {1, 4, 5} -``` -## 5. Set Operations - - -Sets support various mathematical operations like union, intersection, and difference. -```python -set1 = {1, 2, 3} # Define the first set -set2 = {3, 4, 5} # Define the second set -union_set = set1 | set2 # Union operation -intersection_set = set1 & set2 # Intersection operation -difference_set = set1 - set2 # Difference operation -print(union_set) # Output: {1, 2, 3, 4, 5} -print(intersection_set) # Output: {3} -print(difference_set) # Output: {1, 2} -``` \ No newline at end of file diff --git a/docs/languages/python/py-6.md b/docs/languages/python/py-6.md deleted file mode 100644 index d1216154f..000000000 --- a/docs/languages/python/py-6.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -id: usage-of-dictionaries-in-python -sidebar_position: 6 -title: Dictionaries in Python -sidebar_label: Dictionaries in Python ---- - -Hey there! In this guide, we'll explore dictionaries in Python. Dictionaries are unordered collections of key-value pairs that allow you to store and manipulate data efficiently. Let's dive in! - -# Python Dictionaries - - -* Dictionaries are unordered collections of key-value pairs. - -* They are mutable, allowing you to change their contents after creation. -## 1. Creating a Dictionary - - -You can create a dictionary using curly braces `{}` or the `dict()` function. -```python -my_dict = {'name': 'John', 'age': 30} # Create a dictionary using curly braces -another_dict = dict(name='Jane', age=25) # Create a dictionary using the dict() function -print(my_dict) # Output: {'name': 'John', 'age': 30} -print(another_dict) # Output: {'name': 'Jane', 'age': 25} -``` -## 2. Accessing Elements - - -You can access values in a dictionary using their keys. -```python -my_dict = {'name': 'John', 'age': 30} # Define a dictionary -print(my_dict['name']) # Access value using key, Output: 'John' -print(my_dict['age']) # Access value using key, Output: 30 -``` -## 3. Adding Elements - - -You can add new key-value pairs to a dictionary using assignment. -```python -my_dict['city'] = 'New York' # Add a new key-value pair -print(my_dict) # Output: {'name': 'John', 'age': 30, 'city': 'New York'} -``` -## 4. Removing Elements - - -You can remove key-value pairs using the `del` statement or the `pop()` method. -```python -del my_dict['age'] # Remove an element using del -print(my_dict) # Output: {'name': 'John', 'city': 'New York'} -age = my_dict.pop('city') # Remove and return an element using pop() -print(age) # Output: 'New York' -print(my_dict) # Output: {'name': 'John'} -``` -## 5. Dictionary Methods - - -Dictionaries have several built-in methods for manipulation. -```python -my_dict = {'name': 'John', 'age': 30} # Define a dictionary -keys = my_dict.keys() # Get all keys -values = my_dict.values() # Get all values -items = my_dict.items() # Get all key-value pairs -print(keys) # Output: dict_keys(['name', 'age']) -print(values) # Output: dict_values(['John', 30]) -print(items) # Output: dict_items([('name', 'John'), ('age', 30)]) -``` \ No newline at end of file diff --git a/docs/languages/python/py-7.md b/docs/languages/python/py-7.md deleted file mode 100644 index 1bf51270c..000000000 --- a/docs/languages/python/py-7.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: usage-of-operators-in-python -sidebar_position: 7 -title: Operators in Python -sidebar_label: Operators in Python ---- - -Hey there! In this guide, we'll explore operators in Python. Operators are special symbols that perform operations on variables and values. Let's dive in! - -# Python Operators - - -* Python supports various types of operators to perform different kinds of operations on variables and values. - -* These operators are grouped into several categories. -## 1. Arithmetic Operators - - -These operators are used to perform basic mathematical operations. -```python -x = 10 # Initialize x -y = 5 # Initialize y -add = x + y # Addition: 10 + 5 = 15 -sub = x - y # Subtraction: 10 - 5 = 5 -mul = x * y # Multiplication: 10 * 5 = 50 -div = x / y # Division: 10 / 5 = 2.0 -mod = x % y # Modulus: 10 % 5 = 0 -exp = x ** y # Exponentiation: 10 ** 5 = 100000 -floordiv = x // y # Floor division: 10 // 5 = 2 -``` -## 2. Comparison Operators - - -These operators are used to compare two values, and they return a Boolean result. -```python -x = 10 # Initialize x -y = 5 # Initialize y -eq = (x == y) # Equal to: False -ne = (x != y) # Not equal to: True -gt = (x > y) # Greater than: True -lt = (x < y) # Less than: False -ge = (x >= y) # Greater than or equal to: True -le = (x <= y) # Less than or equal to: False -``` -## 3. Logical Operators - - -These operators are used to combine conditional statements. -```python -a = True # Initialize a -b = False # Initialize b -logical_and = (a and b) # Logical AND: False -logical_or = (a or b) # Logical OR: True -logical_not = not a # Logical NOT: False -``` -## 4. Assignment Operators - - -These operators are used to assign values to variables. -```python -x = 10 # Assign 10 to x -x += 5 # Add and assign: x = x + 5 -> 15 -x -= 3 # Subtract and assign: x = x - 3 -> 12 -x *= 2 # Multiply and assign: x = x * 2 -> 24 -x /= 4 # Divide and assign: x = x / 4 -> 6.0 -x %= 3 # Modulus and assign: x = x % 3 -> 0 -x //= 2 # Floor divide and assign: x = x // 2 -> 0 -x **= 3 # Exponentiation and assign: x = x ** 3 -> 0 -``` -## 5. Bitwise Operators - - -These operators work on bits and perform bit-level operations. -```python -x = 6 # Binary: 110 -y = 3 # Binary: 011 -bitwise_and = x & y # Bitwise AND: 010 -> 2 -bitwise_or = x | y # Bitwise OR: 111 -> 7 -bitwise_xor = x ^ y # Bitwise XOR: 101 -> 5 -bitwise_not = ~x # Bitwise NOT: 001 -> -7 (two's complement) -shift_left = x << 2 # Left shift: 110 << 2 -> 11000 -> 24 -shift_right = x >> 2 # Right shift: 110 >> 2 -> 001 -> 1 -``` -## 6. Membership Operators - - -These operators test for membership in a sequence, such as strings, lists, or tuples. -```python -my_list = [1, 2, 3, 4] # Define a list -is_in = 2 in my_list # Check if 2 is in the list: True -is_not_in = 5 not in my_list # Check if 5 is not in the list: True -``` -## 7. Identity Operators - - -These operators compare the memory locations of two objects. -```python -x = 5 # Initialize x -y = 5 # Initialize y -is_identical = (x is y) # Check if x and y refer to the same object: True -is_not_identical = (x is not y) # Check if x and y refer to different objects: False -``` \ No newline at end of file diff --git a/docs/languages/python/py-8.md b/docs/languages/python/py-8.md deleted file mode 100644 index e7ebdbde2..000000000 --- a/docs/languages/python/py-8.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: usage-of-python-classes -sidebar_position: 8 -title: Classes in Python -sidebar_label: Classes in Python ---- - -Hey there! In this guide, we'll explore classes in Python. Classes are a fundamental part of object-oriented programming in Python. Let's dive in! - -# Python Classes - - -* Python supports object-oriented programming, and classes are a fundamental part of this paradigm. - -* A class is a blueprint for creating objects, defining their attributes and methods. -## 1. Creating a Simple Class - - -Here's how to define a simple class with attributes and methods. -```python -class Dog: # Define a class named Dog - def __init__(self, name, age): # Constructor method to initialize attributes - self.name = name # Assign name to the instance - self.age = age # Assign age to the instance - def bark(self): # Method to make the dog bark - return 'Woof!' # Return barking sound -``` -## 2. Creating an Object - - -You can create an object (instance) of the class like this: -```python -my_dog = Dog('Buddy', 3) # Create an instance of Dog class -print(my_dog.name) # Access the name attribute: Buddy -print(my_dog.age) # Access the age attribute: 3 -print(my_dog.bark()) # Call the bark method: Woof! -``` -## 3. Class Inheritance - - -Classes can inherit attributes and methods from other classes. -```python -class Animal: # Base class - def __init__(self, species): # Constructor for species - self.species = species # Assign species to the instance -class Cat(Animal): # Cat class inherits from Animal - def __init__(self, name, age): # Constructor method for Cat - super().__init__('Cat') # Call the base class constructor - self.name = name # Assign name to the instance - self.age = age # Assign age to the instance - def meow(self): # Method to make the cat meow - return 'Meow!' # Return meowing sound -``` -## 4. Creating an Inherited Object - - -You can create an object of the inherited class like this: -```python -my_cat = Cat('Whiskers', 2) # Create an instance of Cat class -print(my_cat.species) # Access inherited species attribute: Cat -print(my_cat.name) # Access name attribute: Whiskers -print(my_cat.meow()) # Call the meow method: Meow! -``` -## 5. Class Methods and Static Methods - - -You can define class methods and static methods in a class. -```python -class MathOperations: # Define a class for math operations - @staticmethod # Static method decorator - def add(x, y): # Static method to add two numbers - return x + y # Return the sum - @classmethod # Class method decorator - def multiply(cls, x, y): # Class method to multiply two numbers - return x * y # Return the product -``` -## 6. Using Class and Static Methods - - -Here's how to use the class and static methods: -```python -sum_result = MathOperations.add(5, 10) # Call the static method: 15 -product_result = MathOperations.multiply(5, 10) # Call the class method: 50 -print(sum_result) # Output the sum result -print(product_result) # Output the product result -``` \ No newline at end of file diff --git a/docs/languages/python/py-9.md b/docs/languages/python/py-9.md deleted file mode 100644 index 383f37244..000000000 --- a/docs/languages/python/py-9.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -id: strings-in-python -sidebar_position: 9 -title: Strings in Python -sidebar_label: Strings in Python ---- - -Hey everyone! Today we're going to explore one of the most commonly used data types in Python – strings. If you're just starting with Python or need a quick refresher, this guide will help you understand how strings work in Python. Let's get started! -# Python Strings - - -* A string in Python is a sequence of characters enclosed within single quotes, double quotes, or triple quotes. - -* Strings are immutable, meaning once created, they cannot be changed. -## 1. Defining a String - - -Let's see how you can define a string in Python: -```python -name = 'Python' # Define a string with single quotes -greeting = "Hello, World!" # Define a string with double quotes -long_string = '''This is a long string # Define a multi-line string with triple quotes -that spans multiple lines.''' # Continuing the multi-line string -``` -## 2. Accessing Characters in a String - - -You can access individual characters in a string using indexing: -```python -name = 'Python' # Define a string -first_char = name[0] # Access the first character: 'P' -last_char = name[-1] # Access the last character: 'n' -print(first_char) # Output: 'P' -print(last_char) # Output: 'n' -``` -## 3. Slicing a String - - -You can slice a string to get a substring: -```python -name = 'Python' # Define a string -sub_str = name[0:3] # Slice from index 0 to 2: 'Pyt' -print(sub_str) # Output: 'Pyt' -``` -## 4. String Concatenation - - -You can combine two or more strings using the `+` operator: -```python -first_name = 'John' # Define a first name string -last_name = 'Doe' # Define a last name string -full_name = first_name + ' ' + last_name # Concatenate strings with a space -print(full_name) # Output: 'John Doe' -``` -## 5. String Formatting - - -You can format strings using f-strings, which is an efficient and readable way to include variables in a string: -```python -name = 'Alice' # Define a name string -age = 30 # Define an age variable -message = f'{name} is {age} years old.' # Format string with variables -print(message) # Output: 'Alice is 30 years old.' -``` -## 6. Common String Methods - - -Python provides several built-in methods to work with strings. Here are a few commonly used ones: -```python -text = ' Hello, Python! ' # Define a string with leading and trailing spaces -trimmed_text = text.strip() # Remove leading and trailing spaces: 'Hello, Python!' -uppercase_text = text.upper() # Convert the string to uppercase: ' HELLO, PYTHON! ' -lowercase_text = text.lower() # Convert the string to lowercase: ' hello, python! ' -replaced_text = text.replace('Python', 'World') # Replace 'Python' with 'World': ' Hello, World! ' -print(trimmed_text) # Output: 'Hello, Python!' -print(uppercase_text) # Output: ' HELLO, PYTHON! ' -print(lowercase_text) # Output: ' hello, python! ' -print(replaced_text) # Output: ' Hello, World! ' -``` -## 7. String Length - - -You can get the length of a string using the `len()` function: -```python -text = 'Hello, Python!' # Define a string -length = len(text) # Get the length of the string: 13 -print(length) # Output: 13 -``` \ No newline at end of file diff --git a/docs/linked-list/CircularDoubly.png b/docs/linked-list/CircularDoubly.png deleted file mode 100644 index 08652ba8c9642c90323ffb6941a054e2ab72cc54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3213 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 diff --git a/docs/linked-list/CircularLinkedList.png b/docs/linked-list/CircularLinkedList.png deleted file mode 100644 index 2e2e31ab0fbed1a14f5b9ed3675d649c75e697b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230132 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

    KFjWXCIU2AqRG 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 - //ask user that how many elements they want to insert - printf("\nenter no. of elements_"); - scanf("%d",&x); - //taking user input - printf("\nenter data_"); - scanf("%d",&h->data); - //taking two pointer at start and at the end - p=h; - for(i=1;inext=(node*)malloc(sizeof(node)); - s=p; - p=p->next; - p->prev=s; - p->next=NULL; - printf("\nenter data_"); - scanf("%d",&p->data); - } - head=p; - //can make choice of where side of control user want to start - printf("\nChoice to give control from start or from last if(num =1 last node pointer will be pass)"); - scanf("%d",&num); - if(num==1) - return(h); - return(head); - } - ``` - -2. **Traversal**: - - ```text - void display(node*head) - { - node*p; - p=head; - //checking if the pointer pass from front or from end (in my case but you can create your creativity) - if(p->next!=NULL) - { - printf("\nDLL is:(by going with next)\n"); - while(p!=NULL) - { - printf("%d\t",p->data); - p=p->next; - } - } - else - { - printf("\nDLL is:(by going with previous)\n"); - while(p!=NULL) - { - printf("%d\t",p->data); - p=p->prev; - } - } - } - ``` -3. **Insertion (begining , last , or any location)**: - - ```text - void insertion(node*head) - { - int loc,i; - node*p,*q,*s; - p=(node*)malloc(sizeof(node)); - p->next=p->prev=NULL; - printf("\nenter inerting element_"); - //making your data's node to insert - scanf("%d",&p->data); - //enter location where you want to insert - printf("\nenter location_"); - scanf("%d",&loc); - q=head; - //insertion at begining - if(loc==1) - { - p->next=head; - head->prev=p; - display(p); - } - else - { - for(i=2;inext; - s=q->next; - p->next=s; - s->prev=p; - q->next=p; - p->prev=q; - //see the inserted linked list - display(head); - } - } - ``` -4. **Deletion (at begining , at last , or at any location)**: - - ```text - void delete(node*head) - { - node*p,*q,*s; - int loc,i; - //from where you want to delete - printf("\nenter location_"); - scanf("%d",&loc); - //at begining - if(loc==1) - { - head=head->next; - head->prev=NULL; - //see the deleted DLL - display(head); - } - else - { - p=head; - for(i=2;inext; - q=p->next->next; - p->next=NULL; - p->next=q; - q->prev=p; - //see the deleted DLL - display(head); - } - } - ``` -5. **Main function**: - - ```text - void main() - { - node*head; - printf("Doubly Linked list\n"); - //creating function - head=create(); - //display function - display(head); - //insertion function - insertion(head); - //delete function - delete(head); - } - ``` -### Complexity - -- **Time Complexity**: - - - Traversal: $O(n)$ - - Insertion : $O(1)$ - - Deletion: $O(1)$ - -- **Space Complexity**: $O(1)$ - -### Advantages: - - -Bidirectional traversal: You can traverse the list both forward and backward. - -Efficient insertion and deletion: Insertion and deletion operations are efficient at both ends of the list as well as in the middle, as you don’t need to shift elements like you would in an array. - -### Disadvantages: - -**Extra memory**: - Each node requires additional memory for storing the pointer to the previous node. -**More complex code**: - The management of two pointers (previous and next) makes the implementation more complex than a singly linked list. - -### Use Cases: - -**Browser History**: - Moving forward and backward through previously visited pages. -**Undo/Redo Operations**: - Navigating through changes in a document or application. -**Navigation systems**: - Efficiently traversing elements in both directions in applications such as playlists or slideshows. - -### Conclusion - -In this **C** implementation, we cover fundamental operations such as inserting and deleting nodes at both ends, as well as traversing the list in both directions. Understanding doubly linked lists is essential for mastering dynamic data structures and memory management in **C**. diff --git a/docs/linked-list/DoublyLL.png b/docs/linked-list/DoublyLL.png deleted file mode 100644 index bc2dd8bf764bec7c03faf1b69d9cb711a66d4da0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199538 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%0AgNpx_4yq?1!>0>(nS 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

    h1+sxFAx)L{-IN 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 Wzhzd`!|7AtPg(xHT!F0Vi~j=luNpA` diff --git a/docs/linked-list/Hare-Tortoise.md b/docs/linked-list/Hare-Tortoise.md deleted file mode 100644 index 94812e7f5..000000000 --- a/docs/linked-list/Hare-Tortoise.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -id: introduction-to-LinkedList -title: Hare and Tortoise Algorithm -sidebar_label: Introduction to Hare and Tortoise Algorithm -sidebar_position: 11 -description: The Hare and Tortoise Algorithm, also known as Floyd's Cycle Detection Algorithm, is a method used to detect cycles in a linked list. It employs two pointers that move at different speeds to identify whether a cycle exists. - -tags: [dsa, data-structures,Hare and Tortoise Algorithm] ---- - - -### Defination: - -The Hare and Tortoise Algorithm, also known as Floyd's Cycle Detection Algorithm, is a method used to detect cycles in a linked list. It employs two pointers that move at different speeds to identify whether a cycle exists. - -### Characteristics: - -- **Two Pointer Technique**: -- The algorithm uses two pointers: a tortoise that moves one step at a time and a hare that moves two steps at a time. - -- **Cycle Detection**: -- If the linked list contains a cycle, the fast-moving hare will eventually meet the slow-moving tortoise. - --**Space Efficiency**: -The algorithm uses a constant amount of space (O(1)), making it very efficient. - --**Applicable to Linked Lists**: -- It is specifically designed to work with linked lists, where the next node is accessed through pointers. - -### Time Complexity: - -- **Best, Average, and Worst Case: O(N)** - - In the worst case, both pointers traverse the entire list, leading to linear time complexity, where n is the number of nodes in the linked list. - -- **Space Complexity: O(1)** -- The algorithm only uses two pointers regardless of the input size, resulting in constant space complexity. - -### C++ Implementation: - -```cpp -#include - -struct ListNode { - int value; - ListNode* next; - ListNode(int val) : value(val), next(nullptr) {} -}; - -bool hasCycle(ListNode* head) { - ListNode* tortoise = head; - ListNode* hare = head; - - while (hare != nullptr && hare->next != nullptr) { - tortoise = tortoise->next; // Move tortoise by 1 step - hare = hare->next->next; // Move hare by 2 steps - - if (tortoise == hare) { - return true; // Cycle detected - } - } - - return false; // No cycle -} - -int main() { - // Creating a linked list with a cycle for testing - ListNode* head = new ListNode(1); - head->next = new ListNode(2); - head->next->next = new ListNode(3); - head->next->next->next = new ListNode(4); - head->next->next->next->next = head->next; // Creating a cycle - - if (hasCycle(head)) { - std::cout << "Cycle detected in the linked list." << std::endl; - } else { - std::cout << "No cycle detected in the linked list." << std::endl; - } - - // Clean up memory (not reached due to cycle) - return 0; -} - - -``` - -### JAVA Implementation: - -```java -class ListNode { - int value; - ListNode next; - - ListNode(int val) { - this.value = val; - this.next = null; - } -} - -public class CycleDetection { - - public static boolean hasCycle(ListNode head) { - ListNode tortoise = head; - ListNode hare = head; - - while (hare != null && hare.next != null) { - tortoise = tortoise.next; // Move tortoise by 1 step - hare = hare.next.next; // Move hare by 2 steps - - if (tortoise == hare) { - return true; // Cycle detected - } - } - - return false; // No cycle - } - - public static void main(String[] args) { - // Creating a linked list with a cycle for testing - ListNode head = new ListNode(1); - head.next = new ListNode(2); - head.next.next = new ListNode(3); - head.next.next.next = new ListNode(4); - head.next.next.next.next = head.next; // Creating a cycle - - if (hasCycle(head)) { - System.out.println("Cycle detected in the linked list."); - } else { - System.out.println("No cycle detected in the linked list."); - } - } -} - - -``` - -### Python Implementation: -```py -class ListNode: - def __init__(self, value=0, next=None): - self.value = value - self.next = next - -def has_cycle(head): - tortoise = head - hare = head - - while hare and hare.next: - tortoise = tortoise.next # Move tortoise by 1 step - hare = hare.next.next # Move hare by 2 steps - - if tortoise == hare: - return True # Cycle detected - - return False # No cycle - -if __name__ == "__main__": - # Creating a linked list with a cycle for testing - head = ListNode(1) - head.next = ListNode(2) - head.next.next = ListNode(3) - head.next.next.next = ListNode(4) - head.next.next.next.next = head.next # Creating a cycle - - if has_cycle(head): - print("Cycle detected in the linked list.") - else: - print("No cycle detected in the linked list.") - - -``` - -### Summary: - -The Hare and Tortoise Algorithm is an efficient method for detecting cycles in a linked list using a two-pointer technique. It operates in linear time and constant space, making it a widely used approach in various applications involving linked data structures. diff --git a/docs/linked-list/Intersection_Linked_list_python.md b/docs/linked-list/Intersection_Linked_list_python.md deleted file mode 100644 index 797277d5d..000000000 --- a/docs/linked-list/Intersection_Linked_list_python.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: intersection-linked-lists-python -sidebar_position: 1 -title: "Find the Intersection Point of Two Linked Lists in Python using hash set" -description: "This tutorial explains how to find the intersection point of two singly linked lists using Python." -sidebar_label: "Linked List Intersection" -tags: [dsa, linked-lists, intersection,python,hash-set] ---- - -# Intersection of Two Linked Lists - -## Problem Statement - -In a linked list, the intersection of two lists occurs when two linked lists share a common node. Given two linked lists, this problem aims to find the node where the two lists intersect. If they do not intersect, the result should be `None`. - -### Example - -Consider the following two linked lists: - -- **List A**: `1 -> 2 -> 3` -- **List B**: `4 -> 5` -- Both lists intersect at the node with value `3`. - -The expected output in this case is: - - -## Approach - -To solve this problem, we can use a hash set to store the nodes of the first linked list. As we traverse the second linked list, we can check if any node exists in the set. If we find a match, that node is the intersection point. - -### Steps: - -1. Traverse the first linked list and add each node to a set. -2. Traverse the second linked list and check if any node is in the set. -3. If a node is found in the set, return that node as the intersection. -4. If no nodes match, return `None`. - -## Python Code - -Below is the implementation of the solution in Python: - -```python -class ListNode: - def __init__(self, x): - self.val = x - self.next = None - -class Solution: - def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: - # Using a set to store the nodes of the first linked list - seen_nodes = set() - curr = headA - - while curr: - seen_nodes.add(curr) # Add the current node to the set - curr = curr.next - - curr2 = headB - while curr2: - if curr2 in seen_nodes: # Check if current node is in the set - return curr2 # Intersection found - curr2 = curr2.next - - return None # No intersection - -# Helper function to create a linked list from a list -def create_linked_list(values): - if not values: - return None - head = ListNode(values[0]) - curr = head - for value in values[1:]: - curr.next = ListNode(value) - curr = curr.next - return head - -# Example usage -if __name__ == "__main__": - # Create linked lists for the example - # List A: 1 -> 2 -> 3 - # List B: 4 -> 5 - # Intersection at node with value 3 - intersection_node = ListNode(3) - - headA = create_linked_list([1, 2]) - headA.next.next = intersection_node # Connect intersection - headB = create_linked_list([4, 5]) - headB.next.next = intersection_node # Connect intersection - - solution = Solution() - intersection = solution.getIntersectionNode(headA, headB) - - if intersection: - print(f"Intersection at node with value: {intersection.val}") - else: - print("No intersection") -``` \ No newline at end of file diff --git a/docs/linked-list/LinkedList.png b/docs/linked-list/LinkedList.png deleted file mode 100644 index 31974c45af5df3249083c1b17c7bc4eff6cb86db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53702 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 -using namespace std; - -struct Node { - int coeff; - int exp; - Node* next; - Node(int c, int e) : coeff(c), exp(e), next(nullptr) {} // Constructor for easy initialization -}; - -// Function to insert a term at the end of the polynomial -void insertTerm(Node*& head, int coeff, int exp) { - Node* newNode = new Node(coeff, exp); - if (head == nullptr) { - head = newNode; - } else { - Node* temp = head; - while (temp->next != nullptr) { - temp = temp->next; - } - temp->next = newNode; - } -} - -// Function to display the polynomial in a formatted way -void displayPolynomial(Node* head) { - Node* temp = head; - bool isFirstTerm = true; - - while (temp != nullptr) { - // Adjust display for x^1 and x^0 cases - if (temp->exp == 1) { - cout << (temp->coeff > 0 && !isFirstTerm ? " + " : "") << temp->coeff << "x"; - } else if (temp->exp == 0) { - cout << (temp->coeff > 0 && !isFirstTerm ? " + " : "") << temp->coeff; - } else { - cout << (temp->coeff > 0 && !isFirstTerm ? " + " : "") << temp->coeff << "x^" << temp->exp; - } - temp = temp->next; - isFirstTerm = false; - } - cout << endl; -} - -// Function to add two polynomials and return the resulting polynomial -Node* addPolynomials(Node* poly1, Node* poly2) { - Node* result = nullptr; - Node* p1 = poly1; - Node* p2 = poly2; - - while (p1 != nullptr && p2 != nullptr) { - if (p1->exp > p2->exp) { - insertTerm(result, p1->coeff, p1->exp); - p1 = p1->next; - } else if (p1->exp < p2->exp) { - insertTerm(result, p2->coeff, p2->exp); - p2 = p2->next; - } else { - int sumCoeff = p1->coeff + p2->coeff; - if (sumCoeff != 0) { // Only add non-zero coefficients - insertTerm(result, sumCoeff, p1->exp); - } - p1 = p1->next; - p2 = p2->next; - } - } - - // Insert remaining terms from either polynomial if any are left - while (p1 != nullptr) { - insertTerm(result, p1->coeff, p1->exp); - p1 = p1->next; - } - while (p2 != nullptr) { - insertTerm(result, p2->coeff, p2->exp); - p2 = p2->next; - } - - return result; -} - -int main() { - Node* poly1 = nullptr; - Node* poly2 = nullptr; - Node* result = nullptr; - int n, coeff, exp; - cout << "Enter the number of terms for the first polynomial: "; - cin >> n; - for (int i = 0; i < n; i++) { - cout << "Enter coefficient and exponent for term " << i + 1 << ": "; - cin >> coeff >> exp; - insertTerm(poly1, coeff, exp); - } - cout << "Enter the number of terms for the second polynomial: "; - cin >> n; - for (int i = 0; i < n; i++) { - cout << "Enter coefficient and exponent for term " << i + 1 << ": "; - cin >> coeff >> exp; - insertTerm(poly2, coeff, exp); - } - cout << "First Polynomial: "; - displayPolynomial(poly1); - cout << "Second Polynomial: "; - displayPolynomial(poly2); - result = addPolynomials(poly1, poly2); - cout << "Sum of Polynomials: "; - displayPolynomial(result); - return 0; -} -``` diff --git a/docs/linked-list/Practice-Problems.md b/docs/linked-list/Practice-Problems.md deleted file mode 100644 index b72706b3b..000000000 --- a/docs/linked-list/Practice-Problems.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -id: practice-problems-on-linked-list -title: Practice Problems -sidebar_label: Practice Problems -sidebar_position: 16 -Description: Here are some practice problems for Linked List data structure divided into topic-wise and difficulty wise. -tags: [DSA, algorithms,linked list, dsa] ---- - -### 1. Basic Operations on Linked List - - - [Reverse a Linked List](https://leetcode.com/problems/reverse-linked-list/description/) - - [Middle of the Linked List](https://leetcode.com/problems/middle-of-the-linked-list/description/) - - [Length of Linked List](https://practice.geeksforgeeks.org/problems/find-length-of-loop/1) - - [Delete Node in a Linked List](https://leetcode.com/problems/delete-node-in-a-linked-list/description/) - - [Swap Nodes in Pairs](https://leetcode.com/problems/swap-nodes-in-pairs/description/) - - [Rotate List](https://leetcode.com/problems/rotate-list/description/) - -### 2. Two Pointer Technique - - - [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/) - - [Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) - - [Remove N-th Node from End](https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/) - - [Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/description/) - - [Split Linked List in Parts](https://leetcode.com/problems/split-linked-list-in-parts/description/) - -### 3. Linked List Merging - - - [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/description/) - - [Add Two Numbers](https://leetcode.com/problems/add-two-numbers/description/) - - [Merge in Between Linked Lists](https://leetcode.com/problems/merge-in-between-linked-lists/description/) - - [Sort List](https://leetcode.com/problems/sort-list/description/) - - [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/description/) - -### 4. Circular Linked List - - [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/) - - [Split Circular List](https://www.geeksforgeeks.org/problems/split-a-circular-linked-list-into-two-halves/1/) - - [Find the Winner of the Circular Game](https://leetcode.com/problems/find-the-winner-of-the-circular-game/description/) - - [Sorted insert for circular linked list](https://geeksforgeeks.org/problems/sorted-insert-for-circular-linked-list/1) - -### 5. Doubly Linked List - - - [Flatten a Multilevel List](https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/description/) - - [Reverse Doubly Linked List](https://www.geeksforgeeks.org/problems/reverse-a-doubly-linked-list/1) - - [Design Browser History](https://leetcode.com/problems/design-browser-history/description/) - -### 6. Advanced Linked List Problems - - - [Convert Binary in Linked List to Integer](https://leetcode.com/problems/convert-binary-number-in-a-linked-list-to-integer/description/) - - [Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/description/) - - [Flatten a Linked List](https://www.geeksforgeeks.org/problems/flattening-a-linked-list/1) - - [LRU Cache](https://leetcode.com/problems/lru-cache/description/) - - [Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/description/) - -### 7. Palindrome Linked List - - - [Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/description/) - - [Linked list of strings forms a palindrome](https://www.geeksforgeeks.org/problems/linked-list-of-strings-forms-a-palindrome/0) \ No newline at end of file diff --git a/docs/linked-list/_category_.json b/docs/linked-list/_category_.json deleted file mode 100644 index 43ba7b561..000000000 --- a/docs/linked-list/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Linked List", - "position": 11, - "link": { - "type": "generated-index", - "description": "Learn the most important concepts of Linked list." - } - } \ No newline at end of file diff --git a/docs/linked-list/circular-doubly-linked-list.md b/docs/linked-list/circular-doubly-linked-list.md deleted file mode 100644 index 36dfb7acb..000000000 --- a/docs/linked-list/circular-doubly-linked-list.md +++ /dev/null @@ -1,516 +0,0 @@ ---- -id: introduction-to-CircularDoublyLinkedList -title: Circular Doubly Linked List Data Structure -sidebar_label: Introduction to Circular Doubly Linked List -sidebar_position: 3 -description: 'A Circular Doubly Linked List is a variation of a doubly linked list in which the last node points back to the first node, and the first node points to the last node.' -tags: [dsa, data-structures, Circular Doubly Linked List] ---- - -### Introduction to Circular Doubly Linked List - -A **Circular Doubly Linked List** is a variation of a doubly linked list in which the last node points back to the first node, and the first node points to the last node. Each node contains three parts: -- Value: The data value stored in the node. -- Next Pointer: A pointer/reference to the next node in the list. -- Previous Pointer: A pointer/reference to the previous node in the list. - - -![alt text](CircularDoubly.png) - - -### Circular Doubly Linked List Operations - -A Circular Doubly Linked List typically supports the following operations: - -1. **Insertion Operations** : Insertion at the beginning or end involves adjusting the next pointers, previous pointer and potentially updating the head pointer. -- **At the Beginning** -- **At the End** -- **After a Given Node** - -2. **Deletion Operations** : Deletion of nodes, whether from the beginning, end, or a specific node, requires properly updating the references of adjacent nodes. -- **Delete from the Beginning** -- **Delete from the End** -- **Delete by Key** - -3. **Search Operation** : The search operation traverses the list until it either finds the required node or returns to the head. - -4. **Traversal Operation** : Traversal begins from the head and continues until the node just before the head is encountered again. - -### Pseudocode - -#### Basic Operations - -1. **Insert at the Beginning**: - - ```text - function insertAtBeginning(list : CircularDoublyLinkedList, value : DataType) { - newNode = new Node(value) - if list.head is null { - newNode.next = newNode - newNode.prev = newNode - list.head = newNode - } else { - newNode.next = list.head - newNode.prev = list.tail - list.tail.next = newNode - list.head.prev = newNode - list.head = newNode - } - } - ``` - -2. **Insert at the End**: - - ```text - function insertAtEnd(list : CircularDoublyLinkedList, value : DataType) { - newNode = new Node(value) - if list.head is null { - newNode.next = newNode - newNode.prev = newNode - list.head = newNode - } else { - newNode.next = list.head - newNode.prev = list.tail - list.tail.next = newNode - list.head.prev = newNode - } - list.tail = newNode - } - ``` - -3. **Insert After a Given Node**: - - ```text - function insertAfter(list : CircularDoublyLinkedList, node : Node, value : DataType) { - if node is null { - return // Invalid node - } - newNode = new Node(value) - newNode.next = node.next - newNode.prev = node - - node.next.prev = newNode - node.next = newNode - - if node is list.tail { - list.tail = newNode // Update tail if necessary - } - } - - ``` - -4. **Delete a Node**: - - ```text - function deleteNode(list : CircularDoublyLinkedList, node : Node) { - if node is null { - return // Invalid node - } - if node.next is node { // Only node in the list - list.head = null - } else { - node.prev.next = node.next - node.next.prev = node.prev - - if node is list.head { - list.head = node.next // Update head if necessary - } - if node is list.tail { - list.tail = node.prev // Update tail if necessary - } - } - } - - ``` - -5. **Traverse Forward**: - - ```text - function traverseForward(list : CircularDoublyLinkedList) { - if list.head is null { - return // List is empty - } - current = list.head - do { - print(current.value) - current = current.next - } while current is not list.head - } - - ``` - -6. **Traverse Backward** - - ```text - function traverseBackward(list : CircularDoublyLinkedList) { - if list.tail is null { - return // List is empty - } - current = list.tail - do { - print(current.value) - current = current.prev - } while current is not list.tail - } - ``` - - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -class Node: - def __init__(self, value): - self.value = value - self.next = None - self.prev = None - -class CircularDoublyLinkedList: - def __init__(self): - self.head = None - self.tail = None - - def insert_at_beginning(self, value): - new_node = Node(value) - if not self.head: - new_node.next = new_node - new_node.prev = new_node - self.head = new_node - self.tail = new_node - else: - new_node.next = self.head - new_node.prev = self.tail - self.tail.next = new_node - self.head.prev = new_node - self.head = new_node - - def insert_at_end(self, value): - new_node = Node(value) - if not self.head: - new_node.next = new_node - new_node.prev = new_node - self.head = new_node - self.tail = new_node - else: - new_node.next = self.head - new_node.prev = self.tail - self.tail.next = new_node - self.head.prev = new_node - self.tail = new_node - - def insert_after(self, prev_node, value): - if prev_node is None: - return - new_node = Node(value) - new_node.next = prev_node.next - new_node.prev = prev_node - prev_node.next.prev = new_node - prev_node.next = new_node - if prev_node is self.tail: - self.tail = new_node - - def delete_node(self, node): - if node is None: - return - if node.next == node: # Only one node - self.head = None - self.tail = None - else: - node.prev.next = node.next - node.next.prev = node.prev - if node is self.head: - self.head = node.next - if node is self.tail: - self.tail = node.prev - - def traverse_forward(self): - if not self.head: - return - current = self.head - while True: - print(current.value, end=' ') - current = current.next - if current == self.head: - break - print() - - def traverse_backward(self): - if not self.tail: - return - current = self.tail - while True: - print(current.value, end=' ') - current = current.prev - if current == self.tail: - break - print() - -# Example Usage -if __name__ == "__main__": - circular_dll = CircularDoublyLinkedList() - circular_dll.insert_at_beginning(10) - circular_dll.insert_at_end(20) - circular_dll.insert_at_end(30) - circular_dll.insert_at_beginning(5) - circular_dll.traverse_forward() # Output: 5 10 20 30 - circular_dll.traverse_backward() # Output: 30 20 10 5 - -``` - -#### C++ Implementation - -```cpp -#include -using namespace std; - -class Node { -public: - int value; - Node* next; - Node* prev; - - Node(int value) { - this->value = value; - this->next = nullptr; - this->prev = nullptr; - } -}; - -class CircularDoublyLinkedList { -public: - Node* head; - Node* tail; - - CircularDoublyLinkedList() { - head = nullptr; - tail = nullptr; - } - - void insertAtBeginning(int value) { - Node* newNode = new Node(value); - if (!head) { // If the list is empty - newNode->next = newNode; - newNode->prev = newNode; - head = newNode; - tail = newNode; - } else { - newNode->next = head; - newNode->prev = tail; - tail->next = newNode; - head->prev = newNode; - head = newNode; - } - } - - void insertAtEnd(int value) { - Node* newNode = new Node(value); - if (!head) { // If the list is empty - newNode->next = newNode; - newNode->prev = newNode; - head = newNode; - tail = newNode; - } else { - newNode->next = head; - newNode->prev = tail; - tail->next = newNode; - head->prev = newNode; - tail = newNode; - } - } - - void insertAfter(Node* prevNode, int value) { - if (prevNode == nullptr) return; - Node* newNode = new Node(value); - newNode->next = prevNode->next; - newNode->prev = prevNode; - prevNode->next->prev = newNode; - prevNode->next = newNode; - if (prevNode == tail) { - tail = newNode; - } - } - - void deleteNode(Node* node) { - if (node == nullptr) return; - if (node->next == node) { // Only one node - head = nullptr; - tail = nullptr; - } else { - node->prev->next = node->next; - node->next->prev = node->prev; - if (node == head) { - head = node->next; - } - if (node == tail) { - tail = node->prev; - } - } - } - - void traverseForward() { - if (!head) return; - Node* current = head; - do { - cout << current->value << " "; - current = current->next; - } while (current != head); - cout << endl; - } - - void traverseBackward() { - if (!tail) return; - Node* current = tail; - do { - cout << current->value << " "; - current = current->prev; - } while (current != tail); - cout << endl; - } -}; - -// Example Usage -int main() { - CircularDoublyLinkedList circularDLL; - circularDLL.insertAtBeginning(10); - circularDLL.insertAtEnd(20); - circularDLL.insertAtEnd(30); - circularDLL.insertAtBeginning(5); - circularDLL.traverseForward(); // Output: 5 10 20 30 - circularDLL.traverseBackward(); // Output: 30 20 10 5 - return 0; -} -``` - -#### Java Implementation - -```java -class Node { - int value; - Node next; - Node prev; - - Node(int value) { - this.value = value; - this.next = null; - this.prev = null; - } -} - -class CircularDoublyLinkedList { - Node head; - Node tail; - - CircularDoublyLinkedList() { - head = null; - tail = null; - } - - void insertAtBeginning(int value) { - Node newNode = new Node(value); - if (head == null) { - newNode.next = newNode; - newNode.prev = newNode; - head = newNode; - tail = newNode; - } else { - newNode.next = head; - newNode.prev = tail; - tail.next = newNode; - head.prev = newNode; - head = newNode; - } - } - - void insertAtEnd(int value) { - Node newNode = new Node(value); - if (head == null) { - newNode.next = newNode; - newNode.prev = newNode; - head = newNode; - tail = newNode; - } else { - newNode.next = head; - newNode.prev = tail; - tail.next = newNode; - head.prev = newNode; - tail = newNode; - } - } - - void insertAfter(Node prevNode, int value) { - if (prevNode == null) return; - Node newNode = new Node(value); - newNode.next = prevNode.next; - newNode.prev = prevNode; - prevNode.next.prev = newNode; - prevNode.next = newNode; - if (prevNode == tail) { - tail = newNode; - } - } - - void deleteNode(Node node) { - if (node == null) return; - if (node.next == node) { // Only one node - head = null; - tail = null; - } else { - node.prev.next = node.next; - node.next.prev = node.prev; - if (node == head) { - head = node.next; - } - if (node == tail) { - tail = node.prev; - } - } - } - - void traverseForward() { - if (head == null) return; - Node current = head; - do { - System.out.print(current.value + " "); - current = current.next; - } while (current != head); - System.out.println(); - } - - void traverseBackward() { - if (tail == null) return; - Node current = tail; - do { - System.out.print(current.value + " "); - current = current.prev; - } while (current != tail); - System.out.println(); - } - - // Example Usage - public static void main(String[] args) { - CircularDoublyLinkedList circularDLL = new CircularDoublyLinkedList(); - circularDLL.insertAtBeginning(10); - circularDLL.insertAtEnd(20); - circularDLL.insertAtEnd(30); - circularDLL.insertAtBeginning(5); - circularDLL.traverseForward(); // Output: 5 10 20 30 - circularDLL.traverseBackward(); // Output: 30 20 10 5 - } -} -``` - -### Complexity - -- **Time Complexity**: - - - Insertion : $O(1)$ - - Deletion: $O(1)$ - - Traversal: $O(n)$ - -- **Space Complexity**: $O(1)$ - - -### Conclusion - -The Circular Doubly Linked List (CDLL) is a versatile data structure that combines the advantages of both doubly linked lists and circular linked lists. By allowing traversal in both forward and backward directions, CDLLs facilitate efficient data manipulation and navigation. \ No newline at end of file diff --git a/docs/linked-list/doubly-linked-list.md b/docs/linked-list/doubly-linked-list.md deleted file mode 100644 index 9002d551a..000000000 --- a/docs/linked-list/doubly-linked-list.md +++ /dev/null @@ -1,410 +0,0 @@ ---- -id: introduction-to-DoublyLinkedList -title: Doubly Linked List Data Structure -sidebar_label: Introduction to Doubly Linked List -sidebar_position: 4 -description: 'A Doubly Linked List (DLL) is a type of linked data structure that consists of nodes. Each node contains three fields: data, a pointer to the next node, and a pointer to the previous node. This structure allows traversal in both directions—forward and backward.' -tags: [dsa, data-structures, Doubly LinkedList] ---- - -### Introduction to Doubly Linked List - -A **Doubly LinkedList** is a variation of a linked list where the last node points back to the first node instead of null (or None in Python). This structure allows for a Doubly traversal where one can start from any node and eventually return to the same node. Doubly linked lists can be either singly or doubly linked. - -![alt text](DoublyLL.png) - - -### Doubly LinkedList Operations - -A Doubly LinkedList typically supports the following operations: - -1. **Insertion Operations** : Insertion at the beginning or end involves adjusting the next pointers to maintain the Doubly nature, and potentially updating the head pointer. -- **At the Beginning** -- **At the End** -- **After a Given Node** - -2. **Deletion Operations** : Deletion of nodes, whether from the beginning, end, or a specific node, requires properly updating the references of adjacent nodes so that the Doubly structure is maintained. -- **Delete from the Beginning** -- **Delete from the End** -- **Delete by Key** - -3. **Search Operation** : The search operation traverses the list until it either finds the required node or returns to the head. - -4. **Traversal Operation** : Traversal begins from the head and continues until the node just before the head is encountered again. - -### Pseudocode - -#### Basic Operations - -1. **Insert at the Beginning**: - - ```text - function insertAtBeginning(list : DoublyLinkedList, value : DataType) { - newNode = new Node(value) - if list.head is null { - list.head = newNode - list.tail = newNode - } else { - newNode.next = list.head - list.head.prev = newNode - list.head = newNode - } - } - ``` - -2. **Insert at the End**: - - ```text - function insertAtEnd(list : DoublyLinkedList, value : DataType) { - newNode = new Node(value) - if list.tail is null { - list.head = newNode - list.tail = newNode - } else { - list.tail.next = newNode - newNode.prev = list.tail - list.tail = newNode - } - } - ``` - -3. **Insert after a given node**: - - ```text - function insertAfter(list : DoublyLinkedList, node : Node, value : DataType) { - if node is null { - return // Invalid node - } - newNode = new Node(value) - newNode.next = node.next - newNode.prev = node - - if node.next is not null { - node.next.prev = newNode - } - node.next = newNode - - if node is list.tail { - list.tail = newNode // Update tail if necessary - } - } - ``` - -4. **Delete a Node**: - - ```text - function deleteNode(list : DoublyLinkedList, node : Node) { - if node is null { - return // Invalid node - } - if node.prev is not null { - node.prev.next = node.next - } else { - list.head = node.next // Update head if it's the first node - } - - if node.next is not null { - node.next.prev = node.prev - } else { - list.tail = node.prev // Update tail if it's the last node - } - - // Optional: Clear the node to help with garbage collection - node = null - } - ``` - -5. **Traverse Forward**: - - ```text - function traverseForward(list : DoublyLinkedList) { - current = list.head - while current is not null { - print(current.value) - current = current.next - } - } - ``` - -6. **Traverse Backward** - - ```text - function traverseBackward(list : DoublyLinkedList) { - current = list.tail - while current is not null { - print(current.value) - current = current.prev - } - } - ``` - - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -class Node: - def __init__(self, data): - self.data = data - self.next = None - self.prev = None - - -class DoublyLinkedList: - def __init__(self): - self.head = None - - def insert_at_beginning(self, data): - new_node = Node(data) - new_node.next = self.head - if self.head is not None: - self.head.prev = new_node - self.head = new_node - - def insert_at_end(self, data): - new_node = Node(data) - if self.head is None: - self.head = new_node - return - last = self.head - while last.next: - last = last.next - last.next = new_node - new_node.prev = last - - def delete_node(self, key): - current = self.head - while current: - if current.data == key: - if current.prev: - current.prev.next = current.next - if current.next: - current.next.prev = current.prev - if current == self.head: - self.head = current.next - del current - return - current = current.next - print(f"Node with value {key} not found.") - - def display(self): - current = self.head - while current: - print(current.data, end=" <=> ") - current = current.next - print("None") - - -# Example usage -if __name__ == "__main__": - dll = DoublyLinkedList() - dll.insert_at_end(10) - dll.insert_at_end(20) - dll.insert_at_beginning(5) - dll.display() # Output: 5 <=> 10 <=> 20 <=> None - dll.delete_node(10) - dll.display() # Output: 5 <=> 20 <=> None - -``` - -#### C++ Implementation - -```cpp -#include -using namespace std; - -class Node { -public: - int data; - Node* next; - Node* prev; - - Node(int data) { - this->data = data; - this->next = nullptr; - this->prev = nullptr; - } -}; - -class DoublyLinkedList { -public: - Node* head; - - DoublyLinkedList() { - head = nullptr; - } - - void insertAtBeginning(int data) { - Node* newNode = new Node(data); - newNode->next = head; - if (head != nullptr) { - head->prev = newNode; - } - head = newNode; - } - - void insertAtEnd(int data) { - Node* newNode = new Node(data); - if (head == nullptr) { - head = newNode; - return; - } - Node* last = head; - while (last->next != nullptr) { - last = last->next; - } - last->next = newNode; - newNode->prev = last; e - } - - void deleteNode(int key) { - Node* current = head; - while (current != nullptr) { - if (current->data == key) { - if (current->prev != nullptr) { - current->prev->next = current->next; - } - if (current->next != nullptr) { - current->next->prev = current->prev; - } - if (current == head) { - head = current->next; - } - delete current; - return; - } - current = current->next; - } - cout << "Node with value " << key << " not found." << endl; - } - - void display() { - Node* current = head; - while (current != nullptr) { - cout << current->data << " <=> "; - current = current->next; - } - cout << "None" << endl; - } -}; - -// Example usage -int main() { - DoublyLinkedList dll; - dll.insertAtEnd(10); - dll.insertAtEnd(20); - dll.insertAtBeginning(5); - dll.display(); // Output: 5 <=> 10 <=> 20 <=> None - dll.deleteNode(10); - dll.display(); // Output: 5 <=> 20 <=> None - return 0; -} - -``` - -#### Java Implementation - -```java -class Node { - int data; - Node next; - Node prev; - - public Node(int data) { - this.data = data; - this.next = null; - this.prev = null; - } -} - -class DoublyLinkedList { - Node head; - - public DoublyLinkedList() { - head = null; - } - - public void insertAtBeginning(int data) { - Node newNode = new Node(data); - newNode.next = head; - if (head != null) { - head.prev = newNode; - } - head = newNode; - } - - public void insertAtEnd(int data) { - Node newNode = new Node(data); - if (head == null) { - head = newNode; - return; - } - Node last = head; - while (last.next != null) { - last = last.next; - } - last.next = newNode; - newNode.prev = last; - } - - public void deleteNode(int key) { - Node current = head; - while (current != null) { - if (current.data == key) { - if (current.prev != null) { - current.prev.next = current.next; - } - if (current.next != null) { - current.next.prev = current.prev; - } - if (current == head) { - head = current.next; - } - return; - } - current = current.next; - } - System.out.println("Node with value " + key + " not found."); - } - - public void display() { - Node current = head; - while (current != null) { - System.out.print(current.data + " <=> "); - current = current.next; - } - System.out.println("None"); - } -} - -// Example usage -public class Main { - public static void main(String[] args) { - DoublyLinkedList dll = new DoublyLinkedList(); - dll.insertAtEnd(10); - dll.insertAtEnd(20); - dll.insertAtBeginning(5); - dll.display(); // Output: 5 <=> 10 <=> 20 <=> None - dll.deleteNode(10); - dll.display(); // Output: 5 <=> 20 <=> None - } -} - -``` - -### Complexity - -- **Time Complexity**: - - - Insertion : $O(1)$ - - Deletion: $O(1)$ - - Search: $O(n)$ - - Traversal: $O(n)$ - -- **Space Complexity**: $O(1)$ - - -### Conclusion - -Doubly Linked Lists are powerful and versatile data structures that allow for efficient insertion and deletion from both ends and provides flexibility in traversing the list. \ No newline at end of file diff --git a/docs/linked-list/floyds-cycle-detection.md b/docs/linked-list/floyds-cycle-detection.md deleted file mode 100644 index f776549cd..000000000 --- a/docs/linked-list/floyds-cycle-detection.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: floyds-cycle-detection -title: Floyd's Cycle Detection Algorithm -sidebar_label: Floyd's Cycle Detection -sidebar_position: 3 -description: 'Floyd’s Cycle Detection Algorithm, also called the Tortoise and Hare Algorithm, is a method used to detect cycles in a linked list. It uses two pointers that move at different speeds through the list to determine if a cycle exists.' -tags: [dsa, algorithms, cycle-detection, linkedList] ---- - -### Introduction - -Floyd's Cycle Detection Algorithm, also known as the **Tortoise and Hare** algorithm, is a two-pointer technique used to detect the presence of a cycle in a linked list. Named after the story of the tortoise and the hare, the algorithm relies on two pointers moving at different speeds—one fast and one slow—to identify if a loop exists in a linked list. - -The algorithm efficiently detects cycles with a time complexity of $O(n)$ and does not require extra space, making it a more memory-efficient solution compared to hash-based methods. - -### How the Algorithm Works - -Imagine you have a circular race track, and two runners are running around it. One is slower (the tortoise), and the other is faster (the hare). If the track is circular (i.e., there is a cycle), the faster runner will eventually lap the slower runner. This same concept is applied in Floyd's algorithm for linked lists: - -1. **Two Pointers (Tortoise and Hare)**: - - The **Tortoise** moves one step at a time. - - The **Hare** moves two steps at a time. - -2. **Cycle Detection**: - - If the linked list has a cycle, the hare will eventually meet the tortoise inside the loop. - - If the hare reaches the end of the list (`NULL`), the list is cycle-free. - -### Applications - -- **Cycle Detection in Linked Lists**: The algorithm is widely used in detecting cycles in singly linked lists, particularly in problems related to data structures and algorithms. -- **Cycle Detection in Graphs**: Though not limited to linked lists, variations of this algorithm are also applied to detect cycles in directed and undirected graphs. -- **Fast and Memory-Efficient**: Unlike using hash sets to store visited nodes, Floyd's algorithm uses constant space. - -### Algorithm Steps - -1. Initialize two pointers, `slow` and `fast`, both starting at the head of the linked list. -2. Move the `slow` pointer one step at a time and the `fast` pointer two steps at a time. -3. If there is a cycle, the `slow` and `fast` pointers will eventually meet. -4. If the `fast` pointer reaches the end of the list (i.e., encounters `NULL`), there is no cycle. - -### Pseudocode - -```text -Function detectCycle(head): - If head is NULL: - Return False - Initialize slow = head and fast = head - While fast is not NULL and fast.next is not NULL: - Move slow by one node (slow = slow.next) - Move fast by two nodes (fast = fast.next.next) - If slow == fast: - Return True # Cycle detected - Return False # No cycle detected -``` -### Implementation in C++ - -```cpp -#include -using namespace std; - -class ListNode { -public: - int val; - ListNode* next; - ListNode(int x) : val(x), next(nullptr) {} -}; - -bool hasCycle(ListNode* head) { - if (!head || !head->next) return false; - - ListNode* slow = head; - ListNode* fast = head; - - while (fast && fast->next) { - slow = slow->next; - fast = fast->next->next; - if (slow == fast) { - return true; - } - } - return false; -} - -// Example usage -int main() { - ListNode* head = new ListNode(3); - head->next = new ListNode(2); - head->next->next = new ListNode(0); - head->next->next->next = new ListNode(-4); - head->next->next->next->next = head->next; // Creating a cycle - - if (hasCycle(head)) { - cout << "Cycle detected!" << endl; - } else { - cout << "No cycle." << endl; - } - - return 0; -} -``` -### Time and Space Complexity -- Time Complexity: $O(n)$ -In the worst case, both pointers will traverse the entire list once. -- Space Complexity: $O(1)$ -This algorithm only uses a constant amount of extra memory, regardless of the size of the input. diff --git a/docs/linked-list/gircular-linked-list.md b/docs/linked-list/gircular-linked-list.md deleted file mode 100644 index 34b786750..000000000 --- a/docs/linked-list/gircular-linked-list.md +++ /dev/null @@ -1,640 +0,0 @@ ---- -id: introduction-to-CircularLinkedList -title: Circular Linked List Data Structure -sidebar_label: Introduction to Circular Linked List -sidebar_position: 2 -description: 'A Circular Linked List is a linked data structure where the last node points back to the first node, forming a circle. This structure allows for efficient traversal and can be either singly or doubly linked. ' -tags: [dsa, data-structures, Circular LinkedList] ---- - -### Introduction to Circular Linked List - -A **Circular LinkedList** is a variation of a linked list where the last node points back to the first node instead of null (or None in Python). This structure allows for a circular traversal where one can start from any node and eventually return to the same node. Circular linked lists can be either singly or doubly linked. - -![alt text](CircularLinkedList.png) - - -### Circular LinkedList Operations - -A Circular LinkedList typically supports the following operations: - -1. **Insertion Operations** : Insertion at the beginning or end involves adjusting the next pointers to maintain the circular nature, and potentially updating the head pointer. -- **At the Beginning** -- **At the End** -- **After a Given Node** - -2. **Deletion Operations** : Deletion of nodes, whether from the beginning, end, or a specific node, requires properly updating the references of adjacent nodes so that the circular structure is maintained. -- **Delete from the Beginning** -- **Delete from the End** -- **Delete by Key** - -3. **Search Operation** : The search operation traverses the list until it either finds the required node or returns to the head. - -4. **Traversal Operation** : Traversal begins from the head and continues until the node just before the head is encountered again. - -### Pseudocode - -#### Basic Operations - -1. **Insert at the Beginning**: - - ```text - Function insert_at_beginning(data): - Create new_node with data - If head is NULL: - head = new_node - new_node.next = head # Points to itself - Else: - Set temp = head - While temp.next != head: - Move temp to temp.next # Traverse to last node - Set new_node.next = head - Set temp.next = new_node # Last node points to new_node - Set head = new_node # Update the head to the new node - End Function - ``` - -2. **Insert at the End**: - - ```text - Function insert_at_end(data): - Create new_node with data - If head is NULL: - head = new_node - new_node.next = head # Points to itself - Else: - Set temp = head - While temp.next != head: - Move temp to temp.next # Traverse to last node - Set temp.next = new_node - Set new_node.next = head # New node points to head - End Function - ``` - -3. **Delete Node by Value**: - - ```text - Function insert_after(prev_data, data): - Create new_node with data - If head is NULL: - Exit Function # List is empty - Else: - Set temp = head - While temp.data != prev_data: - Move temp to temp.next - If temp == head: - Print "Node not found" - Exit Function - Set new_node.next = temp.next # Link new_node to temp's next node - Set temp.next = new_node # Link temp to new_node - End Function - ``` - -4. **Search for a Node**: - - ```text - Function delete_beginning(): - If head is NULL: - Exit Function # List is empty - If head.next == head: # Only one node - head = NULL - Else: - Set temp = head - While temp.next != head: - Move temp to temp.next # Traverse to last node - Set temp.next = head.next # Last node points to second node - Set head = head.next # Update head to the second node - End Function - ``` - -5. **Traverse and Print the List**: - - ```text - Function delete_end(): - If head is NULL: - Exit Function # List is empty - If head.next == head: # Only one node - head = NULL - Else: - Set temp = head - Set prev = NULL - While temp.next != head: - Set prev = temp # Keep track of second last node - Move temp to temp.next - Set prev.next = head # Second last node points to head - End Function - ``` - -6. **Deletion of a Specific Node** - - ```text - Function delete_node(key): - If head is NULL: - Exit Function # List is empty - If head.data == key AND head.next == head: # Only one node - head = NULL - Else If head.data == key: - Set temp = head - While temp.next != head: - Move temp to temp.next # Traverse to last node - Set temp.next = head.next # Last node points to second node - Set head = head.next # Update head to the second node - Else: - Set temp = head - Set prev = NULL - While temp.data != key: - Set prev = temp # Keep track of previous node - Move temp to temp.next - If temp == head: - Print "Node not found" - Exit Function - Set prev.next = temp.next # Remove the node by linking prev to temp.next - End Function - ``` - -7. **Traversal (Displaying the List)** - - ```text - Function display(): - If head is NULL: - Print "List is empty" - Else: - Set temp = head - Do: - Print temp.data - Move temp to temp.next - While temp != head - End Function - ``` - -8. **Search for a Node** - - ```text - Function search(key): - If head is NULL: - Return False # List is empty - Set temp = head - Do: - If temp.data == key: - Return True # Node found - Move temp to temp.next - While temp != head - Return False # Node not found - End Function - ``` - - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -class Node: - def __init__(self, data): - self.data = data - self.next = None - -class CircularLinkedList: - def __init__(self): - self.head = None - - def insert_beginning(self, data): - new_node = Node(data) - if not self.head: - self.head = new_node - new_node.next = self.head - else: - temp = self.head - while temp.next != self.head: - temp = temp.next - new_node.next = self.head - temp.next = new_node - self.head = new_node - - def insert_end(self, data): - new_node = Node(data) - if not self.head: - self.head = new_node - new_node.next = self.head - else: - temp = self.head - while temp.next != self.head: - temp = temp.next - temp.next = new_node - new_node.next = self.head - - def insert_after_node(self, target, data): - if not self.head: - print("List is empty") - return - new_node = Node(data) - temp = self.head - while True: - if temp.data == target: - new_node.next = temp.next - temp.next = new_node - return - temp = temp.next - if temp == self.head: - break - print(f"Node with data {target} not found.") - - def delete_by_key(self, key): - if not self.head: - print("List is empty") - return - current = self.head - prev = None - while True: - if current.data == key: - if prev: - prev.next = current.next - else: - # Deleting head - if current.next == self.head: - self.head = None - else: - temp = self.head - while temp.next != self.head: - temp = temp.next - self.head = current.next - temp.next = self.head - return - prev = current - current = current.next - if current == self.head: - break - print(f"Key {key} not found.") - - def search(self, key): - if not self.head: - return False - temp = self.head - while True: - if temp.data == key: - return True - temp = temp.next - if temp == self.head: - break - return False - - def display(self): - nodes = [] - if self.head: - temp = self.head - while True: - nodes.append(temp.data) - temp = temp.next - if temp == self.head: - break - print(" -> ".join(map(str, nodes))) - -# Example Usage -cll = CircularLinkedList() -cll.insert_end(1) - cll.insert_end(2) - cll.insert_end(3) - cll.display() # Output: 1 -> 2 -> 3 - - cll.insert_beginning(0) - cll.display() # Output: 0 -> 1 -> 2 -> 3 - - cll.insert_after_node(2, 2.5) - cll.display() # Output: 0 -> 1 -> 2 -> 2.5 -> 3 - - cll.delete_by_key(2) - cll.display() # Output: 0 -> 1 -> 2.5 -> 3 - - print("Search for 2:", cll.search(2)) # Output: False - print("Search for 2.5:", cll.search(2.5)) # Output: True - -``` - -#### C++ Implementation - -```cpp -#include -using namespace std; - -class Node { -public: - int data; - Node* next; - - Node(int data) { - this->data = data; - this->next = nullptr; - } -}; - -class CircularLinkedList { -public: - Node* head; - - CircularLinkedList() { - head = nullptr; - } - - void append(int data) { - Node* newNode = new Node(data); - if (head == nullptr) { - head = newNode; - newNode->next = head; - } else { - Node* temp = head; - while (temp->next != head) { - temp = temp->next; - } - temp->next = newNode; - newNode->next = head; - } - } - - void insertBeginning(int data) { - Node* newNode = new Node(data); - if (head == nullptr) { - head = newNode; - newNode->next = head; - } else { - Node* temp = head; - while (temp->next != head) - temp = temp->next; - newNode->next = head; - temp->next = newNode; - head = newNode; - } - } - - void insertEnd(int data) { - Node* newNode = new Node(data); - if (head == nullptr) { - head = newNode; - newNode->next = head; - } else { - Node* temp = head; - while (temp->next != head) - temp = temp->next; - temp->next = newNode; - newNode->next = head; - } - } - - void insertAfterNode(int target, int data) { - if (head == nullptr) { - cout << "List is empty" << endl; - return; - } - Node* temp = head; - do { - if (temp->data == target) { - Node* newNode = new Node(data); - newNode->next = temp->next; - temp->next = newNode; - return; - } - temp = temp->next; - } while (temp != head); - cout << "Node with data " << target << " not found." << endl; - } - - void deleteByKey(int key) { - if (head == nullptr) { - cout << "List is empty" << endl; - return; - } - Node* current = head; - Node* prev = nullptr; - do { - if (current->data == key) { - if (prev != nullptr) { - prev->next = current->next; - } else { - // Deleting head - if (current->next == head) { - head = nullptr; - } else { - Node* temp = head; - while (temp->next != head) - temp = temp->next; - head = current->next; - temp->next = head; - } - } - delete current; - return; - } - prev = current; - current = current->next; - } while (current != head); - cout << "Key " << key << " not found." << endl; - } - - bool search(int key) { - if (head == nullptr) - return false; - Node* temp = head; - do { - if (temp->data == key) - return true; - temp = temp->next; - } while (temp != head); - return false; - } - - void display() { - if (head != nullptr) { - Node* temp = head; - do { - cout << temp->data << " -> "; - temp = temp->next; - } while (temp != head); - cout << endl; - } - } -}; - -// Example Usage -int main() { - CircularLinkedList cll; - cll.insertEnd(1); - cll.insertEnd(2); - cll.insertEnd(3); - cll.display(); // Output: 1 -> 2 -> 3 -> - - cll.insertBeginning(0); - cll.display(); // Output: 0 -> 1 -> 2 -> 3 -> - - cll.insertAfterNode(2, 2.5); - cll.display(); // Output: 0 -> 1 -> 2 -> 2.5 -> 3 -> - - cll.deleteByKey(2); - cll.display(); // Output: 0 -> 1 -> 2.5 -> 3 -> - - cout << "Search for 2: " << (cll.search(2) ? "Found" : "Not Found") << endl; // Output: Not Found - cout << "Search for 2.5: " << (cll.search(2.5) ? "Found" : "Not Found") << endl; // Output: Found - - return 0; -} - -``` - -#### Java Implementation - -```java -class Node { - int data; - Node next; - - public Node(int data) { - this.data = data; - this.next = null; - } -} - -class CircularLinkedList { - Node head; - - public CircularLinkedList() { - head = null; - } - - public void insertAtBeginning(int data) { - Node newNode = new Node(data); - if (head == null) { - head = newNode; - newNode.next = head; - } else { - Node temp = head; - while (temp.next != head) { - temp = temp.next; - } - newNode.next = head; - temp.next = newNode; - head = newNode; - } - } - - public void insertAtEnd(int data) { - Node newNode = new Node(data); - if (head == null) { - head = newNode; - newNode.next = head; - } else { - Node temp = head; - while (temp.next != head) { - temp = temp.next; - } - temp.next = newNode; - newNode.next = head; - } - } - - public void insertAfter(int prevData, int data) { - Node temp = head; - Node newNode = new Node(data); - if (head == null) { - return; - } - do { - if (temp.data == prevData) { - newNode.next = temp.next; - temp.next = newNode; - return; - } - temp = temp.next; - } while (temp != head); - } - - public void deleteNode(int key) { - if (head == null) { - return; - } - if (head.data == key && head.next == head) { - head = null; - } else if (head.data == key) { - Node temp = head; - while (temp.next != head) { - temp = temp.next; - } - temp.next = head.next; - head = head.next; - } else { - Node temp = head; - Node prev = null; - do { - if (temp.data == key) { - prev.next = temp.next; - return; - } - prev = temp; - temp = temp.next; - } while (temp != head); - } - } - - public void display() { - if (head != null) { - Node temp = head; - do { - System.out.print(temp.data + " -> "); - temp = temp.next; - } while (temp != head); - System.out.println(); - } - } - - public boolean search(int key) { - Node temp = head; - do { - if (temp.data == key) { - return true; - } - temp = temp.next; - } while (temp != head); - return false; - } - -// Example usage - public static void main(String[] args) { - CircularLinkedList cll = new cll.insertEnd(1); - cll.insertEnd(2); - cll.insertEnd(3); - cll.display(); // Output: 1 -> 2 -> 3 -> - - cll.insertBeginning(0); - cll.display(); // Output: 0 -> 1 -> 2 -> 3 -> - - cll.insertAfter(2, 2.5); - cll.display(); // Output: 0 -> 1 -> 2 -> 2.5 -> 3 -> - - cll.deleteByKey(2); - cll.display(); // Output: 0 -> 1 -> 2.5 -> 3 -> - - System.out.println("Search for 2: " + cll.search(2)); // Output: false - System.out.println("Search for 2.5: " + cll.search(2.5)); // Output: true - } -} -``` - -### Complexity - -- **Time Complexity**: - - - Insertion at the Beginning: $O(n)$ - - Insertion at the End: $O(n)$ - - Insert After Node: $O(n)$ - - Delete from Beginning: $O(n)$ - - Delete from End: $O(n)$ - - Delete by Key: $O(n)$ - - Search: $O(n)$ - - Traversal: $O(n)$ - -- **Space Complexity**: - -- Operations typically use $O(1) $ extra space as they only involve manipulating existing nodes. -- In Python's display method, storing node data in a list requires O(n) space. - - -### Conclusion - -Circular Linked Lists are versatile data structures that allow for efficient cyclic traversals. While most operations have a time complexity of O(n) due to the need to traverse the list, they offer the advantage of not having a null reference at the end, which can be beneficial in certain applications like implementing round-robin schedulers or circular queues. \ No newline at end of file diff --git a/docs/linked-list/intersection-linked-lists.md b/docs/linked-list/intersection-linked-lists.md deleted file mode 100644 index 2cd7700b1..000000000 --- a/docs/linked-list/intersection-linked-lists.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -id: intersection-linked-lists -sidebar_position: 1 -title: "Find the Intersection Point of Two Linked Lists in C++" -description: "This tutorial explains how to find the intersection point of two singly linked lists using C++." -sidebar_label: "Linked List Intersection" -tags: [dsa, linked-lists, intersection] ---- - -## Linked List Intersection: - -This tutorial provides a C++ implementation to find the intersection point of two singly linked lists. Intersection occurs when two lists share the same nodes after a certain point. - -### Problem Statement: - -Given two singly linked lists, find the node where the two linked lists intersect. Intersection is determined based on the reference of nodes, not the value. - -### Approach: - -The key steps in the approach are as follows: - -1. **Count the Nodes in Each List**: Determine the number of nodes in both linked lists. -2. **Calculate the Difference**: Find the difference in the number of nodes between the two lists. -3. **Align the Longer List**: Traverse the longer list by the difference in lengths so that both lists now have an equal number of nodes left. -4. **Find the Intersection Point**: Traverse both lists simultaneously until the intersection is found by comparing the node addresses. - -### C++ Implementation: - -Here is the C++ code that implements this approach: - -```cpp -#include -using namespace std; - -/* Node structure */ -class Node { -public: - int data; - Node* next; -}; - -/* Function to count the number of nodes in a list */ -int getCount(Node* head); - -/* Function to get the intersection point of two linked lists */ -int getIntersectionNode(Node* head1, Node* head2); - -/* Helper function to find the intersection point */ -int findIntersection(int diff, Node* head1, Node* head2); - -/* Count the number of nodes in the linked list */ -int getCount(Node* head) { - int count = 0; - Node* current = head; - while (current != nullptr) { - count++; - current = current->next; - } - return count; -} - -/* Function to find the intersection node */ -int getIntersectionNode(Node* head1, Node* head2) { - int count1 = getCount(head1); - int count2 = getCount(head2); - int diff; - - if (count1 > count2) { - diff = count1 - count2; - return findIntersection(diff, head1, head2); - } else { - diff = count2 - count1; - return findIntersection(diff, head2, head1); - } -} - -/* Function to find the intersection node after adjusting for the difference */ -int findIntersection(int diff, Node* head1, Node* head2) { - Node* current1 = head1; - Node* current2 = head2; - - // Move the pointer of the longer list ahead by the difference in counts - for (int i = 0; i < diff; i++) { - if (current1 == nullptr) { - return -1; - } - current1 = current1->next; - } - - // Traverse both lists simultaneously to find the intersection point - while (current1 != nullptr && current2 != nullptr) { - if (current1 == current2) { - return current1->data; - } - current1 = current1->next; - current2 = current2->next; - } - - return -1; -} - -/* Driver Code */ -int main() { - Node* newNode; - - // Create two linked lists - Node* head1 = new Node(); - head1->data = 10; - Node* head2 = new Node(); - head2->data = 3; - - newNode = new Node(); - newNode->data = 6; - head2->next = newNode; - - newNode = new Node(); - newNode->data = 9; - head2->next->next = newNode; - - newNode = new Node(); - newNode->data = 15; - head1->next = newNode; - head2->next->next->next = newNode; - - newNode = new Node(); - newNode->data = 30; - head1->next->next = newNode; - - head1->next->next->next = nullptr; - - cout << "The intersection point is " << getIntersectionNode(head1, head2) << endl; - - return 0; -} -``` -## Explanation: - -## Step 1: The function getCount() counts the number of nodes in each linked list. -## Step 2: The getIntersectionNode() function computes the difference between the lengths of the two lists and calls findIntersection() to adjust the longer list. -## Step 3: The findIntersection() function aligns both lists by moving the pointer of the longer list ahead by the difference in node counts, and then simultaneously traverses both lists to find the intersection. - -Example Usage: - - -Given the following lists: -``` -List 1: 10 -> 15 -> 30 -> NULL -List 2: 3 -> 6 -> 9 -> 15 -> 30 -> NULL -``` -The output would be: -``` - The intersection point is 15 -``` -The intersection point is 15 -Time Complexity: - -Time Complexity: O(m + n), where m and n are the lengths of the two linked lists. - -Space Complexity: O(1), since no additional space is required. - - -Applications: -This method is useful in several contexts: - -Linked List Algorithms: Finding intersections is a common problem in linked list manipulation. -Networking: Detecting loops or intersections in routing tables. -Geometric Applications: Identifying overlapping paths or routes. - diff --git a/docs/linked-list/introduction-to-linked-list.md b/docs/linked-list/introduction-to-linked-list.md deleted file mode 100644 index c09a759a4..000000000 --- a/docs/linked-list/introduction-to-linked-list.md +++ /dev/null @@ -1,456 +0,0 @@ ---- -id: introduction-to-linkedList -title: Linked List Data Structure -sidebar_label: Introduction to Linked List -sidebar_position: 1 -description: 'A Linked List is a linear data structure in which elements are stored in nodes, and each node points to the next node, forming a chain. Unlike arrays, linked lists do not store elements in contiguous memory locations. Instead, each node holds two main components: data and a reference (or pointer) to the next node in the sequence. This structure allows for dynamic memory allocation, meaning the list can grow or shrink as needed without reallocating or resizing.' -tags: [dsa, data-structures, LinkedList] ---- - -### Introduction to Linked List - -A **LinkedList** is a linear data structure in which elements are stored in nodes, and each node points to the next node, forming a chain. Imagine a train where each car is connected to the next car, but you can only move forward through the train. Each car contains passengers (data) and has a coupling (pointer) that connects it to the next car. - -### Definition and Structure -A linked list consists of nodes, where each node contains: -- **Data:** The value stored in the node. -- **Next:** A reference to the next node in the sequence (or `null` if there is no next node). - -The sequence starts from a node called the **head** and continues until it reaches a node that points to `null`, which marks the end of the list. - -### Properties -Key characteristics of linked lists include: -- **Dynamic Size:** Unlike arrays, linked lists can grow and shrink dynamically as nodes are added or removed. -- **Sequential Access:** Accessing elements in a linked list requires traversal from the head, as elements are not indexed like in an array. - - ``` - Head -> A -> B -> C -> D -> null - ``` - -### Types of Linked Lists -1. **Singly Linked Lists:** Each node has a reference to the next node in the sequence. - - Example: - ```plaintext - Head -> 10 -> 20 -> 30 -> null - ``` - -2. **Doubly Linked Lists:** Each node has two references—one to the next node and one to the previous node. - - Example: - ```plaintext - Head <-> 10 <-> 20 <-> 30 <-> null - ``` - -3. **Circular Linked Lists:** The last node points back to the head, forming a circular structure. - - Example: - ```plaintext - Head -> 10 -> 20 -> 30 --| - |-----------------| - ``` - -4. **Doubly Circular Linked Lists:** Similar to a circular linked list but with both next and previous references. - - Example: - ```plaintext - Head <-> 10 <-> 20 <-> 30 <-> Head - ``` -![alt text](LinkedList.png) - -### LinkedList Operations - -A LinkedList typically supports the following operations: - -1. **Insert at the Beginning**: -- A new node is created with the given data. -- The new node's next pointer is set to the current head. - The head pointer is updated to point to the new node. -2. **Insert at the End**: -- If the list is empty, the new node becomes the head. -- Otherwise, traverse the list until the last node is found, and set its next to the new node. -3. **Delete Node by Value**: -- If the head contains the key, adjust the head to point to the next node. --Otherwise, traverse the list to find the node before the target node and adjust its next pointer to skip the target node. -4. **Search for a Node**: -- Traverse the list while comparing each node’s data with the key. -- If a match is found, return True; otherwise, after reaching the end of the list, return False. - -5. **Traverse and Print the List**: --Traverse the list, printing the data in each node until the end of the list (NULL) is reached. - -### Advantages and Disadvantages -#### Advantages: - -- **Efficient Insertion/Deletion**: Can insert and delete nodes at any position in constant time if the node reference is known. -- **Dynamic Size**: Can easily grow and shrink in size without the need for resizing or memory reallocation like arrays. - -#### Disadvantages: - -- **No Random Access**: Unlike arrays, linked lists do not provide direct access to elements via index, requiring traversal from the head. -- **Memory Overhead**: Each node requires extra memory for storing a pointer to the next node. -- **Slow Lookups**: Finding an element requires linear time (O(n)) as the list must be traversed. - -### Applications of Linked Lists - -- **Dynamic Memory Allocation**: Linked lists provide an efficient way to manage memory when the number of elements is not known in advance. They are widely used in memory management systems to keep track of free and used memory blocks. - -- **Implementation of Other Data Structures**: Linked lists serve as the foundation for more complex data structures such as: - - **Stacks**: Dynamic stacks can be efficiently implemented using linked lists, allowing for dynamic memory usage. - - **Queues**: Linked lists are ideal for building dynamic queues, ensuring efficient insertion and deletion operations. - - **Graphs**: Linked lists are used to represent adjacency lists in graph data structures, allowing efficient traversal and manipulation of nodes. - -- **Efficient Insertions/Deletions**: For applications where elements are frequently inserted or removed, such as task scheduling or buffer management, linked lists are ideal due to their dynamic nature and minimal overhead for these operations. - -- **Polynomial Representation**: Linked lists are used to represent polynomials, where each term is stored in a node. This structure allows efficient addition and manipulation of polynomial terms. - - Example: - ```plaintext - (5x^2 + 3x + 2) -> 5 -> 3 -> 2 -> null - - -### Pseudocode - -#### Basic Operations - -1. **Insert at the Beginning**: - - ```text - Function insertAtBeginning(head, data): - Create newNode with data - Set newNode.next = head - Set head = newNode - Return head - ``` - -2. **Insert at the End**: - - ```text - Function insertAtEnd(head, data): - Create newNode with data - If head is NULL: - Set head = newNode - Return head - Set temp = head - While temp.next is not NULL: - Move temp to temp.next - Set temp.next = newNode - Return head - ``` - -3. **Delete Node by Value**: - - ```text - Function deleteNode(head, key): - If head.data equals key: - Set head = head.next - Return head - Set temp = head - While temp is not NULL and temp.next.data is not key: - Move temp to temp.next - If temp is NULL: - Return head (Key not found) - Set temp.next = temp.next.next - Return head - ``` - -4. **Search for a Node**: - - ```Function searchNode(head, key): - Set temp = head - While temp is not NULL: - If temp.data equals key: - Return True - Move temp to temp.next - Return False - ``` - -5. **Traverse and Print the List**: - - ```text - Function traverseList(head): - Set temp = head - While temp is not NULL: - Print temp.data - Move temp to temp.next - ``` - -### Implementation in Python, C++, and Java - -#### Python Implementation - -```python -class Node: - def __init__(self, data): - self.data = data - self.next = None - -class LinkedList: - def __init__(self): - self.head = None - - def insert_at_beginning(self, data): - new_node = Node(data) - new_node.next = self.head - self.head = new_node - - def insert_at_end(self, data): - new_node = Node(data) - if self.head is None: - self.head = new_node - return - last = self.head - while last.next: - last = last.next - last.next = new_node - - def delete_node(self, key): - temp = self.head - if temp is not None: - if temp.data == key: - self.head = temp.next - temp = None - return - while temp is not None: - if temp.data == key: - break - prev = temp - temp = temp.next - if temp is None: - return - prev.next = temp.next - temp = None - - def search(self, key): - current = self.head - while current: - if current.data == key: - return True - current = current.next - return False - - def print_list(self): - temp = self.head - while temp: - print(temp.data, end=" -> ") - temp = temp.next - print("None") - -# Example usage -ll = LinkedList() -ll.insert_at_end(1) -ll.insert_at_end(2) -ll.insert_at_beginning(0) -ll.print_list() # Outputs: 0 -> 1 -> 2 -> None -ll.delete_node(2) -ll.print_list() # Outputs: 0 -> 1 -> None -print(ll.search(1)) # Outputs: true -``` - -#### C++ Implementation - -```cpp -#include -using namespace std; - -class Node { -public: - int data; - Node* next; - Node(int val) : data(val), next(nullptr) {} -}; - -class LinkedList { -public: - Node* head; - - LinkedList() { head = nullptr; } - - void insertAtBeginning(int data) { - Node* newNode = new Node(data); - newNode->next = head; - head = newNode; - } - - void insertAtEnd(int data) { - Node* newNode = new Node(data); - if (head == nullptr) { - head = newNode; - return; - } - Node* last = head; - while (last->next != nullptr) { - last = last->next; - } - last->next = newNode; - } - - void deleteNode(int key) { - Node* temp = head; - if (temp != nullptr && temp->data == key) { - head = temp->next; - delete temp; - return; - } - Node* prev = nullptr; - while (temp != nullptr && temp->data != key) { - prev = temp; - temp = temp->next; - } - if (temp == nullptr) return; - prev->next = temp->next; - delete temp; - } - - bool search(int key) { - Node* current = head; - while (current != nullptr) { - if (current->data == key) - return true; - current = current->next; - } - return false; - } - - void printList() { - Node* temp = head; - while (temp != nullptr) { - cout << temp->data << " -> "; - temp = temp->next; - } - cout << "None" << endl; - } -}; - -// Example usage -int main() { - LinkedList ll; - ll.insertAtEnd(1); - ll.insertAtEnd(2); - ll.insertAtBeginning(0); - ll.printList(); //Outputs: 0 -> 1 -> 2 -> None - ll.deleteNode(2); - ll.printList(); // Outputs: 0 -> 1 -> None - cout << ll.search(1) << endl; // Outputs: true - return 0; -} -``` - -#### Java Implementation - -```java -class LinkedList { - Node head; - - class Node { - int data; - Node next; - - Node(int d) { - data = d; - next = null; - } - } - - public void insertAtBeginning(int data) { - Node newNode = new Node(data); - newNode.next = head; - head = newNode; - } - - public void insertAtEnd(int data) { - Node newNode = new Node(data); - if (head == null) { - head = newNode; - return; - } - Node last = head; - while (last.next != null) { - last = last.next; - } - last.next = newNode; - } - - public void deleteNode(int key) { - Node temp = head, prev = null; - if (temp != null && temp.data == key) { - head = temp.next; - return; - } - while (temp != null && temp.data != key) { - prev = temp; - temp = temp.next; - } - if (temp == null) return; - prev.next = temp.next; - } - - public boolean search(int key) { - Node current = head; - while (current != null) { - if (current.data == key) { - return true; - } - current = current.next; - } - return false; - } - - public void printList() { - Node temp = head; - while (temp != null) { - System.out.print(temp.data + " -> "); - temp = temp.next; - } - System.out.println("None"); - } - -// Example usage - public static void main(String[] args) { - LinkedList ll = new LinkedList(); - ll.insertAtEnd(1); - ll.insertAtEnd(2); - ll.insertAtBeginning(0); - ll.printList(); // Outputs: 0 -> 1 -> 2 -> None - ll.deleteNode(2); - ll.printList(); //Outputs: 0 -> 1 -> None - System.out.println(ll.search(1)); //Outputs: True - } -} -``` - -### Complexity - -- **Time Complexity**: - - - Insertion at the Beginning: $O(1)$ - - Insertion at the End: $O(n)$ - - Deletion by Value: $O(n)$ - - Search for a Node by Value: $O(n)$ - - Traversal (Print the List): $O(n)$ - -- **Space Complexity**: $O(n)$, where $n$ is the number of nodes. - -### Example - -Consider that you start with an empty list of student IDs and perform the following operations: - -1. Insert 101 -2. Insert 102 at the beginning -3. Insert 103 at the end -4. Insert 100 at the beginning -5. Search for a student with ID 102 -6. Delete the student with ID 103 -7. Print the final list of students - -**Operations**: - -- **Insert 101**: List: 101 -- **Insert 102 at the beginning**: List: 102 -> 101 -- **Insert 103 at the end**: List: 102 -> 101 -> 103 -- **Insert 100 at the beginning**: List: 100 -> 102 -> 101 -> 103 -- **Search for a student with ID 102**: Found: 1 (true) -- **Delete ID 103 and print final list of students**: Output: 100 -> 102 -> 101 -> None - -### Conclusion - -Singly Linked Lists (SLLs) offer dynamic memory management. They grow or shrink in size as needed, avoiding the limitations of static data structures like arrays. SLLs are excellent for applications that involve frequent insertions and deletions (especially at the beginning or middle), such as in stacks, queues, or other dynamic datasets. A singly linked list can be slower in terms of searching compared to arrays, since every search requires linear time. \ No newline at end of file diff --git a/docs/linked-list/linked-list-approaches.md b/docs/linked-list/linked-list-approaches.md deleted file mode 100644 index ec525fa8c..000000000 --- a/docs/linked-list/linked-list-approaches.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -id: linked-list-approaches-dsa -title: Linked List Approaches -sidebar_label: Different Approaches in Linked List -sidebar_position: 6 -description: "Linked lists are dynamic data structures, and various approaches can be used to solve problems involving linked lists. This file outlines iterative and recursive approaches used to implement and manipulate linked lists." -tags: [linked-list, data-structures, approaches, dsa] ---- - -# Linked List Approaches | Problem Solving Techniques - -A **Linked List** is a linear data structure that allows dynamic memory management by linking elements (nodes) via pointers. This document outlines different approaches to solving problems involving linked lists, particularly focusing on **iterative** and **recursive** methods for common linked list operations. - ---- - -## Common Linked List Operations - -The primary operations on linked lists include: - -1. **Insertion**: Adding an element at the head, tail, or a specific position in the list. -2. **Deletion**: Removing an element from the head, tail, or a specific position. -3. **Searching**: Finding an element in the list. -4. **Traversal**: Iterating through all elements in the list. - ---- - -## Approach 1: Iterative Approach for Linked List Operations - -### Insertion at Head (Iterative) - -Inserting a new node at the head of the list involves adjusting the `next` pointer of the new node to point to the current head, and then updating the head pointer to the new node. - -```cpp -struct Node { - int data; - Node* next; -}; - -void insertAtHead(Node*& head, int value) { - Node* newNode = new Node(); - newNode->data = value; - newNode->next = head; - head = newNode; -} -``` - -## Approach 2: Recursive Approach for Linked List Operations -### Insertion at End (Recursive) -Inserting at the tail can also be done recursively. Each recursive call moves one step forward until it reaches the end of the list, where the new node is appended. - -```cpp -void insertAtEnd(Node*& head, int value) { - if (head == nullptr) { - head = new Node(); - head->data = value; - head->next = nullptr; - return; - } - - insertAtEnd(head->next, value); -} -``` -## Approach 3: Two Pointer Approach for Linked Lists -The two-pointer approach, also known as the slow and fast pointer technique, is commonly used in linked list problems such as detecting cycles or finding the middle element. - -### Detecting Cycle in a Linked List (Floyd’s Cycle Detection) -This approach uses two pointers: slow moves one step at a time, and fast moves two steps at a time. If there is a cycle, the two pointers will eventually meet. - -```cpp -bool detectCycle(Node* head) { - Node* slow = head; - Node* fast = head; - - while (fast != nullptr && fast->next != nullptr) { - slow = slow->next; - fast = fast->next->next; - - if (slow == fast) { - return true; - } - } - return false; -} -``` - -## Approach 4: Recursive Reversal of Linked List -Reversing a linked list recursively involves reversing the rest of the list, then fixing the head pointer. - -```cpp -Node* reverseRecursive(Node* head) { - if (head == nullptr || head->next == nullptr) return head; - - Node* rest = reverseRecursive(head->next); - head->next->next = head; - head->next = nullptr; - - return rest; -} -``` - -## Time and Space Complexities -### Iterative Approach -- Time Complexity: O(n) for most operations, where n is the number of nodes. -- Space Complexity: O(1) (no additional memory used). -### Recursive Approach -- Time Complexity: O(n) for most operations. -- Space Complexity: O(n) due to recursive stack space. -### Two Pointer Approach -- Time Complexity: O(n) for cycle detection and finding the middle. -- Space Complexity: O(1). -### Recursive Reversal -- Time Complexity: O(n). -- Space Complexity: O(n) due to recursion. diff --git a/docs/linked-list/merge-two-sorted-list.md b/docs/linked-list/merge-two-sorted-list.md deleted file mode 100644 index 5e3820c8c..000000000 --- a/docs/linked-list/merge-two-sorted-list.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: merge-two-sorted-list -sidebar_position: 1 -title: "Merge Two Sorted Linked Lists" -description: "This tutorial explains how to merge two sorted list using Cpp." -sidebar_label: "Linked List Intersection" -tags: [dsa, linked-lists, merge,cpp] ---- -# Merge Two Sorted Linked Lists - -## Problem Statement - -Given two sorted linked lists, the task is to merge them into one sorted linked list. The merged linked list should be created by splicing together the nodes of the input lists. - -### Example - -**Input:** -- `list1 = [1, 2, 4]` -- `list2 = [1, 3, 4]` - -**Output:** -- `Merged List: 1 -> 1 -> 2 -> 3 -> 4 -> 4` - -### Constraints -- Both lists are sorted in non-decreasing order. -- The output should maintain the sorted order by merging nodes directly from the input lists. - -## Solution Explanation - -To merge the two sorted linked lists: -1. **Dummy Node and Tail**: Start with a dummy node to simplify list manipulation. Use a `tail` pointer to keep track of the last node in the merged list. -2. **Comparison and Insertion**: - - Traverse both lists. For each pair of nodes from the two lists, attach the smaller node to the `tail` and move to the next node in that list. -3. **Remaining Nodes**: - - Once one list is exhausted, link the rest of the nodes from the remaining list to the `tail`. -4. **Return Merged List**: - - The merged list starts from `dummy.next` since `dummy` is just a placeholder. - -### Complexity -- **Time Complexity**: `O(n + m)`, where `n` and `m` are the lengths of the two input lists. -- **Space Complexity**: `O(1)` (in-place merging without additional data structures). - -## Code Implementation - -Here’s the C++ code for merging two sorted linked lists: - -```cpp -#include -#include -using namespace std; - -struct ListNode { - int val; - ListNode *next; - ListNode(int x) : val(x), next(nullptr) {} -}; - -class Solution { -public: - ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) { - ListNode dummy(0); // Dummy node to start the merged list - ListNode* tail = &dummy; - - // Merge the lists by comparing nodes - while (list1 && list2) { - if (list1->val < list2->val) { - tail->next = list1; - list1 = list1->next; - } else { - tail->next = list2; - list2 = list2->next; - } - tail = tail->next; - } - - // Attach the remaining nodes, if any - tail->next = list1 ? list1 : list2; - - return dummy.next; // Return the head of the merged list - } -}; -``` \ No newline at end of file diff --git a/docs/linked-list/range-sum-of-linked-list.md b/docs/linked-list/range-sum-of-linked-list.md deleted file mode 100644 index 1438f27e0..000000000 --- a/docs/linked-list/range-sum-of-linked-list.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -id: range-sum-of-linked-list -title: Range Sum of Linked List -sidebar_label: Range Sum of Linked List -description: 'Calculate the sum of node values within this range.' -tags: [dsa, data-structures, LinkedList] ---- - -### Range Sum of Linked List - -Given a linked list and a range defined by start and end (0-indexed), calculate the sum of the node values within this range. - -### Implementation in c++ - -```cpp -#include -using namespace std; - -struct ListNode { - int val; - ListNode* next; - ListNode(int x) : val(x), next(NULL) {} -}; - -int rangeSum(ListNode* head, int start, int end) { - int rangeSum = 0; // Sum of values within the range - int position = 0; // Track the current position in the list - ListNode* current = head; // Pointer to traverse the list - - // Traverse the linked list - while (current != nullptr) { - // If the position is within the specified range, add to sum - if (position >= start && position <= end) { - rangeSum += current->val; - } - - // Break if we've passed the end of the range - if (position > end) { - break; - } - - // Move to the next node and increment the position - current = current->next; - position++; - } - - return rangeSum; -} - -int main() { - // Creating a sample linked list: 1 -> 2 -> 3 -> 4 -> 5 - ListNode* head = new ListNode(1); - head->next = new ListNode(2); - head->next->next = new ListNode(3); - head->next->next->next = new ListNode(4); - head->next->next->next->next = new ListNode(5); - - // Calculate the sum of node values from position 1 to 3 (inclusive) - int start = 1; - int end = 3; - cout << "Range Sum: " << rangeSum(head, start, end) << endl; // Output should be 2 + 3 + 4 = 9 - - // Clean up the memory allocated for the linked list - ListNode* temp; - while (head != nullptr) { - temp = head; - head = head->next; - delete temp; - } - - return 0; -} -``` - -### Complexity - -- **Time Complexity**: $O(n)$ -- **Space Complexity**: $O(1)$ diff --git a/docs/linked-list/remove-duplicates-from-sorted-list.md b/docs/linked-list/remove-duplicates-from-sorted-list.md deleted file mode 100644 index 54dfc4b6a..000000000 --- a/docs/linked-list/remove-duplicates-from-sorted-list.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: remove-duplicates-from-sorted-list -sidebar_position: 1 -title: "Remove Duplicates from Sorted Linked Lists" -description: "This tutorial explains how to remove duplicates from sorted list using Cpp." -sidebar_label: "Linked List Intersection" -tags: [dsa, linked-lists,cpp] ---- - -# Remove Duplicates from Sorted List - -## Problem Statement - -Given the head of a sorted linked list, remove all duplicates such that each element appears only once. Return the modified linked list, which remains sorted. - -### Example - -**Input:** -- `head = [1,1,2]` - -**Output:** -- `[1,2]` - -### Constraints -- The list is sorted in non-decreasing order. -- The output should retain the sorted order with no duplicate values. - -## Solution Explanation - -To remove duplicates from the sorted linked list: -1. **Single Pass with Current Pointer**: - - Use a pointer (`current`) to traverse the list. - - At each node, compare the value of `current` with `current->next`. - - If the values are the same, update the `next` pointer of `current` to skip the duplicate node. - - If the values are different, move `current` to the next node. -2. **End Condition**: - - Continue the process until `current` reaches the end of the list. -3. **In-place Modification**: - - This algorithm modifies the list in place without additional data structures. - -### Complexity -- **Time Complexity**: `O(n)`, where `n` is the number of nodes in the linked list, as we traverse each node once. -- **Space Complexity**: `O(1)`, as it operates in constant space by modifying the list in place. - -## Code Implementation - -Here’s the C++ code for removing duplicates from a sorted linked list: - -```cpp -#include -#include -using namespace std; - -struct ListNode { - int val; - ListNode *next; - ListNode(int x) : val(x), next(nullptr) {} -}; - -class Solution { -public: - ListNode* deleteDuplicates(ListNode* head) { - if (!head) return nullptr; // If list is empty, return null - - ListNode* current = head; // Start with the head of the list - - // Traverse the list - while (current && current->next) { - if (current->val == current->next->val) { - // Skip the duplicate node - ListNode* duplicate = current->next; - current->next = duplicate->next; - delete duplicate; // Free memory for the duplicate node - } else { - // Move to the next distinct element - current = current->next; - } - } - - return head; // Return the modified list without duplicates - } -}; - -// Helper function to create a linked list from an array -ListNode* createLinkedList(const vector& values) { - ListNode dummy(0); - ListNode* current = &dummy; - for (int value : values) { - current->next = new ListNode(value); - current = current->next; - } - return dummy.next; -} - -// Helper function to print a linked list -void printLinkedList(ListNode* head) { - while (head) { - cout << head->val; - if (head->next) cout << " -> "; - head = head->next; - } - cout << endl; -} - -int main() { - vector list_values = {1, 1, 2}; - ListNode* head = createLinkedList(list_values); - - cout << "Original List: "; - printLinkedList(head); - - Solution solution; - ListNode* modifiedHead = solution.deleteDuplicates(head); - - cout << "List after removing duplicates: "; - printLinkedList(modifiedHead); - - return 0; -} -``` \ No newline at end of file diff --git a/docs/machine-learning/AdaBoost.md b/docs/machine-learning/AdaBoost.md deleted file mode 100644 index 8cd49b790..000000000 --- a/docs/machine-learning/AdaBoost.md +++ /dev/null @@ -1,136 +0,0 @@ ---- - -id: adaboost-visualizations -title: AdaBoost Visualizations -sidebar_label: AdaBoost -description: "Implement the AdaBoost algorithm to combine multiple weak classifiers into a strong ensemble model. This feature will visualize the boosting process and support various base learners." -tags: [machine learning, ensemble methods, AdaBoost, data visualization, classifiers] - ---- - -### Definition: -**AdaBoost (Adaptive Boosting)** is a popular ensemble learning algorithm that combines the outputs of multiple weak classifiers to create a robust model. By focusing on the errors made by previous classifiers, AdaBoost iteratively improves its predictions and effectively reduces bias and variance. - -### Characteristics: -- **Weak Learners**: - Utilizes multiple weak classifiers (often decision stumps) that perform slightly better than random guessing. - -- **Adaptive Weighting**: - Adjusts the weights of misclassified samples in each iteration, allowing the model to focus more on difficult cases. - -- **Boosting Technique**: - Sequentially adds weak learners, each correcting the mistakes of its predecessors, ultimately creating a strong combined model. - -### Components of AdaBoost: -1. **Base Learners**: - Simple models (weak classifiers) that serve as the building blocks of the ensemble. - -2. **Weights**: - Each data point is assigned a weight, which is updated based on classification performance. - -3. **Final Model**: - The final strong classifier is a weighted sum of the individual weak classifiers, where the weights reflect their performance. - -### Steps Involved: -1. **Initialize Weights**: - Assign equal weights to all training samples at the start. - -2. **Train Weak Classifier**: - Fit a weak learner to the training data using the current weights. - -3. **Calculate Error**: - Compute the error rate of the weak learner based on the weighted samples. - -4. **Update Weights**: - Increase the weights of misclassified samples and decrease the weights of correctly classified samples. - -5. **Combine Classifiers**: - Add the new weak learner to the ensemble with a weight based on its performance, and repeat the process for a specified number of iterations. - -### Key Concepts: -- **Ensemble Learning**: - Combines multiple models to improve overall performance and robustness. - -- **Weight Update Rule**: - The formula used to adjust sample weights based on classification results. - -- **Final Classifier**: - The aggregate model formed from the weak learners, providing the final predictions. - -### Advantages of AdaBoost: -- **Improved Accuracy**: - Significantly enhances model performance by effectively reducing both bias and variance. - -- **Flexibility**: - Can work with various types of weak classifiers, allowing for customization based on the problem. - -- **Robustness to Overfitting**: - While more susceptible to noise, AdaBoost can perform well with appropriately selected weak learners and parameters. - -### Limitations of AdaBoost: -- **Sensitive to Noisy Data**: - Outliers can adversely affect model performance since AdaBoost focuses on misclassified samples. - -- **Weak Learner Dependency**: - The performance heavily relies on the choice of base learners; poorly chosen weak classifiers may lead to suboptimal results. - -### Popular Applications of AdaBoost: -1. **Image Recognition**: - Used to classify images by combining features from weak classifiers. - -2. **Text Classification**: - Effective for categorizing documents based on textual features. - -3. **Medical Diagnosis**: - Applied in healthcare for identifying diseases from complex datasets. - -4. **Fraud Detection**: - Helps in detecting fraudulent activities by analyzing transaction patterns. - -5. **Customer Segmentation**: - Utilized in marketing to classify customer behavior for targeted strategies. - -### Example of AdaBoost in Python: -```python -import numpy as np -from sklearn.ensemble import AdaBoostClassifier -from sklearn.tree import DecisionTreeClassifier -from sklearn.datasets import make_classification -import matplotlib.pyplot as plt - -# Create a sample dataset -X, y = make_classification(n_samples=100, n_features=20, n_informative=10, n_redundant=10) - -# Initialize the base learner -base_learner = DecisionTreeClassifier(max_depth=1) # Decision stump - -# Create AdaBoost classifier -ada_classifier = AdaBoostClassifier(base_estimator=base_learner, n_estimators=50) - -# Fit the model -ada_classifier.fit(X, y) - -# Visualize the decision boundaries -plt.figure(figsize=(8, 6)) -plt.title('AdaBoost Decision Boundaries') -plt.scatter(X[:, 0], X[:, 1], c=ada_classifier.predict(X), cmap='viridis', edgecolor='k') -plt.xlabel('Feature 1') -plt.ylabel('Feature 2') -plt.grid() -plt.show() -``` - -### Time and Space Complexity: -- **Time Complexity**: - Training complexity is approximately $O(n \cdot m \cdot t)$, where $n$ is the number of samples, $m$ is the number of features, and $t$ is the number of weak learners. - -- **Space Complexity**: - The space required is $O(t)$ for storing the weak classifiers and their weights. - -### Summary & Applications: -- **AdaBoost** is a powerful ensemble technique that enhances classification performance by leveraging the strengths of multiple weak learners. - -- **Applications**: - Commonly used in various domains, including image and text classification, fraud detection, and medical diagnosis, making it a valuable addition to any machine learning toolkit. - ---- diff --git a/docs/machine-learning/Autoencoders.md b/docs/machine-learning/Autoencoders.md deleted file mode 100644 index f933ee2f9..000000000 --- a/docs/machine-learning/Autoencoders.md +++ /dev/null @@ -1,180 +0,0 @@ ---- - -id: autoencoders -title: Autoencoders -sidebar_label: Autoencoders -description: "In this post, we will explore Autoencoders, a type of artificial neural network used for unsupervised learning that focuses on efficiently encoding input data and reconstructing it." -tags: [machine learning, deep learning, autoencoders, neural networks, unsupervised learning] - ---- - -### Definition: -**Autoencoders** are a type of artificial neural network used to learn efficient representations of data in an unsupervised manner. Their goal is to map input data to a compressed representation (encoding) and then reconstruct the input data from this representation (decoding). Autoencoders are widely used for dimensionality reduction, feature learning, and data denoising. - -### Characteristics: -- **Unsupervised Learning**: - Autoencoders do not require labeled data, making them ideal for unsupervised learning tasks like dimensionality reduction and anomaly detection. - -- **Compression and Reconstruction**: - Autoencoders aim to learn a lower-dimensional encoding of the input data and reconstruct the original input as closely as possible. - -- **Symmetric Architecture**: - The network is typically symmetric, with the encoder compressing the data and the decoder reconstructing the input. - -### Components of Autoencoders: -1. **Encoder**: - The encoder maps the input data to a lower-dimensional latent space (or hidden representation) through multiple layers of neurons. This part compresses the input data into fewer dimensions. - -2. **Latent Space**: - The latent space, or bottleneck layer, represents the compressed, encoded version of the input. This space holds the most critical features needed for reconstruction. - -3. **Decoder**: - The decoder takes the compressed data from the latent space and attempts to reconstruct the original input data. The output of the decoder should ideally resemble the input. - -4. **Reconstruction Loss**: - The difference between the input data and its reconstruction (the output) is captured by a loss function. This loss, often referred to as **reconstruction loss**, is minimized during training to improve the quality of the autoencoder. - -### Types of Autoencoders: -1. **Vanilla Autoencoders**: - The simplest form of an autoencoder, consisting of an encoder and a decoder. Both parts are neural networks, and the goal is to minimize the reconstruction loss. - -2. **Denoising Autoencoders (DAE)**: - These autoencoders are designed to remove noise from input data. The input is corrupted with noise, and the autoencoder learns to reconstruct the clean, original data. - -3. **Sparse Autoencoders**: - A regularization term is added to the loss function to encourage sparsity in the latent representation. These autoencoders learn features by constraining the model to activate only a few neurons in the hidden layer. - -4. **Variational Autoencoders (VAE)**: - These autoencoders are probabilistic models that generate new data similar to the training data by learning the distribution of the input data. VAEs are used in tasks like image generation. - -5. **Convolutional Autoencoders (CAE)**: - These autoencoders apply convolutional layers instead of fully connected layers, making them suitable for tasks involving image data. CAEs are used for tasks like image denoising and compression. - -### Steps Involved: -1. **Input Data**: - The autoencoder receives raw input data (e.g., images, text, or tabular data). - -2. **Encoding**: - The encoder processes the input through multiple layers to generate a lower-dimensional latent representation. - -3. **Bottleneck/Latent Space**: - The latent space holds the compressed version of the input data. - -4. **Decoding**: - The decoder takes the latent representation and attempts to reconstruct the original input data. - -5. **Minimizing Loss**: - The network is trained to minimize reconstruction loss, which measures the difference between the input data and the reconstructed data. - -### Problem Statement: -Given a set of unlabeled data, the goal is to train an autoencoder to efficiently encode and reconstruct the data, minimizing reconstruction loss. - -### Key Concepts: -- **Dimensionality Reduction**: - Autoencoders can reduce the dimensionality of data, which helps with data visualization, compression, and speeding up downstream tasks like classification. - -- **Unsupervised Learning**: - Since autoencoders do not require labels, they are highly useful in unsupervised learning scenarios where the goal is to discover underlying structure in data. - -- **Reconstruction Loss**: - The reconstruction loss quantifies how well the autoencoder can replicate the input data from its encoded representation. Common loss functions include: - - **Mean Squared Error (MSE)**: - Measures the average squared difference between the input and output. - - **Binary Cross-Entropy**: - Used for binary or normalized input data. - -- **Latent Space Representation**: - The compressed representation in the latent space can be used for other tasks like clustering, visualization, or as input for another machine learning model. - -### Split Criteria: -Autoencoders are trained to minimize the reconstruction loss between the input and the output, so the criteria are not based on splitting but on reconstructing the input accurately. - -### Time Complexity: -- **Training Complexity**: - The time complexity depends on the number of layers and neurons in the encoder and decoder. For an autoencoder with $l$ layers and $n$ neurons per layer, the complexity is $O(n \cdot l)$. - -- **Prediction Complexity**: - The prediction or encoding complexity is also proportional to the number of layers and neurons, as the data passes through each layer of the network. - -### Space Complexity: -- **Space Complexity**: - The space complexity depends on the number of neurons and weights in the encoder and decoder, as well as the size of the latent space. - -### Example: -Consider a simple example of an autoencoder applied to **image compression**. The autoencoder compresses an input image into a lower-dimensional latent space and then reconstructs the image from this compressed version. - -#### Image Compression with Autoencoders: - -1. **Input**: - An input image is passed through the encoder, which compresses it into a latent space of reduced dimensions. - -2. **Latent Space**: - The compressed version of the image (latent representation) is much smaller than the original image but contains enough information to reconstruct it. - -3. **Reconstruction**: - The decoder reconstructs the image from the latent space representation, with the aim of minimizing reconstruction loss. - -### Python Implementation: -Here is a simple implementation of an autoencoder using **TensorFlow/Keras**: - -```python -import tensorflow as tf -from tensorflow.keras import layers, models -import numpy as np - -# Load dataset (for example, MNIST digits dataset) -(x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data() -x_train = x_train.astype('float32') / 255.0 -x_test = x_test.astype('float32') / 255.0 - -# Flatten the data (since autoencoder works on vectorized input) -x_train = x_train.reshape((x_train.shape[0], -1)) -x_test = x_test.reshape((x_test.shape[0], -1)) - -# Define Autoencoder architecture -input_dim = x_train.shape[1] - -# Encoder -input_layer = layers.Input(shape=(input_dim,)) -encoded = layers.Dense(128, activation='relu')(input_layer) -encoded = layers.Dense(64, activation='relu')(encoded) -encoded = layers.Dense(32, activation='relu')(encoded) - -# Decoder -decoded = layers.Dense(64, activation='relu')(encoded) -decoded = layers.Dense(128, activation='relu')(decoded) -decoded = layers.Dense(input_dim, activation='sigmoid')(decoded) - -# Autoencoder Model -autoencoder = models.Model(input_layer, decoded) - -# Compile the model -autoencoder.compile(optimizer='adam', loss='mse') - -# Train the autoencoder -autoencoder.fit(x_train, x_train, epochs=50, batch_size=256, shuffle=True, validation_data=(x_test, x_test)) - -# Encode and Decode Test Data -encoded_imgs = autoencoder.predict(x_test) - -# Evaluate reconstruction loss on test data -loss = autoencoder.evaluate(x_test, x_test) -print(f"Reconstruction Loss: {loss}") -``` - -### Summary and Applications: -- **Dimensionality Reduction**: - Autoencoders can reduce the dimensionality of data, providing a more compact representation useful for visualization and speeding up subsequent algorithms. - -- **Denoising**: - Denoising autoencoders can remove noise from corrupted data (e.g., images, audio) by learning how to reconstruct the clean version of the input. - -- **Anomaly Detection**: - Autoencoders can be used to detect anomalies in data by comparing the reconstruction loss. Unusual data points tend to have higher reconstruction errors. - -- **Data Compression**: - Autoencoders compress input data into a lower-dimensional space, which can be useful for storage and transmission purposes. - -- **Feature Extraction**: - The latent space representation learned by the encoder can serve as a feature vector for other machine learning tasks, such as classification or clustering. - diff --git a/docs/machine-learning/BeamSearch.md b/docs/machine-learning/BeamSearch.md deleted file mode 100644 index 35a103869..000000000 --- a/docs/machine-learning/BeamSearch.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -id: beam-search -title: Beam Search Algorithm -sidebar_label: Beam Search -description: "This guide covers the Beam Search algorithm, a heuristic search technique commonly used in sequence generation tasks to find the most probable output sequence in machine learning." -tags: [machine learning, search algorithm, beam search, NLP, transformer] ---- - -### Definition: -**Beam Search** is a heuristic search algorithm that is widely used in sequence prediction tasks to find the most likely sequence of outputs by considering multiple candidates at each step. Beam Search is particularly useful in applications like language translation, speech recognition, and image captioning where the goal is to generate coherent, accurate sequences based on probabilities. - -### Characteristics: -- **Heuristic Search**: - Beam Search uses a probabilistic approach, evaluating multiple partial sequences at each time step and discarding less likely candidates. -- **Controlled Exploration**: - Beam Search keeps a fixed number of candidates at each step, called the "beam width," balancing between search breadth and computational efficiency. -- **Greedy Yet Flexible**: - Unlike pure greedy search, Beam Search maintains multiple candidates, allowing it to recover from locally optimal but globally suboptimal choices. - -### Components of Beam Search: -1. **Beam Width (k)**: - The beam width determines the number of candidate sequences kept at each time step. A higher beam width allows more paths to be considered but requires more computational resources. -2. **Score Calculation**: - Beam Search calculates scores for each candidate sequence by combining the probability of the sequence with additional metrics like length normalization. -3. **Pruning**: - At each time step, Beam Search keeps only the top `k` sequences with the highest scores, discarding the rest to manage computational efficiency. -4. **Termination Condition**: - The algorithm stops when all selected sequences reach an end condition, such as a specified token (`` token in NLP tasks) or a maximum length. - -### Beam Search Architecture: -1. **Input Sequence**: - The model is provided with an initial input sequence, usually a `` token for text generation tasks, to begin predicting the output sequence. -2. **Candidate Expansion**: - For each candidate sequence in the beam, the model generates probabilities for the next token in the sequence. -3. **Pruning**: - The algorithm keeps only the `k` most likely sequences at each time step, maintaining only the highest-scoring candidates. -4. **Output Selection**: - When the search reaches the termination condition, Beam Search outputs the sequence with the highest score among the final candidates. - -### Problem Statement: -Given an initial input sequence and a model that can predict probabilities for the next token in a sequence, the goal of Beam Search is to generate the most probable sequence of tokens. This is achieved by exploring multiple possible paths and discarding less probable ones to optimize search efficiency while maintaining high-quality results. - -### Key Concepts: -- **Sequence Probability**: - The overall probability of a sequence is calculated as the product of the probabilities of each token in the sequence. Beam Search aims to maximize this probability. -- **Beam Width (k)**: - Beam width controls the number of candidates explored at each step. Higher beam widths can improve output quality but also increase computation. -- **Normalization**: - Length normalization can be applied to avoid bias toward shorter or longer sequences, depending on the task. -- **Pruning Mechanism**: - Pruning reduces the search space by keeping only the top `k` candidates, discarding sequences with lower probabilities to manage computation. - -### Steps Involved in Beam Search: -1. **Initialize Beam**: - Start with the initial input token (e.g., `` in text generation) and calculate the initial probabilities for possible first tokens. -2. **Generate Candidates**: - For each sequence in the beam, generate possible next tokens and calculate their probabilities. -3. **Score and Prune**: - Compute scores for each candidate sequence by combining the probabilities of tokens in the sequence. Retain only the top `k` sequences. -4. **Repeat Until Termination**: - Continue expanding, scoring, and pruning until the sequences reach the end condition. -5. **Select Final Output**: - Output the sequence with the highest score among the remaining candidates. - -### Example: -```python -import torch -import torch.nn.functional as F - -def beam_search(model, start_token, end_token, beam_width, max_length): - # Initialize the beam with the start token - beam = [(start_token, 0.0)] # (sequence, score) - - for _ in range(max_length): - new_beam = [] - - # Expand each sequence in the current beam - for seq, score in beam: - # Stop expanding if end token is reached - if seq[-1] == end_token: - new_beam.append((seq, score)) - continue - - # Predict next token probabilities - predictions = model(torch.tensor([seq])) - probs = F.log_softmax(predictions[-1], dim=-1) - - # Get top beam_width tokens - top_tokens = torch.topk(probs, beam_width) - - # Add each top token to the new beam - for token, token_prob in zip(top_tokens.indices, top_tokens.values): - new_seq = seq + [token.item()] - new_score = score + token_prob.item() # Add log-probability - new_beam.append((new_seq, new_score)) - - # Prune to keep only top beam_width sequences - new_beam = sorted(new_beam, key=lambda x: x[1], reverse=True)[:beam_width] - beam = new_beam - - # Return the sequence with the highest score - return max(beam, key=lambda x: x[1])[0] - -# Example usage -start_token = 0 # example start token -end_token = 1 # example end token -beam_width = 3 -max_length = 10 - -# Simulate a model function -def model(input_seq): - # Dummy model function returning random probabilities for simplicity - return torch.randn(len(input_seq) + 1, 5000) - -output_sequence = beam_search(model, [start_token], end_token, beam_width, max_length) -print("Output Sequence:", output_sequence) - -``` - -### Summary & Applications of Beam Search: -- **Language Translation**: - Beam Search is frequently used in neural machine translation to generate coherent translations by maximizing the probability of the output sequence. -- **Speech Recognition**: - Beam Search helps select the most likely sequence of phonemes or words in automatic speech recognition. -- **Image Captioning**: - In image captioning, Beam Search is used to generate descriptive captions by exploring multiple candidate captions. -- **Text Summarization**: - Beam Search aids in summarizing texts by generating summary sequences with high probabilities, balancing informativeness and coherence. diff --git a/docs/machine-learning/Convolutional_Neural_Network.md b/docs/machine-learning/Convolutional_Neural_Network.md deleted file mode 100644 index 9a0c540b4..000000000 --- a/docs/machine-learning/Convolutional_Neural_Network.md +++ /dev/null @@ -1,176 +0,0 @@ ---- - -id: convolutional-neural-networks -title: Convolutional Neural Networks (CNN) -sidebar_label: CNNs -description: "This post explores Convolutional Neural Networks (CNN), a specialized neural network architecture widely used for tasks involving image processing and computer vision." -tags: [machine learning, deep learning, cnn, neural networks, computer vision] - ---- - -### Definition: -**Convolutional Neural Networks (CNNs)** are a class of deep neural networks specifically designed to process data with a grid-like structure, such as images. CNNs are highly effective in tasks like image classification, object detection, and recognition due to their ability to capture spatial hierarchies in data through convolutional layers. - -### Characteristics: -- **Convolutional Layers**: - CNNs use convolutional layers to automatically detect spatial features (e.g., edges, textures) from input data, reducing the number of parameters and computational cost compared to fully connected layers. - -- **Local Connectivity**: - Each neuron in a convolutional layer is connected only to a small, local region of the input data, capturing localized patterns that are useful for tasks like image and video analysis. - -- **Hierarchical Feature Learning**: - CNNs learn to extract features in a hierarchical manner, starting with low-level features (edges, textures) and progressing to more complex patterns (shapes, objects). - -### Components of CNN: -1. **Convolutional Layer**: - This layer applies a set of filters (or kernels) to the input, producing feature maps. It captures local patterns in the data by sliding the filters over the input, detecting different features at each position. - -2. **Activation Function (ReLU)**: - After convolution, a non-linear activation function, typically **ReLU (Rectified Linear Unit)**, is applied to introduce non-linearity and help the network learn complex patterns. - -3. **Pooling Layer (Subsampling)**: - The pooling layer reduces the spatial dimensions of the feature maps, summarizing the most important features and making the network more computationally efficient. Common pooling methods include **Max Pooling** and **Average Pooling**. - -4. **Fully Connected Layer**: - After the convolutional and pooling layers, the data is flattened and passed through fully connected layers. These layers combine the learned features to make predictions. - -5. **Softmax Layer (for Classification)**: - In classification tasks, the output of the last fully connected layer is passed through a **softmax** function to produce probability distributions over classes. - -### CNN Architecture: -1. **Input Layer**: - The input can be an image (e.g., 32x32 pixels with 3 color channels: RGB). CNNs can also handle other grid-like data, such as time-series or audio spectrograms. - -2. **Convolutional Layer(s)**: - Multiple convolutional layers are stacked, each extracting progressively more abstract features from the input data. - -3. **Pooling Layer(s)**: - Pooling layers (e.g., Max Pooling) are interleaved between convolutional layers to reduce the dimensionality of feature maps while retaining important information. - -4. **Fully Connected Layer(s)**: - After several convolutional and pooling layers, the feature maps are flattened and passed through fully connected layers, which serve as a classifier or regressor depending on the task. - -5. **Output Layer**: - The final fully connected layer outputs the class probabilities (for classification) or the prediction (for regression). - -### Types of Convolutions: -1. **Standard Convolution**: - A kernel is applied to the entire image, sliding over it to produce a feature map. - -2. **Depthwise Convolution**: - This type of convolution is applied separately to each input channel (e.g., RGB channels), reducing computational cost by keeping channels independent. - -3. **Dilated Convolution**: - The filter is applied with gaps between each element, allowing for a larger receptive field without increasing computational cost. - -4. **Transposed Convolution**: - Used in tasks like image generation, transposed convolutions perform the opposite operation of standard convolutions, increasing the spatial dimensions of the input. - -### Problem Statement: -Given an image dataset, the goal of a CNN is to classify the images into different categories (e.g., classifying digits in the MNIST dataset or identifying objects in CIFAR-10). CNNs are also used in segmentation, detection, and generation tasks in computer vision. - -### Key Concepts: -- **Filters (Kernels)**: - Filters are small matrices that slide over the input data to detect features like edges, corners, or textures. Multiple filters are used to detect various features. - -- **Stride**: - The number of pixels by which the filter slides over the input data. A larger stride reduces the spatial dimensions of the feature map. - -- **Padding**: - Adding pixels (typically zeros) around the input to maintain its spatial dimensions after convolution. Padding can be used to prevent shrinking of the feature maps. - -- **Receptive Field**: - The region of the input image that influences a particular feature in the output. Deeper layers in a CNN have a larger receptive field and can detect more complex features. - -- **Pooling**: - Pooling layers downsample the feature maps by summarizing regions of the data. Max pooling selects the maximum value, while average pooling computes the average. - -### Steps Involved: -1. **Input Data**: - The input is typically an image or a grid-like structure. For example, an RGB image with dimensions 32x32x3. - -2. **Convolution**: - The input is passed through convolutional layers, where multiple filters detect features like edges, corners, or textures. - -3. **Activation**: - A non-linear activation function (ReLU) is applied to the convolved output, introducing non-linearity. - -4. **Pooling**: - Pooling layers reduce the spatial dimensions of the feature maps, making the network computationally efficient. - -5. **Fully Connected Layers**: - After several convolutional and pooling layers, the feature maps are flattened and passed through fully connected layers, producing a prediction. - -6. **Output**: - For classification, the output is passed through a softmax layer, which converts the output into class probabilities. - -### Split Criteria: -CNNs split data by progressively extracting features at different layers, with lower layers detecting simple patterns (e.g., edges) and higher layers capturing complex features (e.g., objects). - -### Time Complexity: -- **Training Complexity**: - The time complexity depends on the number of filters, kernel size, and input dimensions. For an image of size $n \times n$ with $k$ filters of size $f \times f$, the time complexity of a convolutional layer is $O(n^2 \cdot f^2 \cdot k)$. - -- **Prediction Complexity**: - For inference, the time complexity depends on the depth of the network and the number of layers. - -### Space Complexity: -- **Space Complexity**: - The space complexity is proportional to the number of filters, input dimensions, and kernel size, as well as the storage for feature maps and weights. - -### Example: -Consider an example where we use a CNN to classify handwritten digits from the MNIST dataset: - -```python -import tensorflow as tf -from tensorflow.keras import layers, models - -# Load MNIST dataset -(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() - -# Preprocess data -x_train = x_train.reshape(-1, 28, 28, 1).astype('float32') / 255.0 -x_test = x_test.reshape(-1, 28, 28, 1).astype('float32') / 255.0 - -# CNN Model -model = models.Sequential() - -# Convolutional Layer -model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) -model.add(layers.MaxPooling2D((2, 2))) - -# Second Convolutional Layer -model.add(layers.Conv2D(64, (3, 3), activation='relu')) -model.add(layers.MaxPooling2D((2, 2))) - -# Fully Connected Layers -model.add(layers.Flatten()) -model.add(layers.Dense(64, activation='relu')) -model.add(layers.Dense(10, activation='softmax')) # 10 output classes for MNIST - -# Compile model -model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) - -# Train the model -model.fit(x_train, y_train, epochs=5, batch_size=64, validation_data=(x_test, y_test)) - -# Evaluate on test data -test_loss, test_acc = model.evaluate(x_test, y_test) -print(f"Test Accuracy: {test_acc}") -``` - -### Summary & Applications of CNNs: -- **Image Classification**: - CNNs are used in tasks like classifying handwritten digits (MNIST), recognizing objects in images (CIFAR-10), and classifying medical images. - -- **Object Detection**: - CNNs are widely used for detecting objects in images or videos, identifying their location, and labeling them (e.g., YOLO, R-CNN). - -- **Image Segmentation**: - In segmentation tasks, CNNs are used to assign labels to each pixel in an image, differentiating between different objects or regions. - -- **Face Recognition**: - CNNs are used for identifying or verifying individuals in photos or videos by learning facial features. - -- **Self-driving Cars**: - CNNs are used to analyze camera data and make decisions in real-time diff --git a/docs/machine-learning/DBSCAN_Clustering_Algorithm.md b/docs/machine-learning/DBSCAN_Clustering_Algorithm.md deleted file mode 100644 index 7700e25c9..000000000 --- a/docs/machine-learning/DBSCAN_Clustering_Algorithm.md +++ /dev/null @@ -1,162 +0,0 @@ ---- - -id: dbscan-clustering -title: DBSCAN Clustering Algorithm -sidebar_label: DBSCAN Clustering -description: "In this post, we'll explore DBSCAN, a density-based clustering algorithm used to identify clusters of arbitrary shape and noise in datasets." -tags: [clustering, machine learning, DBSCAN, density-based] - ---- - -### Definition: -**DBSCAN (Density-Based Spatial Clustering of Applications with Noise)** is a clustering algorithm that groups points based on the density of the data. It can identify clusters of arbitrary shapes and handle noise (outliers) effectively by grouping densely packed points and marking sparse points as noise. - -### Characteristics: -- **Density-Based**: - DBSCAN forms clusters by grouping points that are closely packed and have many neighboring points. Points in low-density regions are classified as noise. - -- **Arbitrary Shape Clusters**: - Unlike other clustering algorithms like K-Means, DBSCAN can find clusters of arbitrary shape, making it useful for non-linear data distributions. - -- **Robust to Outliers**: - DBSCAN can automatically detect and exclude outliers, as they do not belong to any dense region. - -### Key Concepts: -1. **Core Points**: - A point is considered a **core point** if it has at least `MinPts` points (including itself) within a distance `ε` (epsilon), the neighborhood radius. - -2. **Border Points**: - A **border point** is not a core point but falls within the neighborhood of a core point. - -3. **Noise Points**: - A **noise point** does not belong to any cluster. These points are outliers and do not have sufficient neighboring points to be part of a cluster. - -4. **Epsilon (ε)**: - The maximum distance between two points for them to be considered neighbors. It defines the neighborhood of a point. - -5. **MinPts**: - The minimum number of points (including the core point itself) required to form a dense region. It is a crucial parameter that controls the density threshold for forming clusters. - -### DBSCAN Clustering Process: -1. **Pick a Random Point**: - Start with a random point that has not been visited. - -2. **Check Neighborhood**: - If the point has at least `MinPts` points within distance `ε`, it becomes a core point and a new cluster is formed. Otherwise, the point is marked as noise (it may later become part of a cluster if it falls within the neighborhood of a core point). - -3. **Expand Cluster**: - Once a core point is found, all points within its `ε` neighborhood are recursively added to the cluster if they are within the defined density threshold. Border points are included if they are within the range of core points. - -4. **Mark as Clustered or Noise**: - The process continues until all points have been visited, either assigned to a cluster or labeled as noise. - -### DBSCAN Algorithm Steps: -1. For each point in the dataset that is not yet visited: - - Mark it as visited. - - Retrieve the `ε`-neighborhood of the point. - - If the point is a core point (i.e., has at least `MinPts` neighbors), create a new cluster and expand it by adding all reachable points (core and border points). - - If the point is not a core point and has fewer than `MinPts` neighbors, mark it as noise. - -2. Repeat the process until all points are either clustered or classified as noise. - -### Parameters: -- **Epsilon (ε)**: - Defines the neighborhood distance. The choice of `ε` depends on the dataset and is critical to the performance of DBSCAN. - -- **MinPts**: - Minimum number of points required to form a dense region. Typically, `MinPts` is set to a value greater than or equal to the number of dimensions plus one. - -### Advantages of DBSCAN: -- **No Need for Predefined Clusters**: - Unlike K-Means, DBSCAN does not require specifying the number of clusters beforehand. - -- **Handles Noise**: - DBSCAN is effective at handling outliers and noise, automatically marking them as noise points. - -- **Detects Arbitrary Shaped Clusters**: - DBSCAN can discover clusters of arbitrary shapes, making it suitable for complex datasets with non-linear cluster boundaries. - -### Disadvantages of DBSCAN: -- **Sensitive to Parameters**: - The performance of DBSCAN is highly sensitive to the choice of `ε` and `MinPts`. Poor choices can lead to bad clustering results. - -- **Difficulty with Varying Density**: - DBSCAN struggles when clusters have significantly varying densities, as it relies on a global `ε` and `MinPts` for all clusters. - -### Example of DBSCAN: -Consider a dataset with two dense clusters and a few scattered noise points. DBSCAN can identify the dense clusters and label the noise points as outliers. - -### Python Implementation: -Here is an example implementation of DBSCAN using **scikit-learn**: - -```python -import numpy as np -import matplotlib.pyplot as plt -from sklearn.cluster import DBSCAN -from sklearn.datasets import make_moons - -# Generate sample data (two clusters with noise) -X, _ = make_moons(n_samples=300, noise=0.05, random_state=0) - -# Apply DBSCAN clustering -dbscan = DBSCAN(eps=0.2, min_samples=5) -clusters = dbscan.fit_predict(X) - -# Plot the clusters -plt.scatter(X[:, 0], X[:, 1], c=clusters, cmap='Paired') -plt.title("DBSCAN Clustering") -plt.xlabel("Feature 1") -plt.ylabel("Feature 2") -plt.show() -``` - -### DBSCAN Parameters: -In the example above: -- `eps=0.2`: Specifies the radius of the neighborhood. -- `min_samples=5`: Sets the minimum number of points required to form a dense region. - -### Choosing `ε` and `MinPts`: -1. **Epsilon (ε)**: - The right value for `ε` depends on the dataset. You can use a **k-distance graph** to help determine the value of `ε`. Plot the distance to the `k`-th nearest point for each point and look for an "elbow" point. - -2. **MinPts**: - A common rule of thumb is to set `MinPts` to `d + 1`, where `d` is the number of dimensions in the dataset. - -### Example Clustering with Noise: -Let's look at another example where DBSCAN identifies clusters and outliers: - -```python -from sklearn.datasets import make_blobs - -# Create a dataset with clusters and outliers -X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=0) - -# Apply DBSCAN with eps=0.5 and min_samples=5 -dbscan = DBSCAN(eps=0.5, min_samples=5) -labels = dbscan.fit_predict(X) - -# Plotting the results -plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='Paired') -plt.title("DBSCAN with Clusters and Outliers") -plt.xlabel("Feature 1") -plt.ylabel("Feature 2") -plt.show() -``` - -### Example Output: -In the plot, you will see well-formed clusters identified by DBSCAN and noise points scattered across the plot, labeled separately. - -### DBSCAN Use Cases: -- **Geospatial Data**: - DBSCAN can be used for clustering spatial data, like grouping houses in a region or identifying geographic patterns. - -- **Anomaly Detection**: - By identifying outliers, DBSCAN can be used for detecting anomalies in various domains like fraud detection and intrusion detection. - -- **Customer Segmentation**: - In marketing, DBSCAN can help group customers based on purchase behavior, identifying natural customer segments and outliers. - -### Summary: -**DBSCAN (Density-Based Spatial Clustering of Applications with Noise)** is a powerful clustering algorithm that forms clusters based on the density of points. It is ideal for datasets with clusters of arbitrary shapes and handles noise effectively. While it is sensitive to its parameters (`ε` and `MinPts`), it offers a robust solution for many real-world clustering problems, including anomaly detection, geospatial clustering, and pattern recognition. - ---- diff --git a/docs/machine-learning/Extra_Trees.md b/docs/machine-learning/Extra_Trees.md deleted file mode 100644 index ea6616d80..000000000 --- a/docs/machine-learning/Extra_Trees.md +++ /dev/null @@ -1,129 +0,0 @@ ---- - -id: extra-trees -title: Extra Trees Algorithm -sidebar_label: Extra Trees -description: "In this post, we’ll explore the Extra Trees Algorithm, an ensemble learning model used for classification and regression tasks, known for its efficiency and randomness in both feature selection and data sampling." -tags: [machine learning, algorithms, extra trees, classification, regression] - ---- - -### Definition: -The **Extra Trees Algorithm** (Extremely Randomized Trees) is an ensemble learning technique similar to Random Forest, but with added randomness in the way splits are selected during tree construction. Like random forests, it is applicable to both **classification** and **regression** tasks. The key difference is that Extra Trees chooses split points randomly for each feature, making the trees more varied and often faster to train than random forests. - -### Characteristics: -- **Extreme Randomness in Split Selection**: - Unlike traditional decision trees and random forests, Extra Trees selects a split point randomly from a range of possible values, increasing variability among trees in the ensemble. - -- **Efficiency**: - Since the split points are selected randomly rather than by calculating the best split (as in random forests), Extra Trees tend to be faster to train while maintaining competitive accuracy. - -- **Bias-Variance Tradeoff**: - Extra Trees generally reduce variance compared to single decision trees, but they may introduce more bias due to the randomness in split selection. However, the ensemble effect mitigates this, often leading to strong overall performance. - -### Types of Extra Trees: -1. **Classification Trees**: - Used when the target variable is categorical. The model makes predictions by averaging votes across all trees to assign a class label. - -2. **Regression Trees**: - Used for continuous target variables. The algorithm averages the output of all trees to generate the final prediction for regression tasks. - -### Steps Involved: -1. **Bootstrap Sampling (Optional)**: - Unlike random forests, Extra Trees can optionally use the full dataset for training each tree without bootstrapping. When bootstrapping is used, the training process is similar to random forests. - -2. **Random Feature Subset Selection**: - At each node, a random subset of features is selected. However, instead of finding the optimal split, Extra Trees choose a random split point from the range of possible values for the selected feature. - -3. **Grow Decision Trees**: - Each tree is grown to its full depth without pruning. The extreme randomness makes the individual trees more diverse but potentially less accurate in isolation. - -4. **Aggregate Results**: - For classification tasks, the final prediction is made by majority voting across all trees. For regression tasks, the final output is the average of the predictions from all trees. - -### Problem Statement: -Given a dataset with features and target values, the goal is to build an ensemble of extremely randomized decision trees that can **classify** data points or **predict** continuous values based on random splits and random feature selection. - -### Key Concepts: -- **Random Split Selection**: - Instead of selecting the best split by maximizing a criterion (e.g., Gini impurity or information gain), Extra Trees choose a random split from possible values, increasing randomness and diversity among trees. - -- **Aggregation Methods**: - - **Majority Voting (for Classification)**: - The class predicted by the majority of trees is the final output. - - **Averaging (for Regression)**: - The average of the predictions from all trees gives the final result. - -### Split Criteria: -- **Random Split Points**: - While traditional decision trees optimize split criteria such as Gini impurity or entropy, Extra Trees randomly select split points, making the algorithm computationally cheaper but still effective. - -- **Gini Impurity** or **Entropy** for classification and **Mean Squared Error (MSE)** for regression tasks can still be used to evaluate the quality of the random splits after they are made. - -### Time Complexity: -- **Training Complexity**: - For `T` trees trained on `n` samples with `d` features, the time complexity is approximately $O(T \cdot n \cdot \log n)$, as splits are selected randomly without the need to evaluate all possible splits. This makes the algorithm faster than random forests. - -- **Prediction Complexity**: - Like random forests, prediction complexity is $O(T \cdot \log n)$, where `T` is the number of trees and `n` is the number of samples. - -### Space Complexity: -- **Space Complexity**: - The space complexity is $O(T \cdot n \cdot d)$ due to the need to store `T` trees, each containing `n` samples and `d` features. - -### Example: -Consider a dataset where the goal is to predict customer churn based on features like age, income, and activity: - -- Dataset: -| Age | Income | Active | Churned | -|-----|--------|--------|---------| -| 25 | High | Yes | No | -| 45 | Medium | No | Yes | -| 35 | Low | Yes | No | -| 22 | Low | No | Yes | - -Step-by-Step Execution: - -1. **Bootstrap Sampling**: - Optionally, a random sample of the dataset is selected for training each tree. - -2. **Random Feature Selection and Split**: - At each node, Extra Trees randomly select features and then randomly select split points from the feature’s value range. - -3. **Grow Trees**: - Each tree is grown to its maximum depth without pruning. - -4. **Aggregate Predictions**: - For classification tasks, predictions are based on the majority vote from all trees. For regression tasks, the final output is the average prediction across all trees. - -### Python Implementation: -Here’s a simple implementation of the Extra Trees Algorithm using **scikit-learn**: - -```python -from sklearn.datasets import load_iris -from sklearn.ensemble import ExtraTreesClassifier -from sklearn.model_selection import train_test_split -from sklearn.metrics import accuracy_score - -# Load dataset -iris = load_iris() -X, y = iris.data, iris.target - -# Split dataset -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - -# Create Extra Trees classifier -clf = ExtraTreesClassifier(n_estimators=100, random_state=42) - -# Train model -clf.fit(X_train, y_train) - -# Predict -y_pred = clf.predict(X_test) - -# Evaluate -accuracy = accuracy_score(y_test, y_pred) -print(f"Accuracy: {accuracy:.2f}") -``` - ---- diff --git a/docs/machine-learning/GBM.md b/docs/machine-learning/GBM.md deleted file mode 100644 index 1c1904edb..000000000 --- a/docs/machine-learning/GBM.md +++ /dev/null @@ -1,174 +0,0 @@ ---- - -id: gbm-visualizations -title: Gradient Boosting Machines (GBM) Visualization -sidebar_label: GBM -description: "Explore the Gradient Boosting Machines (GBM) algorithm for machine learning, including popular variants like XGBoost and LightGBM. Learn how it builds models sequentially, improving performance by correcting errors from previous models." -tags: [machine learning, gradient boosting, XGBoost, LightGBM, data visualization, ensemble learning] - ---- - -### Definition: -**Gradient Boosting Machines (GBM)** are a family of machine learning algorithms that build models sequentially. Each new model focuses on correcting the errors made by previous models. The primary objective of GBM is to minimize a loss function by combining weak learners (typically decision trees) into a stronger model. - -### Characteristics: -- **Sequential Learning**: - GBMs build models in a step-by-step fashion, correcting errors from previous iterations. - -- **Gradient Descent Optimization**: - Each new model is trained to minimize the residual errors of the previous models by leveraging gradient descent optimization. - -- **Boosting Technique**: - By emphasizing difficult-to-predict observations, GBMs create a powerful predictive model that outperforms individual weak learners. - -### Components of GBM: -1. **Base Learner (Weak Learner)**: - Typically, decision trees are used as the base learners in GBM. They are sequentially improved to correct errors from earlier iterations. - -2. **Gradient Descent**: - GBM uses gradient descent to minimize the loss function by adjusting the parameters of the model iteratively. - -3. **Learning Rate**: - A key hyperparameter that controls the contribution of each new model to the ensemble. A smaller learning rate requires more iterations but often leads to better accuracy. - -4. **Loss Function**: - Different loss functions can be used depending on the task (e.g., mean squared error for regression, log loss for classification). The choice of loss function directly impacts how the errors are corrected. - -### Steps Involved: -1. **Initialize the Model**: - Start by initializing the predictions with a simple model (often the mean for regression or uniform distribution for classification). - -2. **Compute Residuals**: - Calculate the residuals, which are the differences between the actual values and the current predictions. - -3. **Fit a New Learner to Residuals**: - Train a new decision tree to predict the residuals from the previous model. - -4. **Update Predictions**: - Adjust the predictions by adding a fraction of the new learner's output (based on the learning rate). - -5. **Iterate**: - Repeat the process until a stopping criterion is met (e.g., maximum iterations or minimal improvement). - -6. **Final Model**: - The final model is a weighted sum of all the models built during the iterations. - -### Key Concepts: -- **Boosting**: - A method that converts weak learners into a strong learner by emphasizing the correction of errors made in earlier iterations. - -- **Learning Rate**: - Controls how much each new model contributes to the ensemble. Lower values result in slower but more reliable convergence. - -- **Loss Function**: - Measures the accuracy of the model. The gradient of the loss function guides the learning process. - -- **Tree Depth**: - The depth of each decision tree controls the complexity of the model. Shallow trees are less likely to overfit, while deeper trees capture more complex patterns. - -### GBM Algorithm Architecture: -1. **Input Layer**: - The input consists of the training dataset with features and targets. The process begins with an initial guess or simple prediction (like the mean value). - -2. **Residual Computation Layer**: - Residuals are calculated by subtracting the predicted values from the true values. - -3. **Weak Learner Training Layer**: - Decision trees are trained on the residuals to learn the patterns missed by previous models. - -4. **Model Update Layer**: - Each new learner's output is scaled by the learning rate and added to the ensemble model's predictions. - -5. **Output Layer**: - The final predictions are a combination of all models created in the process, leading to an improved and accurate predictive model. - -### Advantages of GBM: -- **High Predictive Accuracy**: - GBMs are known for their superior predictive power, especially in competitions and real-world applications. - -- **Flexibility**: - They can handle a variety of data types and loss functions, making them versatile for different machine learning tasks. - -- **Feature Importance**: - GBMs provide insights into the most influential features in the dataset, making them useful for feature selection and interpretability. - -### Limitations of GBM: -- **Computational Complexity**: - Training GBMs can be computationally intensive, especially for large datasets or deep trees. - -- **Overfitting Risk**: - GBMs are prone to overfitting if the model is too complex or the learning rate is too high. - -- **Hyperparameter Tuning**: - GBMs require careful tuning of parameters like learning rate, tree depth, and number of iterations to achieve optimal performance. - -### Popular Variants: -1. **XGBoost**: - A highly optimized version of GBM that uses advanced regularization techniques, tree-pruning, and parallel processing to speed up training. - -2. **LightGBM**: - A variant designed for speed and efficiency, particularly on large datasets. It uses a novel leaf-wise tree growth strategy and histogram-based learning. - -3. **CatBoost**: - A gradient boosting library specifically designed to handle categorical features without extensive preprocessing. - -### Use Cases: -1. **Classification & Regression**: - GBMs excel in both classification and regression tasks, commonly used in areas like financial risk prediction, fraud detection, and customer segmentation. - -2. **Ranking**: - GBMs are popular in ranking applications, such as search engines, recommendation systems, and personalized advertising. - -3. **Feature Engineering**: - GBMs can be used for feature selection, identifying which features contribute the most to the predictive power of the model. - -4. **Time-Series Forecasting**: - GBMs can be adapted for time-series analysis, predicting future values based on past observations. - -### Example of GBM in Python: -```python -import numpy as np -import matplotlib.pyplot as plt -from sklearn.datasets import load_boston -from sklearn.model_selection import train_test_split -from sklearn.ensemble import GradientBoostingRegressor -from sklearn.metrics import mean_squared_error - -# Load dataset -data = load_boston() -X = data.data -y = data.target - -# Split data into training and testing sets -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) - -# Train GBM model -gbm = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42) -gbm.fit(X_train, y_train) - -# Predictions -y_pred = gbm.predict(X_test) - -# Plot predictions vs. actual values -plt.figure(figsize=(8, 6)) -plt.scatter(y_test, y_pred, alpha=0.7, color='blue') -plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color='red', lw=2) -plt.title("GBM Predictions vs. Actual Values") -plt.xlabel("Actual") -plt.ylabel("Predicted") -plt.show() -``` - -### Time and Space Complexity: -- **Time Complexity**: - Training time is roughly $O(m \cdot d \cdot n \cdot \log(n))$, where $m$ is the number of iterations, $d$ is the average depth of the trees, and $n$ is the number of data points. - -- **Space Complexity**: - Space complexity is $O(n \cdot d)$ due to the storage required for decision trees. - -### Summary & Applications: -- **Gradient Boosting Machines (GBM)** combine multiple weak learners (decision trees) in a sequential manner to create a strong predictive model. They are renowned for their versatility and high accuracy in machine learning tasks. - -- **Applications**: - GBMs are widely used in finance, healthcare, marketing, and many other fields for predictive modeling, ranking tasks, and feature importance analysis. - diff --git a/docs/machine-learning/Gaussian_Mixture_Model.md b/docs/machine-learning/Gaussian_Mixture_Model.md deleted file mode 100644 index bd5b1e633..000000000 --- a/docs/machine-learning/Gaussian_Mixture_Model.md +++ /dev/null @@ -1,154 +0,0 @@ ---- - -id: gaussian-mixture-models -title: Gaussian Mixture Models (GMM) -sidebar_label: GMM -description: "This post explores Gaussian Mixture Models (GMM), a probabilistic model for representing normally distributed subpopulations within a larger population." -tags: [machine learning, clustering, gmm, gaussian, statistics] - ---- - -### Definition: -**Gaussian Mixture Models (GMMs)** are a probabilistic model used to represent a mixture of multiple Gaussian distributions within a dataset. GMMs are commonly applied in clustering tasks where data is assumed to be generated from several Gaussian-distributed subpopulations, but the identity of the subpopulation to which a particular data point belongs is unknown. - -### Characteristics: -- **Probabilistic Model**: - GMM represents each data point as belonging to one of several Gaussian distributions, each with its own mean, covariance, and weight (prior probability). - -- **Soft Clustering**: - Unlike methods like K-Means, which provide hard assignments of data points to clusters, GMM assigns each data point a probability of belonging to each cluster. - -- **Multivariate Gaussian Distributions**: - GMMs can model data in multiple dimensions, with each Gaussian component having its own covariance matrix, allowing for flexibility in cluster shapes. - -### Components of GMM: -1. **Gaussian Components**: - Each component in GMM is a Gaussian distribution, defined by a mean vector, a covariance matrix, and a mixing coefficient. The model assumes that data points are drawn from these Gaussian distributions. - -2. **Means**: - The mean vector defines the center of each Gaussian distribution, representing the location of the cluster in the feature space. - -3. **Covariance Matrix**: - This matrix defines the shape and orientation of each Gaussian distribution. Depending on the covariance type (full, diagonal, tied, spherical), GMM can model clusters with different sizes and orientations. - -4. **Mixing Coefficients**: - Mixing coefficients (or weights) represent the proportion of data points that belong to each Gaussian component, summing to 1 across all components. - -5. **Expectation-Maximization (EM) Algorithm**: - GMM parameters are typically estimated using the EM algorithm, which iteratively assigns probabilities to each data point and updates the model parameters to maximize the likelihood of the data. - -### GMM Architecture: -1. **Input Data**: - The input to a GMM can be multi-dimensional data points, such as 2D or 3D points, where the goal is to identify underlying subgroups or clusters within the data. - -2. **Gaussian Components**: - The model assumes that the data comes from a mixture of Gaussian distributions, each representing a potential cluster in the data. - -3. **EM Algorithm**: - The Expectation-Maximization algorithm alternates between two steps: - - **Expectation (E-step)**: Calculates the probability of each data point belonging to each Gaussian component (soft assignments). - - **Maximization (M-step)**: Updates the parameters of each Gaussian component (mean, covariance, and weights) based on the data's probability distribution from the E-step. - -4. **Cluster Assignment**: - After convergence, data points are assigned to clusters based on their highest probability of belonging to a particular Gaussian component. - -### Covariance Types in GMM: -1. **Full Covariance**: - Each Gaussian component has its own general covariance matrix, allowing clusters to take on any elliptical shape. - -2. **Diagonal Covariance**: - Each Gaussian component has its own diagonal covariance matrix, implying that features are independent but can have different variances. - -3. **Tied Covariance**: - All Gaussian components share the same covariance matrix, limiting the flexibility of cluster shapes. - -4. **Spherical Covariance**: - Each Gaussian component has a covariance matrix that is a scaled identity matrix, meaning clusters are spherical and have the same radius. - -### Problem Statement: -Given a set of multi-dimensional data points, the goal of GMM is to model the data as being generated from a mixture of several Gaussian distributions. This helps in clustering the data points into different subpopulations based on their probability of belonging to each Gaussian component. - -### Key Concepts: -- **Latent Variables**: - In GMM, each data point is assumed to be associated with a hidden or latent variable, indicating which Gaussian component it comes from. - -- **Likelihood**: - GMM maximizes the likelihood of the data, which is the probability that the observed data was generated by the mixture of Gaussian distributions. - -- **Posterior Probability**: - The posterior probability gives the likelihood that a data point belongs to a particular Gaussian component, computed during the E-step of the EM algorithm. - -- **Convergence**: - The EM algorithm iterates between the E-step and M-step until the parameters converge, i.e., the likelihood does not change significantly between iterations. - -### Steps Involved: -1. **Initialize Parameters**: - Initialize the means, covariance matrices, and mixing coefficients for each Gaussian component, either randomly or using a method like K-Means. - -2. **Expectation Step**: - For each data point, calculate the probability that it belongs to each Gaussian component based on the current parameters. - -3. **Maximization Step**: - Update the means, covariance matrices, and mixing coefficients of each Gaussian component based on the probabilities calculated in the E-step. - -4. **Repeat**: - Repeat the E-step and M-step until the model parameters converge. - -5. **Cluster Assignment**: - Assign each data point to the Gaussian component with the highest posterior probability, or retain the soft assignments for probabilistic clustering. - -### Example: - -```python -from sklearn.mixture import GaussianMixture -import numpy as np - -# Generate synthetic data -np.random.seed(42) -data = np.vstack([ - np.random.normal(loc=0, scale=1, size=(100, 2)), - np.random.normal(loc=5, scale=1.5, size=(100, 2)) -]) - -# Fit a GMM model with 2 components -gmm = GaussianMixture(n_components=2, covariance_type='full') -gmm.fit(data) - -# Predict the cluster for each data point -labels = gmm.predict(data) - -# Get the probabilities of each data point belonging to each Gaussian component -probs = gmm.predict_proba(data) - -# Print the means and covariances of the Gaussian components -print("Means:", gmm.means_) -print("Covariances:", gmm.covariances_) -``` - -### Summary & Applications of GMM: -- **Clustering**: - GMMs are widely used in clustering tasks, particularly when clusters are not well-separated or when clusters have different shapes and sizes. - -- **Anomaly Detection**: - GMMs can be used to detect anomalies or outliers in the data by modeling the normal data as a mixture of Gaussians and flagging points with low likelihood under this model. - -- **Density Estimation**: - GMMs are used for density estimation, allowing for probabilistic modeling of the data distribution, useful in scenarios where data is continuous. - -- **Speech Recognition**: - GMMs are a key component in traditional speech recognition systems, where they model the distribution of feature vectors corresponding to different phonemes. - -- **Image Segmentation**: - GMMs can be used for segmenting images into regions by modeling pixel intensities as a mixture of Gaussians. - -### Time Complexity: -- **Training Complexity**: - The time complexity of fitting a GMM with EM is generally $O(n \cdot d^2 \cdot k \cdot t)$, where $n$ is the number of data points, $d$ is the dimensionality, $k$ is the number of components, and $t$ is the number of iterations until convergence. - -- **Prediction Complexity**: - For inference, the complexity is $O(n \cdot d^2 \cdot k)$, where $n$ is the number of data points, $d$ is the dimensionality, and $k$ is the number of Gaussian components. - -### Space Complexity: -- **Space Complexity**: - GMM space complexity depends on the number of components $k$, dimensionality $d$, and the number of data points $n$, typically $O(k \cdot d^2)$ for storing the parameters. - diff --git a/docs/machine-learning/Generative_Adversarial_Networks.md b/docs/machine-learning/Generative_Adversarial_Networks.md deleted file mode 100644 index 027b36bb4..000000000 --- a/docs/machine-learning/Generative_Adversarial_Networks.md +++ /dev/null @@ -1,173 +0,0 @@ ---- - -id: generative-adversarial-networks -title: Generative Adversarial Networks (GAN) -sidebar_label: GANs -description: "In this post, we'll explore Generative Adversarial Networks (GAN), a powerful class of neural networks used for generating new data based on learned distributions." -tags: [deep learning, neural networks, GANs, generative models] - ---- - -### Definition: -**Generative Adversarial Networks (GANs)** are a class of deep learning models designed to generate new data samples that are similar to a given dataset. GANs consist of two neural networks, the **generator** and the **discriminator**, which are trained simultaneously in a game-theoretic setting. The **generator** learns to produce realistic data, while the **discriminator** tries to distinguish between real and generated data. This adversarial process helps the generator improve over time. - -### Characteristics: -- **Generative Model**: - GANs are used to generate new, previously unseen data samples that resemble the training data. - -- **Adversarial Training**: - The generator and discriminator are trained simultaneously in a competitive setting, each improving as the other learns. - -- **Unsupervised Learning**: - GANs typically work with unlabeled data, making them suitable for unsupervised learning tasks. - -### How GANs Work: -1. **Generator**: - The generator is a neural network that takes random noise as input and generates synthetic data (e.g., images, text) that resemble the real data. The goal of the generator is to produce data that the discriminator cannot distinguish from real data. - -2. **Discriminator**: - The discriminator is another neural network that takes both real data and generated data as input and tries to classify whether the input is real (from the dataset) or fake (generated by the generator). The discriminator's task is binary classification. - -3. **Adversarial Process**: - The generator and discriminator play a two-player minimax game, where the generator tries to fool the discriminator, and the discriminator tries not to be fooled. The objective of the generator is to minimize the discriminator's accuracy, while the discriminator's goal is to maximize its classification accuracy. - -### Objective Function: -The objective function for GANs is a **minimax game** where the generator $G$ tries to minimize the loss, and the discriminator $D$ tries to maximize it. This is given by: - -![image](https://github.com/user-attachments/assets/684b5961-1fad-4995-8632-c7d3e0d51da5) - - -Where: -- ![image](https://github.com/user-attachments/assets/ca6c5152-87c0-46db-a8d6-2b29c1cb0622) - is the distribution of the real data. -- ![image](https://github.com/user-attachments/assets/d03461ef-0afc-4136-a22a-233766f7208d) - is the distribution of the random noise input. -- $D(x)$ is the probability that &( x )$ is real. -- $G(z)$ is the generator's output based on random noise $( z )$. - -### Types of GANs: -1. **Vanilla GAN**: - The basic form of GAN where the generator and discriminator are both fully connected networks. - -2. **Conditional GAN (cGAN)**: - A variant of GAN where both the generator and discriminator are conditioned on additional information, such as class labels or data attributes. This allows for controlled generation of specific types of data. - -3. **Deep Convolutional GAN (DCGAN)**: - A type of GAN that uses convolutional neural networks (CNNs) in both the generator and discriminator, making it especially effective for generating high-quality images. - -4. **CycleGAN**: - A GAN that learns to translate images from one domain to another without paired examples (e.g., turning a photo of a horse into a zebra). - -### How GANs Are Trained: -1. **Step 1**: - The generator creates synthetic data from random noise. - -2. **Step 2**: - The discriminator takes both real data and generated data as input and classifies them as real or fake. - -3. **Step 3**: - The generator's goal is to make the discriminator classify the generated data as real, while the discriminator aims to correctly distinguish between real and fake data. - -4. **Step 4**: - During backpropagation, the generator updates its parameters to fool the discriminator, while the discriminator updates its parameters to become better at detecting fake data. - -5. **Repeat**: - The process continues until the generator produces data indistinguishable from real data, and the discriminator is unable to tell the difference with a 50% accuracy rate. - -### Key Concepts: -- **Adversarial Loss**: - The loss function used in GANs where the generator tries to minimize the discriminator's accuracy, and the discriminator tries to maximize its accuracy. - -- **Mode Collapse**: - A common issue in GANs where the generator produces limited or repetitive outputs, failing to capture the full diversity of the training data. - -- **Wasserstein GAN (WGAN)**: - An improved GAN variant that uses the Wasserstein distance as a loss function, helping to stabilize training and reduce mode collapse. - -### Example of GAN Architecture: - -1. **Generator Network**: - - Input: Random noise vector (e.g., $z \sim N(0, 1)$). - - Output: Synthetic data (e.g., an image). - - ![Generator Network](https://github.com/user-attachments/assets/e457fd7f-a8c5-46d8-a3be-2a517f8bcdd4) - -2. **Discriminator Network**: - - Input: Real or generated data. - - Output: Probability that the input is real or fake. - - ![Discriminator Network](https://github.com/user-attachments/assets/f9f5d21f-a9d4-4fcb-b84b-96a2e9b3de63) - -### Applications of GANs: -1. **Image Generation**: - GANs are widely used to generate high-quality images, including art, photos, and even realistic human faces. - -2. **Data Augmentation**: - GANs can be used to augment datasets by generating additional data points, improving model training. - -3. **Image-to-Image Translation**: - CycleGANs and other GAN variants can translate images from one domain to another (e.g., turning a winter scene into a summer scene). - -4. **Text-to-Image Generation**: - GANs can be used to generate images based on textual descriptions. - -### Python Implementation: -Here is a basic implementation of a simple GAN in Python using **TensorFlow**: - -```python -import tensorflow as tf -from tensorflow.keras import layers - -# Generator model -def build_generator(): - model = tf.keras.Sequential() - model.add(layers.Dense(128, input_dim=100, activation='relu')) - model.add(layers.Dense(784, activation='sigmoid')) - return model - -# Discriminator model -def build_discriminator(): - model = tf.keras.Sequential() - model.add(layers.Dense(128, input_dim=784, activation='relu')) - model.add(layers.Dense(1, activation='sigmoid')) - return model - -# Build and compile models -generator = build_generator() -discriminator = build_discriminator() -discriminator.compile(loss='binary_crossentropy', optimizer='adam') - -# GAN model (generator + discriminator) -discriminator.trainable = False -gan_input = layers.Input(shape=(100,)) -gan_output = discriminator(generator(gan_input)) -gan = tf.keras.Model(gan_input, gan_output) -gan.compile(loss='binary_crossentropy', optimizer='adam') - -# Train the GAN (example code) -import numpy as np - -def train_gan(gan, generator, discriminator, epochs, batch_size=128): - for epoch in range(epochs): - # Generate random noise - noise = np.random.normal(0, 1, (batch_size, 100)) - generated_data = generator.predict(noise) - - # Get real data (placeholder for real dataset) - real_data = np.random.rand(batch_size, 784) # Example real data - - # Train discriminator - combined_data = np.concatenate([real_data, generated_data]) - labels = np.concatenate([np.ones(batch_size), np.zeros(batch_size)]) - discriminator.train_on_batch(combined_data, labels) - - # Train generator - noise = np.random.normal(0, 1, (batch_size, 100)) - misleading_labels = np.ones(batch_size) - gan.train_on_batch(noise, misleading_labels) -``` - -### Summary: -Generative Adversarial Networks (GANs) are a powerful and flexible class of deep learning models for generating new data that resemble the input dataset. By leveraging an adversarial process, GANs can learn complex distributions, making them suitable for tasks like image generation, data augmentation, and domain translation. However, GAN training can be unstable, and addressing challenges like mode collapse is essential for producing high-quality results. - ---- diff --git a/docs/machine-learning/HBOS.md b/docs/machine-learning/HBOS.md deleted file mode 100644 index 09693b642..000000000 --- a/docs/machine-learning/HBOS.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -id: histogram-based-outlier-score -title: Histogram-Based Outlier Score (HBOS) -sidebar_label: HBOS -description: "In this post, we'll explore Histogram-Based Outlier Score (HBOS), an unsupervised anomaly detection technique that analyzes each feature independently." -tags: [anomaly detection, outlier detection, unsupervised learning] - ---- - -### Overview -Histogram-Based Outlier Score (HBOS) is an unsupervised anomaly detection technique that assumes independence between features and analyzes each feature independently. It calculates histograms for each feature and then evaluates the "outlierness" of a data point based on its position in the histogram bins. - -The main idea is that points falling in bins with low frequencies (rare occurrences) are more likely to be considered outliers. - -### How HBOS Works - -1. **Feature Independence Assumption**: - - HBOS assumes that all features are independent, which simplifies the computation. - - This allows the detection process to analyze each feature individually without considering multivariate dependencies. - -2. **Creating Histograms for Each Feature**: - - For each feature in the dataset, a histogram is created by dividing the range of the feature into several bins. - - The number of bins and the binning strategy can be set manually or determined automatically. - -3. **Scoring Data Points**: - - The outlier score for a data point is calculated based on the inverse of the bin frequency for each feature. If a data point falls into a bin with a low frequency (i.e., fewer samples), it is assigned a higher outlier score. - - The final outlier score for a data point is often the product of the individual scores for each feature (assuming independence). Alternatively, the sum of logarithmic scores can be used for numerical stability. - -4. **Normalization of Scores**: - - Scores are typically normalized to fall within a certain range, such as [0, 1], to facilitate interpretation. - -### Mathematical Formulation - -Let **x** = (x₁, x₂, ..., xₙ) be a data point in an n-dimensional feature space. The outlier score for the data point **x**, denoted as HBOS(x), is computed based on the frequency of each feature value in the histogram bins. - -### Step 1: Construct Histograms -For each feature *i*, construct a histogram with *bᵢ* bins. The frequency of data points falling within each bin is used to estimate the probability distribution for the feature. - -### Step 2: Calculate the Probability for Each Feature -The probability for a feature value *xᵢ* to fall within a particular bin is given by: -Pᵢ(xᵢ) = (count of data points in the bin containing xᵢ) / (total number of data points) - -### Step 3: Compute the HBOS Score -The HBOS score for the data point **x** is then calculated as the product of the inverse probabilities for each feature (assuming feature independence): - -HBOS(x) = ∏ (1 / Pᵢ(xᵢ)), for i = 1 to n - -Alternatively, a logarithmic version can be used to improve numerical stability: - -HBOS(x) = ∑ -log(Pᵢ(xᵢ)), for i = 1 to n - -### Advantages of HBOS - -- **Computational Efficiency**: Since each feature is processed independently, HBOS is computationally efficient and can handle large datasets with high dimensions. -- **Scalability**: It scales well with the number of data points and features, making it suitable for big data applications. -- **Interpretability**: The algorithm is straightforward to understand and interpret, especially in cases where the distributions of features are known. - -### Limitations of HBOS - -- **Independence Assumption**: The primary limitation is the assumption that features are independent. This may not hold in many real-world datasets, leading to less effective anomaly detection. -- **Binning Sensitivity**: The choice of the number of bins and binning strategy can significantly affect the results. Improper binning may lead to missed or false detections of anomalies. -- **Univariate Approach**: As it handles each feature separately, it may not detect anomalies that only manifest when considering the interaction between multiple features. - -### Use Cases for HBOS - -- **Network Intrusion Detection**: Identifying unusual patterns in network traffic based on individual features like packet size, duration, or frequency. -- **Credit Card Fraud Detection**: Detecting unusual transactions by evaluating independent features such as transaction amount or frequency. -- **Sensor Data Monitoring**: Identifying anomalies in IoT sensor data by assessing readings for individual sensors. - -### Implementation Example (Python) - -Here's a basic example of how HBOS can be implemented using Python with the `pyod` library: - -```python -from pyod.models.hbos import HBOS -from sklearn.datasets import make_classification - -# Generate synthetic data -X, _ = make_classification(n_samples=1000, n_features=10, contamination=0.1, random_state=42) - -# Initialize HBOS detector -hbos = HBOS(n_bins=10, alpha=0.1) - -# Fit the model -hbos.fit(X) - -# Predict anomaly scores -anomaly_scores = hbos.decision_function(X) - -# Get binary labels (0: inlier, 1: outlier) -anomaly_labels = hbos.predict(X) - -print("Anomaly Scores:", anomaly_scores) -print("Anomaly Labels:", anomaly_labels) -``` diff --git a/docs/machine-learning/Hidden_Markov_Model.md b/docs/machine-learning/Hidden_Markov_Model.md deleted file mode 100644 index 8086b60c7..000000000 --- a/docs/machine-learning/Hidden_Markov_Model.md +++ /dev/null @@ -1,142 +0,0 @@ ---- - -id: hidden-markov-model -title: Hidden Markov Models (HMM) Algorithm -sidebar_label: Hidden Markov Models -description: "In this post, we'll explore Hidden Markov Models (HMMs), a statistical model that represents systems with hidden and observable states, commonly used for sequence data in various domains." -tags: [machine learning, hidden markov model, HMM, sequence modeling] - ---- - -### Definition: -**Hidden Markov Models (HMMs)** are statistical models that represent systems as a set of hidden states and observable sequences. They are widely used for sequential data modeling, where the system evolves over time and only observable data points can be seen, while the underlying states remain hidden. - -### Characteristics: -- **Probabilistic Transitions**: - The model represents transitions between states as probabilities. Each state has a probability of transitioning to another state or staying the same. - -- **Hidden and Observable States**: - HMMs have two types of states: hidden states, which define the unobserved structure, and observable states, which can be directly measured. - -- **Sequence Modeling**: - HMMs are suitable for time-series data, natural language processing, and speech recognition, where the sequence order and probabilistic dependencies are important. - -### Key Concepts: -1. **States**: - States in HMMs are categorized into hidden states (not directly observed) and observable states (can be observed). Examples include the weather (hidden) and umbrella usage (observable). - -2. **Transition Probabilities**: - Defines the probability of transitioning from one hidden state to another, representing the likelihood of moving between different states in the system. - -3. **Emission Probabilities**: - The probability of observing a particular observation given a hidden state, representing how likely an observation is based on the hidden state. - -4. **Initial State Distribution**: - The probability of starting in each hidden state at the beginning of the sequence. - -### Hidden Markov Model Process: -1. **Define States and Observations**: - Identify the hidden and observable states based on the system or data structure. - -2. **Specify Parameters**: - Determine the transition and emission probabilities and initial state distribution based on training data or domain knowledge. - -3. **Train the Model**: - Use data to estimate the parameters (transition, emission probabilities, etc.) or utilize algorithms like the Baum-Welch for training. - -4. **Inference with the Model**: - Use algorithms like the **Viterbi** algorithm for the most probable state sequence or the **Forward-Backward** algorithm to calculate the probability of a sequence. - -### HMM Algorithm Steps: -1. **Initialize Model Parameters**: - Define initial probabilities for states, transition probabilities, and emission probabilities. - -2. **Calculate Forward Probabilities**: - Use the Forward algorithm to compute the probability of observing a sequence given the model. - -3. **Compute Backward Probabilities**: - Apply the Backward algorithm to find probabilities of observing the remaining part of the sequence, starting from each hidden state. - -4. **Viterbi Algorithm**: - Use the Viterbi algorithm to determine the most likely sequence of hidden states given the observations. - -### Parameters: -- **Transition Probability Matrix**: - A matrix where each cell \((i, j)\) represents the probability of transitioning from state \(i\) to state \(j\). - -- **Emission Probability Matrix**: - Each cell represents the probability of an observable state given a hidden state. - -- **Initial State Probability Vector**: - Vector specifying the starting probability of each state in the sequence. - -### Advantages of HMM: -- **Captures Temporal Dependencies**: - Ideal for sequential and time-series data, where the order of events is crucial. - -- **Good for Partially Observable Data**: - Useful in situations where only partial data (observations) is visible, but underlying states are hidden. - -### Disadvantages of HMM: -- **Limited to Markov Assumptions**: - Assumes that future states depend only on the current state, which may be restrictive for some applications. - -- **Parameter Estimation Complexity**: - Requires large amounts of data for accurate parameter estimation, which can be computationally intensive. - -### Python Implementation: -Here is an example implementation of HMM using **hmmlearn**: - -```python -import numpy as np -from hmmlearn import hmm - -# Define states and observations -states = ["Rainy", "Sunny"] -observations = ["walk", "shop", "clean"] - -# Convert to numerical format -state_map = {state: i for i, state in enumerate(states)} -obs_map = {obs: i for i, obs in enumerate(observations)} - -# Initialize the model -model = hmm.MultinomialHMM(n_components=len(states), n_iter=100) - -# Define model parameters (probabilities should sum to 1) -model.startprob_ = np.array([0.6, 0.4]) # Initial state distribution -model.transmat_ = np.array([ - [0.7, 0.3], # Transition probabilities from "Rainy" - [0.4, 0.6] # Transition probabilities from "Sunny" -]) -model.emissionprob_ = np.array([ - [0.1, 0.4, 0.5], # Emission probabilities for "Rainy" - [0.6, 0.3, 0.1] # Emission probabilities for "Sunny" -]) - -# Define an observation sequence -obs_seq = np.array([[obs_map["walk"]], [obs_map["shop"]], [obs_map["clean"]]]) - -# Fit the model (if training needed) and predict hidden states -model.fit(obs_seq) -logprob, hidden_states = model.decode(obs_seq, algorithm="viterbi") - -print("Most likely hidden states:", [states[state] for state in hidden_states]) -``` - -### HMM Parameters: -In the example above: -- `startprob_`: Specifies the initial state probabilities. -- `transmat_`: Defines the transition probability matrix. -- `emissionprob_`: Specifies the emission probability matrix for each observable state. - -### Choosing Parameters: -1. **Transition and Emission Probabilities**: - Should be estimated from training data or set based on domain knowledge. - -2. **Initial State Probabilities**: - Choose initial probabilities that match the expected start of sequences. - -### Summary: -**Hidden Markov Models (HMMs)** are effective for modeling sequential data with hidden and observable states. They are widely used for applications involving time-dependent or sequence data, such as speech recognition, natural language processing, and bioinformatics. By representing complex systems with hidden states and probabilistic transitions, HMMs offer powerful tools for analyzing data with underlying temporal structures. - ---- diff --git a/docs/machine-learning/HierarchialClustering.md b/docs/machine-learning/HierarchialClustering.md deleted file mode 100644 index 383da6653..000000000 --- a/docs/machine-learning/HierarchialClustering.md +++ /dev/null @@ -1,153 +0,0 @@ ---- - -id: hierarchical-clustering -title: Hierarchical Clustering Algorithm -sidebar_label: Hierarchical Clustering -description: "Hierarchical clustering is a method of grouping similar data points into clusters based on their relative distances, creating a hierarchy that can be visualized as a dendrogram." -tags: [Machine Learning, Clustering] - ---- - -# Hierarchical Clustering Algorithm - -Hierarchical clustering is a method of grouping similar data points into clusters based on their relative distances from each other. Unlike flat clustering techniques such as k-means, hierarchical clustering does not require a pre-specified number of clusters. Instead, it creates a hierarchy of clusters that can be visualized as a dendrogram, showing the hierarchical relationship between clusters. - ---- - -## Table of Contents -- [Introduction](#introduction) -- [How It Works](#how-it-works) -- [Types of Hierarchical Clustering](#types-of-hierarchical-clustering) -- [Linkage Methods](#linkage-methods) -- [Benefits and Use Cases](#benefits-and-use-cases) -- [Implementation](#implementation) - ---- - -## Introduction - -Hierarchical clustering is an unsupervised machine learning algorithm that builds a multi-level hierarchy of clusters. This hierarchical structure allows users to choose their desired number of clusters based on the level of detail they need. Hierarchical clustering is often applied in: -- **Biology:** for phylogenetic tree construction to show relationships among species. -- **Social Sciences and Psychology:** to cluster people based on survey data or behavioral patterns. -- **Marketing:** to segment customers based on their purchasing behavior. -- **Text Analysis:** to group similar documents or articles together. - -Unlike methods like k-means clustering, hierarchical clustering does not require users to specify the number of clusters in advance. Instead, clusters are determined based on distances between data points and merge or split until a single cluster or the desired cluster number is achieved. - ---- - -## How It Works - -Hierarchical clustering uses a distance metric to calculate the similarity between points or clusters. In the **agglomerative approach** (bottom-up): -1. Each data point begins as its own cluster. -2. Calculate the distance between each pair of clusters using a chosen linkage criterion. -3. Merge the two closest clusters. -4. Repeat steps 2-3 until only one cluster remains or a specified number of clusters is reached. - -In the **divisive approach** (top-down): -1. All data points start in one large cluster. -2. This cluster is split into smaller clusters recursively until each data point is its own cluster or a predefined threshold is met. - -The results can be visualized with a **dendrogram**, a tree-like diagram showing the order and level of merges or splits. - ---- - -## Types of Hierarchical Clustering - -### Agglomerative (Bottom-Up) -In the agglomerative approach, each data point is initially its own cluster, and clusters are iteratively merged based on similarity. This approach is more common due to its intuitive nature and ease of implementation. - -### Divisive (Top-Down) -The divisive approach begins with a single cluster containing all data points and recursively splits it. Although less commonly used, it can be more effective in some cases, particularly for datasets with natural group separations. - ---- - -## Linkage Methods - -The linkage method determines how the distance between clusters is calculated when they are merged or split. Common linkage methods include: - -- **Single Linkage:** The distance between two clusters is defined as the minimum distance between any two points in the two clusters. This often results in "chain-like" clusters. - -- **Complete Linkage:** The distance between two clusters is defined as the maximum distance between any two points in the two clusters, leading to compact clusters. - -- **Average Linkage:** The distance between two clusters is defined as the average distance between all pairs of points in the two clusters. - -- **Ward’s Method:** This linkage minimizes the total variance within clusters. It is often preferred when clusters are expected to be roughly spherical. - -Each linkage method produces different cluster shapes, and the choice of linkage can significantly affect the final clustering outcome. - ---- - -## Benefits and Use Cases - -### Benefits -1. **Flexibility:** Hierarchical clustering can produce a range of cluster sizes and numbers, allowing for detailed exploration of data structure. -2. **Visualization:** The dendrogram provides a clear, visual representation of how clusters relate at different levels, which is useful for understanding the data's structure. -3. **No Need to Predefine Cluster Count:** Hierarchical clustering does not require the user to specify the number of clusters in advance, which is often a requirement in methods like k-means. - -### Use Cases -- **Biological Data Analysis:** Constructing phylogenetic trees or understanding genetic similarity between species. -- **Market Segmentation:** Grouping customers by purchasing patterns or demographics. -- **Document Classification:** Organizing large collections of text data into meaningful categories. -- **Image Segmentation:** Grouping pixels or image features for applications in computer vision. - ---- - -## Implementation - -### Dependencies -Ensure you have the following libraries installed: -```bash -pip install scipy matplotlib -``` - -#### Python Implementation - -``` -import numpy as np -from scipy.cluster.hierarchy import dendrogram, linkage, fcluster -from scipy.spatial.distance import pdist -import matplotlib.pyplot as plt - -# Sample data (2D points) -data = np.array([ - [1, 2], - [2, 3], - [3, 4], - [5, 6], - [8, 8], - [7, 7], - [8, 9] -]) - -# Step 1: Compute the pairwise distance matrix -distance_matrix = pdist(data) - -# Step 2: Perform hierarchical clustering using a specified linkage method -Z = linkage(distance_matrix, method='single') # Options: 'single', 'complete', 'average', 'ward' - -# Step 3: Visualize the clustering as a dendrogram -plt.figure(figsize=(10, 7)) -dendrogram(Z, labels=[f'Point {i+1}' for i in range(len(data))]) -plt.title("Hierarchical Clustering Dendrogram") -plt.xlabel("Data Points") -plt.ylabel("Distance") -plt.show() - -# Step 4: Extract clusters by setting a threshold -threshold = 3 # Adjust threshold based on dataset and desired cluster separation -clusters = fcluster(Z, threshold, criterion='distance') - -print("Cluster Assignments:", clusters) - -# Optional: Scatter plot of clustered data -plt.figure(figsize=(8, 5)) -plt.scatter(data[:, 0], data[:, 1], c=clusters, cmap='rainbow', s=100) -plt.title("Hierarchical Clustering - Clustered Data Points") -plt.xlabel("X-axis") -plt.ylabel("Y-axis") -plt.show() -``` - - - diff --git a/docs/machine-learning/Independent Component Analysis.md b/docs/machine-learning/Independent Component Analysis.md deleted file mode 100644 index 8deb076c9..000000000 --- a/docs/machine-learning/Independent Component Analysis.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -id: independent-component-analysis -title: Independent Component Analysis -sidebar_label: Independent Component Analysis -description: "In this post, we'll explore the Independent Component Analysis (ICA) Algorithm, a powerful technique in statistical data analysis." -tags: [machine learning, algorithms, ICA, signal processing] - ---- - -### Definition: -**Independent Component Analysis (ICA)** is a computational method used for separating a multivariate signal into additive, independent components. It is widely applied in the fields of signal processing, data analysis, and feature extraction, particularly in scenarios where the observed data is a mixture of signals from different sources. - -### Characteristics: -- **Statistical Independence**: - ICA assumes that the components are statistically independent from each other, which distinguishes it from other methods like PCA (Principal Component Analysis). - -- **Non-Gaussianity**: - ICA exploits the non-Gaussian properties of the signals. The more non-Gaussian the signals are, the better the separation results. - -- **Mixing Process**: - ICA can handle linear mixtures of non-Gaussian signals, allowing for the recovery of the original signals from the mixed observations. - -### How ICA Works: -1. **Data Representation**: - The observed data is represented as a linear combination of independent source signals. - -2. **Centering**: - The data is centered by subtracting the mean to ensure that the components have a zero mean. - -3. **Whitening**: - The data is whitened (decorrelated) to remove redundancy and prepare it for ICA processing. - -4. **Independent Component Extraction**: - ICA algorithms, such as FastICA or Infomax, are used to extract the independent components from the mixed signals. This is typically done by maximizing the statistical independence of the output signals. - -### Mathematical Model: -In ICA, the observed data \( X \) can be modeled as: - -$$ -X = A.S -$$ - -Where: -- \( X \) is the observed data matrix. -- \( A \) is the mixing matrix. -- \( S ) is the matrix of independent components. - -## Time Complexity - -The time complexity of ICA can vary depending on the specific algorithm used (such as FastICA, Infomax, etc.). Generally, the complexity is: - -- **Fast ICA: $O(n^2 . m)$** - - Where \(n\) is the number of samples and \(m) is the number of signals/components. - -## Space Complexity - -The space complexity of ICA is typically: - -- **$O(n + m)$** - - Where \(n\) is the number of samples, and \(m) is the number of components. This accounts for storage of the input signals and the estimated components. - -### Loss Function -The objective of ICA is to minimize the mutual information between the extracted components, effectively maximizing their statistical independence. - -### Key Concepts: -- **Mixing Matrix (A)**: - Represents the coefficients used to combine the independent signals into the observed signals. - -- **Independent Components (S)**: - The signals that are recovered by ICA, which are statistically independent from each other. - -- **Non-Gaussianity**: - A measure of how much a distribution deviates from a Gaussian distribution, used to differentiate signals. - -### Advantages - -1. **Blind Source Separation**: ICA is effective in separating mixed signals without prior information about the source signals. -2. **Non-Gaussian Assumption**: ICA leverages the non-Gaussian nature of source signals, which can provide better separation compared to Gaussian-based methods. -3. **Robustness**: It can handle noise and other distortions in the mixed signals. -4. **Widely Applicable**: ICA is useful in various fields, including audio processing, image analysis, and biomedical signal processing. - -### Disadvantages - -1. **Assumption of Independence**: ICA assumes that the source signals are statistically independent, which may not always hold true in real-world applications. -2. **Sensitivity to Initialization**: The performance of ICA can be sensitive to the initial conditions and may converge to different solutions based on starting points. -3. **Computational Complexity**: Depending on the algorithm used, ICA can be computationally intensive, especially for large datasets. - -### Applications: -- **Signal Separation**: - Commonly used in separating audio signals (e.g., the "cocktail party problem") where multiple audio sources are mixed together. - -- **Image Processing**: - ICA can be used for facial recognition, where it helps to separate different facial features from images. - -- **Biomedical Signal Processing**: - ICA is used in analyzing EEG and fMRI data to separate brain activity signals. - -### Python Implementation: -Here is a basic implementation of Independent Component Analysis using **scikit-learn**: - -```python -import numpy as np -from sklearn.decomposition import FastICA - -# Generate sample data: two independent sources -S = np.array([[1, 2, 3, 4, 5], - [5, 4, 3, 2, 1]]) - -# Mix the data -A = np.array([[1, 1], [0.5, 2]]) # Mixing matrix -X = S.dot(A.T) # Mixed signals - -# Apply ICA -ica = FastICA(n_components=2) -S_ = ica.fit_transform(X) # Recovered signals -A_ = ica.mixing_ # Estimated mixing matrix - -# Display the results -print("Mixed Signals (X):") -print(X) -print("Recovered Independent Components (S):") -print(S) -print("Estimated Mixing Matrix (A):") -print(A) -``` - -### Summary -Independent Component Analysis is a powerful technique for separating mixed signals into their independent sources. While it has numerous advantages, it also has limitations that must be considered when applying it to real-world problems. Its broad range of applications in various fields demonstrates its versatility and effectiveness in data analysis. \ No newline at end of file diff --git a/docs/machine-learning/K-Means_clustering.md b/docs/machine-learning/K-Means_clustering.md deleted file mode 100644 index b768ef173..000000000 --- a/docs/machine-learning/K-Means_clustering.md +++ /dev/null @@ -1,133 +0,0 @@ ---- - -id: k-means-clustering-visualizations -title: K-Means Clustering Visualizations -sidebar_label: K-Means Clustering -description: "Implement the K-Means clustering algorithm to partition data into K clusters based on feature similarity. This feature will include visualizations to help users understand the clustering process." -tags: [data science, clustering, K-Means, data visualization, machine learning] - ---- - -### Definition: -**K-Means Clustering** is a popular unsupervised machine learning algorithm used to partition a dataset into K distinct clusters. It groups similar data points together based on feature similarity, minimizing the variance within each cluster and maximizing the variance between clusters. - -### Characteristics: -- **Centroid-Based**: - K-Means works by identifying K centroids, which represent the center of each cluster. - -- **Iterative Refinement**: - The algorithm iteratively updates the centroids and the cluster assignments until convergence is achieved. - -- **Distance Metric**: - Typically uses Euclidean distance to measure similarity between data points and centroids. - -### Components of K-Means: -1. **Clusters**: - The K groups into which the data is partitioned. - -2. **Centroids**: - The center points of each cluster, which are recalculated during each iteration. - -3. **Iterations**: - The process of assigning points to clusters and updating centroids continues until a stopping criterion is met. - -### Steps Involved: -1. **Initialize Centroids**: - Randomly select K data points as the initial centroids. - -2. **Assign Clusters**: - Assign each data point to the nearest centroid based on the chosen distance metric. - -3. **Update Centroids**: - Recalculate the centroids as the mean of all data points assigned to each cluster. - -4. **Repeat**: - Continue the assignment and update steps until the centroids no longer change significantly or a maximum number of iterations is reached. - -### Key Concepts: -- **Elbow Method**: - A technique used to determine the optimal number of clusters (K) by plotting the explained variance against the number of clusters. - -- **Silhouette Score**: - A metric that measures how similar a point is to its own cluster compared to other clusters, aiding in the evaluation of clustering quality. - -- **Convergence**: - The point at which the centroids stabilize and do not change significantly between iterations. - -### Advantages of K-Means: -- **Simplicity**: - Easy to implement and interpret, making it a popular choice for clustering tasks. - -- **Efficiency**: - Performs well with large datasets, especially when K is small. - -- **Scalability**: - Scales linearly with the number of data points and clusters. - -### Limitations of K-Means: -- **Choosing K**: - Requires the user to specify the number of clusters in advance, which may not always be clear. - -- **Sensitivity to Initialization**: - The final results can vary depending on the initial placement of centroids. - -- **Assumption of Spherical Clusters**: - K-Means assumes clusters are spherical and evenly sized, which may not be suitable for all data distributions. - -### Popular Applications of K-Means: -1. **Customer Segmentation**: - Grouping customers based on purchasing behavior for targeted marketing. - -2. **Image Compression**: - Reducing the number of colors in an image by clustering similar colors together. - -3. **Document Clustering**: - Organizing text documents into categories based on content similarity. - -4. **Anomaly Detection**: - Identifying outliers in data by clustering normal instances and observing deviations. - -5. **Genomic Data Analysis**: - Clustering genes or samples based on expression patterns in biological research. - -### Example of K-Means in Python: -```python -import numpy as np -import matplotlib.pyplot as plt -from sklearn.cluster import KMeans -from sklearn.datasets import make_blobs - -# Create a sample dataset -X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0) - -# Apply K-Means -kmeans = KMeans(n_clusters=4) -kmeans.fit(X) -y_kmeans = kmeans.predict(X) - -# Visualize the results -plt.figure(figsize=(8, 6)) -plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis') -centers = kmeans.cluster_centers_ -plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='X') -plt.title('K-Means Clustering Visualization') -plt.xlabel('Feature 1') -plt.ylabel('Feature 2') -plt.grid() -plt.show() -``` - -### Time and Space Complexity: -- **Time Complexity**: - The time complexity is approximately $O(n \cdot k \cdot i)$, where $n$ is the number of data points, $k$ is the number of clusters, and $i$ is the number of iterations. - -- **Space Complexity**: - The space required is $O(n)$ for storing the data points and cluster assignments. - -### Summary & Applications: -- **K-Means Clustering** is a widely used technique for exploratory data analysis, providing a simple and efficient method for partitioning data into meaningful groups. - -- **Applications**: - Effective in various domains, including marketing, image processing, and biological data analysis, enhancing the ability to discover patterns and insights in complex datasets. - ---- diff --git a/docs/machine-learning/K-NearestNeighbours.md b/docs/machine-learning/K-NearestNeighbours.md deleted file mode 100644 index 774c084b7..000000000 --- a/docs/machine-learning/K-NearestNeighbours.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -id: k-nearest-neighbors -title: k-Nearest Neighbors Algorithm -sidebar_label: k-Nearest Neighbors -description: "In this post, we'll explore the k-Nearest Neighbors (k-NN) Algorithm, one of the simplest and most intuitive algorithms in machine learning." -tags: [machine learning, algorithms, classification, regression, k-NN] ---- - -**k-Nearest Neighbors (k-NN)** is a simple and widely used supervised learning algorithm. It can be applied to both classification and regression tasks. The algorithm classifies or predicts a data point based on how closely it resembles its neighbours. k-NN does not have an explicit training phase; instead, it stores the entire dataset and makes predictions by finding the **k nearest neighbours** of a given input and using their majority class (for classification) or average value (for regression) to make predictions. - -## Characteristics: - -- **Instance-Based Learning**: - k-NN is a **lazy learner**, meaning it stores all training instances and delays computation until prediction time. - -- **Non-Parametric**: - It makes no assumptions about the underlying data distribution, making it highly flexible but sensitive to noisy data. - -- **Distance-Based**: - The algorithm relies on a **distance metric** (e.g., Euclidean distance) to measure the data points' proximity or similarity. - -## How k-NN Works: - -1. **Data Collection**: - k-NN requires a labelled dataset of examples, where each example consists of feature values and a corresponding label (for classification) or continuous target (for regression). - -2. **Prediction**: - To predict the label or value for a new, unseen data point: - - Measure the distance between the new point and all points in the training set using a distance metric. - - Select the **k nearest neighbours** based on the shortest distances. - - For classification, assign the most frequent class (majority voting) among the k neighbours. For regression, calculate the average of the k neighbours’ values. - -## Distance Metrics: -The most commonly used distance metrics in k-NN are: - -### 1. Euclidean Distance - -Euclidean Distance is the most common distance metric, defined as the straight-line distance between two points in Euclidean space. - -$$ -d(x, y) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2} -$$ - -where: -- $x_i$ and $y_i$ are the coordinates of the points in $n$-dimensional space. - -## 2. Manhattan Distance - -Manhattan Distance is the sum of the absolute differences between the coordinates of the points. It is also known as the L1 distance or taxicab distance. - -$$ -d(x, y) = \sum_{i=1}^{n} |x_i - y_i| -$$ - -where: -- $x_i$ and $y_i$ are the coordinates of the points in $n$-dimensional space. - -## 3. Minkowski Distance - -Minkowski Distance is a generalized metric that can be seen as a generalization of both the Euclidean and Manhattan distances. - -$$ -d(x, y) = \left( \sum_{i=1}^{n} |x_i - y_i|^p \right)^{\frac{1}{p}} -$$ - -where: -- \$p$ is a parameter that defines the distance metric: - - $p = 1$ gives the Manhattan distance. - - $p = 2$ gives the Euclidean distance. -- $x_i$ and $y_i$ are the coordinates of the points in $n$-dimensional space. - -## 4. Hamming Distance - -Hamming Distance is used for categorical data and is defined as the number of positions at which the corresponding elements are different. - -$$ -d(x, y) = \sum_{i=1}^{n} \delta(x_i, y_i) -$$ - -**where:** -$$ -\delta(x_i, y_i) = -\begin{cases} -1 & \text{if } x_i \neq y_i \\ -0 & \text{if } x_i = y_i -\end{cases} -$$ - -## Choosing k: -- **Small k**: - A smaller k (e.g., k=1 or k=3) makes the model sensitive to noise and can lead to **overfitting** because it considers fewer neighbors. - -- **Large k**: - A larger k provides a more generalized prediction but may lead to **underfitting** if it includes too many neighbors from different classes. - -- **Optimal k**: - The ideal value of k is often found through experimentation or by using techniques like **cross-validation**. - -### Classification with k-NN: -In classification tasks, k-NN assigns the class label based on the majority class among the k-nearest neighbours. Each neighbour votes for its class, and the most frequent class becomes the prediction. - -**Example**: -Suppose we are classifying an unknown data point based on three nearest neighbours (k=3), and the classes of these neighbours are: -- Neighbor 1: Class A -- Neighbor 2: Class A -- Neighbor 3: Class B - -Since Class A occurs more frequently, the new point is assigned to **Class A**. - -## Regression with k-NN: -In regression tasks, k-NN predicts the target value based on the **average** of the values of its k nearest neighbours. - -**Example**: -To predict the price of a house, k-NN will find k houses with similar features (square footage, number of rooms) and return the average price of those k houses as the predicted price. - -### Steps in k-NN Algorithm: -1. **Data Storage**: - k-NN stores the entire dataset of training examples. - -2. **Distance Calculation**: - For a new input data point, compute the distance between the input and every point in the training set using a chosen distance metric. - -3. **Identify Neighbors**: - Sort the distances and identify the k-nearest neighbours. - -4. **Prediction**: - - For classification, count the occurrences of each class among the k neighbours and assign the class with the majority votes. - - For regression, take the average of the k neighbours' target values. - -## Problem Statement: -Given a dataset with labelled examples (for classification) or continuous targets (for regression), the goal is to classify or predict new input data points by finding the k most similar data points in the training set and using them to infer the output. - -### Key Concepts: -- **Lazy Learning**: - k-NN is called a lazy learner because it doesn’t explicitly learn a model during training but simply stores the training dataset. - -- **Similarity**: - The similarity between data points is quantified by calculating the distance between their feature vectors. - -- **Majority Voting**: - For classification, the class of a new data point is determined by the majority class among its k nearest neighbours. - -- **Averaging**: - For regression, the predicted value is the average of the k nearest neighbour's target values. - -### Time Complexity: -- **Training Time Complexity: $O(1)$** - k-NN doesn’t require a training phase, so it takes constant time. - -- **Prediction Time Complexity: $O(n \cdot d)$** - Predicting the class or value for a new data point requires computing the distance between the new point and all n training points, each of which has d dimensions. - -### Space Complexity: -- **Space Complexity: $O(n \cdot d)$** - The algorithm stores the entire dataset, which consists of n points in d dimensions. - -### Example: -Consider a simple k-NN classification example for predicting whether a fruit is an apple or an orange based on its features (weight and Color): - -- Dataset: - ``` - | Weight (g) | Color (scale 1-10) | Fruit | - |------------|--------------------|---------| - | 150 | 8 | Apple | - | 170 | 7 | Apple | - | 130 | 6 | Orange | - | 140 | 5 | Orange | - ``` - -**Step-by-Step Execution**: - -1. **Store Dataset**: - Store the dataset as-is. - -2. **Calculate Distances**: - For a new fruit with a weight of 160g and Color value of 7, compute the distance from this point to all existing data points. - -3. **Find k Nearest Neighbors**: - If k=3, identify the 3 closest fruits to the new one based on the shortest distances. - -4. **Make Prediction**: - Count the class occurrences (Apple or Orange) among the 3 nearest neighbours and assign the new fruit to the most frequent class. - -### Python Implementation: -Here’s a simple implementation of the k-NN algorithm using **scikit-learn**: - -```python -from sklearn.neighbors import KNeighborsClassifier -import numpy as np - -# Sample data -X = np.array([[150, 8], [170, 7], [130, 6], [140, 5]]) # Features (Weight, Color) -y = np.array(['Apple', 'Apple', 'Orange', 'Orange']) # Target (Fruit) - -# Create k-NN classifier -knn = KNeighborsClassifier(n_neighbors=3) - -# Train the model -knn.fit(X, y) - -# Make a prediction for a new fruit -new_fruit = np.array([[160, 7]]) # New fruit with weight 160g and color 7 -predicted_fruit = knn.predict(new_fruit) -print(f"The predicted fruit is: {predicted_fruit[0]}") -``` - -### Summary: -The **k-Nearest Neighbors Algorithm** is a straightforward and intuitive method for both classification and regression tasks. It works by finding the k most similar examples in the training dataset and using them to predict the class or value of a new data point. While easy to implement, k-NN can be computationally expensive, especially on large datasets, as it requires calculating the distance to every training point at prediction time. diff --git a/docs/machine-learning/LinearRegression.md b/docs/machine-learning/LinearRegression.md deleted file mode 100644 index 817b8c3de..000000000 --- a/docs/machine-learning/LinearRegression.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -id: linear-regression -title: Linear Regression Algorithm -sidebar_label: Linear Regression -description: "In this post, we'll explore the Linear Regression Algorithm, one of the most basic and commonly used algorithms in machine learning." -tags: [machine learning, algorithms, linear regression, regression] - ---- - -### Definition: -**Linear Regression** is a supervised learning algorithm used for **predictive modeling** of continuous numerical variables. It establishes a linear relationship between a dependent variable (the target) and one or more independent variables (the features). The goal of linear regression is to model this relationship using a straight line (linear equation) to predict the target values based on input features. - -### Characteristics: -- **Regression Model**: - Unlike classification, linear regression predicts **continuous** values rather than categories. - -- **Linear Relationship**: - Assumes a linear relationship between the features and the target variable, where changes in feature values proportionally affect the target. - -- **Minimizing Error**: - The model minimizes the difference between the actual values and predicted values using a method called **Ordinary Least Squares** (OLS). - -### Types of Linear Regression: -1. **Simple Linear Regression**: - Used when there is one independent variable to predict the target. - Example: Predicting house price based solely on square footage. - -2. **Multiple Linear Regression**: - Used when there are two or more independent variables to predict the target. - Example: Predicting house price based on square footage, number of rooms, and age of the house. - -### Linear Equation: -In linear regression, the relationship between the target \( y \) and the input features \( X \) is modeled using the equation of a straight line: - -![image](https://github.com/user-attachments/assets/1875d7db-cf35-4ce7-a907-52c2366b2f94) - - -Where: -- \( y \) is the dependent variable (target). -- ![image](https://github.com/user-attachments/assets/e1719652-349b-456c-a1e1-e45a751bc619) - are the independent variables (features). -- ![image](https://github.com/user-attachments/assets/63ea3e53-41fc-463d-b485-72cf47d8edcf) - is the intercept![image](https://github.com/user-attachments/assets/20179b4e-8bbc-4c75-af5e-0c6697628740) -. -- ![image](https://github.com/user-attachments/assets/48f41c2a-c6fe-4c22-9ba5-e3c41ddd2588) - are the coefficients (slopes), representing the change in \( y \) for a unit change in the corresponding ![image](https://github.com/user-attachments/assets/88f0e8e8-3f9b-4194-81fb-fb2e1dabef86) - - -### How Linear Regression Works: -1. **Data Collection**: - Gather a dataset with one or more features (independent variables) and the corresponding target variable (dependent variable). - -2. **Model Training**: - The algorithm attempts to find the best-fitting line by optimizing the parameters (intercept and slopes). This is achieved using **Ordinary Least Squares** (OLS), which minimizes the sum of squared residuals (the differences between actual and predicted values). - -3. **Making Predictions**: - Once trained, the model can predict the target value \( y \) for new data points by applying the learned linear equation. - -4. **Residuals**: - The residual is the difference between the actual and predicted value: -![image](https://github.com/user-attachments/assets/883e638f-3a8f-49e8-abfa-46c5295dd923) - - The goal is to minimize these residuals. - -### Problem Statement: -Given a dataset with independent variables (features), the objective is to learn a linear regression model that can predict the target variable based on new input values. - -### Key Concepts: -- **Slope (Coefficient)**: - The slope represents how much the target variable changes when the corresponding feature increases by one unit. In multiple regression, each feature has its own slope. - -- **Intercept**: - The intercept is the predicted value of the target when all feature values are zero. - -- **Best-Fit Line**: - Linear regression aims to find the line (or hyperplane for multiple regression) that best fits the data, meaning it minimizes the overall distance between the data points and the line. - -### Loss Function: -The loss function used in linear regression is the **Mean Squared Error (MSE)**, which calculates the average of the squared differences between the actual and predicted values: - -![image](https://github.com/user-attachments/assets/8cfd9f8a-5473-4492-aeb3-d6cdcb10cf37) - -Where: -- ![image](https://github.com/user-attachments/assets/5d2a3123-9c81-4843-b8d4-1dffec0c55a0) - is the actual target value of the \(i\)-th data point. -- ![image](https://github.com/user-attachments/assets/c811a466-140c-4a76-8c2a-a0e5df20a57c) - is the predicted target value. -- \( n \) is the total number of samples. - -### Gradient Descent (Alternative Training Method): -Another approach to finding the best-fit line is **gradient descent**, which iteratively updates the model parameters by moving in the direction of the steepest decrease in the loss function. - -- **Update rule** for each parameter: -![image](https://github.com/user-attachments/assets/99d5d6c9-fb83-4e6e-b3cf-ba19b29c9127) - - Where: - - ![image](https://github.com/user-attachments/assets/1395eba3-d492-465c-879c-5f7ce406beb3) - is the learning rate (controls step size). - - ![image](https://github.com/user-attachments/assets/6493a7af-6685-47d9-b9a3-70f5cd8abc8b) - is the loss function (MSE). - - The parameters are updated in each iteration to reduce the error. - -### Time Complexity: -- **Best, Average, and Worst Case: $O(n)$** - The time complexity for training a linear regression model is linear with respect to the number of samples \( n \) and features \( p \), making it efficient for large datasets. - -### Space Complexity: -- **Space Complexity: $O(p)$** - The space complexity is proportional to the number of features \( p \), as the model stores one coefficient per feature, plus the intercept. - -### Example: -Consider a dataset for predicting the price of a house based on **square footage**: - -- Dataset: - ``` - | Square Footage | Price ($) | - |----------------|--------------| - | 1500 | 200,000 | - | 1700 | 230,000 | - | 1800 | 250,000 | - | 1900 | 270,000 | - ``` - -Step-by-Step Execution: - -1. **Fit the model**: - Linear regression will learn the relationship between **square footage** (independent variable) and **price** (dependent variable). - -2. **Equation**: - The model will output an equation like: - ![image](https://github.com/user-attachments/assets/8061012e-d2b6-46be-b51b-a1889207eac8) - - -3. **Predict price**: - For a new house with 2000 square feet, the model will predict the price using the equation. - -### Python Implementation: -Here is a basic implementation of Linear Regression in Python using **scikit-learn**: - -```python -from sklearn.linear_model import LinearRegression -import numpy as np - -# Sample data -X = np.array([[1500], [1700], [1800], [1900]]) # Features (Square Footage) -y = np.array([200000, 230000, 250000, 270000]) # Target (Price) - -# Create linear regression model -model = LinearRegression() - -# Train the model -model.fit(X, y) - -# Make predictions -predicted_price = model.predict([[2000]]) # Predict price for 2000 square footage -print(f"Predicted price: ${predicted_price[0]:,.2f}") - -# Display the model's coefficients -print(f"Intercept: {model.intercept_}") -print(f"Coefficient: {model.coef_[0]}") -``` - -### Summary: -The **Linear Regression Algorithm** is one of the most fundamental techniques for predicting continuous outcomes. Its simplicity and interpretability make it a powerful tool for many real-world applications, particularly in finance, economics, and engineering. However, it assumes a linear relationship between variables and may not work well for datasets with non-linear patterns. - ---- diff --git a/docs/machine-learning/LogisticRegression.md b/docs/machine-learning/LogisticRegression.md deleted file mode 100644 index 5bdd713d7..000000000 --- a/docs/machine-learning/LogisticRegression.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: logistic-regression -title: Logistic Regression Algorithm -sidebar_label: Logistic Regression -description: "In this post, we'll explore the Logistic Regression Algorithm, a widely used classification model in machine learning." -tags: [machine learning, algorithms, logistic regression, classification] - ---- - -### Definition: -**Logistic Regression** is a supervised learning algorithm primarily used for **binary classification** tasks (where the target variable has two categories). It models the relationship between the independent variables (features) and the probability of a particular outcome (class). Unlike linear regression, logistic regression predicts the **probability** that a given input belongs to a specific class using the **logistic function** (also known as the sigmoid function). - -### Characteristics: -- **Classification Model**: - Although it contains "regression" in its name, logistic regression is a **classification** algorithm used to assign observations to discrete categories. - -- **Probabilistic Output**: - The model outputs a probability value between 0 and 1, which is then thresholded to classify data points. - -- **Linear Decision Boundary**: - It assumes a linear relationship between the features and the log-odds of the outcome. - -### Types of Logistic Regression: -1. **Binary Logistic Regression**: - Used when the target variable has two classes (e.g., yes/no, spam/ham). - -2. **Multinomial Logistic Regression**: - Used when the target variable has more than two classes but they are not ordinal (e.g., types of fruits). - -3. **Ordinal Logistic Regression**: - Used when the target variable has more than two categories that follow a natural order (e.g., ranking systems like low/medium/high). - -### Logistic Function: -The logistic function, also called the **sigmoid function**, is the mathematical function used to map any real-valued number into the [0, 1] range. It’s expressed as: - -![image](https://github.com/user-attachments/assets/acf5be45-0958-4690-82a7-1c625da800c4) - - -Where: -- \( z \) is a linear combination of input features ![image](https://github.com/user-attachments/assets/bbcb200b-70f8-4382-a81a-88d8745f298a) - -- ![image](https://github.com/user-attachments/assets/4aa2ba43-52c0-4335-a353-23814ac64404) - is the predicted probability that the given input belongs to class 1 ![image](https://github.com/user-attachments/assets/b4b0c5fb-c213-4e9c-959e-e7c0ba2dfa8a) - - -### How Logistic Regression Works: -1. **Linear Model**: - The model starts by calculating a weighted sum of the input features plus a bias term. This is similar to linear regression: - - ![image](https://github.com/user-attachments/assets/565ec3e9-903c-4899-a3d8-71769063d786) - - -2. **Sigmoid Transformation**: - The linear output \( z \) is passed through the sigmoid function to produce a probability: - - ![image](https://github.com/user-attachments/assets/f14f0028-0e70-4695-beb9-223e02a6d210) - - where ![image](https://github.com/user-attachments/assets/7b28ac13-1992-40ec-80e6-944db5890bbd) - is the predicted probability that the data point belongs to the positive class (class 1). - -3. **Classification**: - A threshold (commonly 0.5) is applied to the predicted probability to determine the class label: - -![image](https://github.com/user-attachments/assets/d58eb745-7d6d-4ca4-b58d-6acb4f470a22) - - -4. **Model Training**: - Logistic regression is trained by **maximum likelihood estimation** (MLE), which optimizes the model parameters (weights) to maximize the likelihood of correctly classifying the data. - -### Problem Statement: -Given a dataset with features and a binary target variable, the goal is to learn a logistic regression model that can **classify** new data points into one of two categories by predicting the probability of each category. - -### Key Concepts: -- **Odds**: - The odds of an event is the ratio of the probability of the event occurring to the probability of it not occurring: - -![image](https://github.com/user-attachments/assets/d40a0cd4-d56a-49af-8785-0effc31b0f47) - - -- **Log-Odds (Logit)**: - Logistic regression models the log-odds of the target variable as a linear function of the input features: - -![image](https://github.com/user-attachments/assets/88fe176a-2cee-4d85-96b7-93cd0577c02e) - - -### Loss Function: -The **loss function** for logistic regression is the **log loss** (also known as the negative log-likelihood or binary cross-entropy). It’s given by: - -![image](https://github.com/user-attachments/assets/5d3f5412-545d-4eff-82cd-0bdde328c843) - - -Where: -- ![image](https://github.com/user-attachments/assets/1f48df37-fe70-4430-96fd-2e8b2aa08703) - is the actual label of the \(i\)-th data point -- ![image](https://github.com/user-attachments/assets/49b0688a-3005-4199-989a-a1cf859747a1) - is the predicted probability of class 1 for the \(i\)-th data point -- \( n \) is the total number of samples - -### Time Complexity: -- **Best, Average, and Worst Case: $O(n)$** - The time complexity for training logistic regression is linear with respect to the number of samples \( n \) and features \( p \), making it efficient for large datasets. - -### Space Complexity: -- **Space Complexity: $O(p)$** - The space complexity depends on the number of features, as the model needs to store a weight for each feature plus a bias term. - -### Example: -Consider a dataset for predicting whether a user will click on an ad based on their **age** and **daily time spent on site**: - -- Dataset: - ``` - | Age | Daily Time Spent | Clicked (Yes/No) | - |-------|------------------|------------------| - | 25 | 65.5 | Yes | - | 45 | 80.3 | No | - | 35 | 45.2 | Yes | - | 22 | 50.1 | No | - ``` - -Step-by-Step Execution: - -1. **Fit the model**: - Logistic regression will learn the relationship between features (Age, Daily Time Spent) and the target (Clicked or not). - -2. **Sigmoid transformation**: - The linear combination of the features is transformed into a probability using the sigmoid function. - -3. **Predict class**: - A threshold (e.g., 0.5) is applied to classify whether the user will click the ad (Yes or No). - -### Python Implementation: -Here is a basic implementation of Logistic Regression in Python using **scikit-learn**: - -```python -from sklearn.datasets import load_iris -from sklearn.linear_model import LogisticRegression -import numpy as np - -# Load dataset -iris = load_iris() -X, y = iris.data, (iris.target == 2).astype(np.int) # Convert to binary classification (target=2 vs rest) - -# Create logistic regression model -clf = LogisticRegression() - -# Train model -clf.fit(X, y) - -# Make predictions -predictions = clf.predict(X) - -# Display the model's coefficients -print(f"Model coefficients: {clf.coef_}") -``` - -### Summary: -The **Logistic Regression Algorithm** is a simple yet powerful method for binary classification tasks. It is widely used in scenarios where interpretability is important, as the model outputs probabilities for each class. Logistic regression is suitable for linearly separable datasets, but it may struggle with non-linear patterns. **Regularization techniques** like L1 and L2 can help prevent overfitting in logistic regression. - ---- diff --git a/docs/machine-learning/Long_Short_Term_Memory.md b/docs/machine-learning/Long_Short_Term_Memory.md deleted file mode 100644 index e08a3d7df..000000000 --- a/docs/machine-learning/Long_Short_Term_Memory.md +++ /dev/null @@ -1,162 +0,0 @@ ---- - -id: long-short-term-memory -title: Long Short-Term Memory (LSTM) -sidebar_label: LSTM -description: "This post delves into Long Short-Term Memory (LSTM), a type of recurrent neural network designed to overcome the vanishing gradient problem, enabling better learning of long-term dependencies in sequential data." -tags: [machine learning, deep learning, lstm, rnn, neural networks, time series, NLP] - ---- - -### Definition: -**Long Short-Term Memory (LSTM)** is a special type of Recurrent Neural Network (RNN) architecture designed to learn long-term dependencies. It addresses the vanishing gradient problem inherent in vanilla RNNs by introducing gates that regulate the flow of information through the network. LSTMs are particularly effective for tasks involving sequential data, such as time-series prediction, language modeling, and speech recognition. - -### Characteristics: -- **Gated Architecture**: - LSTMs utilize gates (input, forget, output) to control which information is remembered, forgotten, or passed on to the next time step. This allows them to maintain relevant information over long sequences. - -- **Memory Cell**: - The key feature of an LSTM is the memory cell, which retains information over arbitrary time intervals. The network can decide whether to keep or discard information at each time step. - -- **Efficient Learning of Long-term Dependencies**: - Unlike vanilla RNNs, which struggle to retain long-term dependencies due to the vanishing gradient problem, LSTMs are explicitly designed to remember information over longer time periods. - -### Components of LSTM: -1. **Cell State**: - The cell state is the LSTM’s "memory," which flows through the network with only minor linear interactions. It retains information over long sequences. - -2. **Forget Gate**: - The forget gate decides what information from the cell state should be discarded. It uses a sigmoid function to output values between 0 and 1, where 0 means "completely forget" and 1 means "completely retain." - -3. **Input Gate**: - The input gate controls which new information should be stored in the cell state. It consists of a sigmoid layer that decides which values to update and a tanh layer that creates new candidate values for updating the cell state. - -4. **Output Gate**: - The output gate determines the output of the LSTM at each time step. It uses the updated cell state to compute the next hidden state, which is passed on to the next time step. - -5. **Hidden State**: - The hidden state is the output of the LSTM for the current time step. It’s influenced by the output gate and the updated cell state. - -### LSTM Architecture: -1. **Input Layer**: - Sequential data (e.g., words in a sentence, time-series data) is provided as input to the LSTM one time step at a time. - -2. **LSTM Cell**: - Each time step is processed by an LSTM cell, which updates the hidden state and cell state based on the current input, the previous hidden state, and the previous cell state. - -3. **Output Layer**: - The output can be generated at each time step (e.g., language translation or generation tasks) or after processing the entire sequence (e.g., sentiment analysis or time-series prediction). - -### Types of LSTMs: -1. **Vanilla LSTM**: - The most basic form of LSTM, where information flows sequentially through the input, forget, and output gates for each time step. - -2. **Bidirectional LSTM (BiLSTM)**: - This architecture consists of two LSTM layers that process the input in both forward and backward directions. It is especially useful for tasks where future context is as important as past context. - -3. **Stacked LSTM**: - Multiple LSTM layers are stacked on top of each other, enabling the network to learn more complex and hierarchical patterns in the data. - -4. **Peephole LSTM**: - In Peephole LSTMs, the gates also receive input from the cell state, allowing them to "peek" into the cell state during updates. - -### Problem Statement: -Given sequential data such as time-series, text, or audio, the goal of an LSTM is to make accurate predictions by effectively capturing long-term dependencies while mitigating issues like vanishing gradients. - -### Key Concepts: -- **Memory Cell**: - LSTMs maintain a memory cell that persists over time and can store relevant information while discarding irrelevant information through its gates. - -- **Vanishing Gradient Problem**: - LSTMs help mitigate the vanishing gradient problem in vanilla RNNs, which makes them better suited for learning long-term dependencies. - -- **Gates**: - LSTMs employ three main gates (forget, input, and output gates) to regulate the flow of information, ensuring that important information is remembered and unimportant information is forgotten. - -- **Backpropagation Through Time (BPTT)**: - LSTMs use BPTT to update weights by propagating gradients back through the entire sequence. Due to the gating mechanism, LSTMs avoid the vanishing gradient problem better than traditional RNNs. - -### Steps Involved: -1. **Input Data**: - Sequential data is fed into the LSTM one time step at a time. - -2. **Gate Calculations**: - The forget, input, and output gates compute which information to retain, update, and output at each time step. - -3. **Cell State Update**: - The cell state is updated using the information from the forget and input gates, deciding which information to keep or discard. - -4. **Hidden State Calculation**: - The output gate computes the hidden state, which is used as the output for the current time step and passed to the next LSTM cell. - -5. **Final Output**: - After processing the entire sequence, the final hidden state can be used for tasks like sequence classification, or intermediate outputs can be used for tasks like sequence generation. - -### Split Criteria: -LSTMs process data in sequential order, using the previous hidden state and cell state at each time step to inform the current step’s calculations. They are particularly useful for tasks where maintaining information over long sequences is critical. - -### Time Complexity: -- **Training Complexity**: - The time complexity of training an LSTM is proportional to the sequence length $T$, the size of the input $n$, and the number of hidden units $h$, and is approximately $O(T \cdot n \cdot h^2)$. - -- **Prediction Complexity**: - For inference, the complexity depends on the sequence length, as LSTMs must process each time step sequentially. - -### Space Complexity: -- **Space Complexity**: - LSTMs need memory proportional to the sequence length $T$ and the number of hidden units $h$, resulting in a space complexity of $O(T \cdot h)$. - -### Example: -Consider an example where we use an LSTM to perform sentiment analysis on text data: - -```python -import numpy as np -import tensorflow as tf -from tensorflow.keras import layers, models - -# Sample input data (e.g., text sequence for sentiment analysis) -text = "This movie was fantastic" -char_to_idx = {ch: idx for idx, ch in enumerate(set(text))} -idx_to_char = {idx: ch for ch, idx in char_to_idx.items()} -input_seq = [char_to_idx[ch] for ch in text] - -# Prepare input data -input_seq = np.array(input_seq).reshape(1, -1) - -# LSTM Model -model = models.Sequential() - -# LSTM Layer -model.add(layers.LSTM(50, input_shape=(None, len(char_to_idx)))) -model.add(layers.Dense(1, activation='sigmoid')) # Binary sentiment classification - -# Compile model -model.compile(optimizer='adam', loss='binary_crossentropy') - -# Train the model (for illustration, usually requires more training) -model.fit(input_seq, np.array([1]), epochs=100) # Example of positive sentiment - -# Predict sentiment -prediction = model.predict(input_seq) -predicted_sentiment = "Positive" if prediction > 0.5 else "Negative" -print(f"Predicted Sentiment: {predicted_sentiment}") -``` - -### Applications of LSTMs: -- **Natural Language Processing (NLP)**: - LSTMs are widely used in NLP tasks such as text generation, language translation, and sentiment analysis due to their ability to capture long-term dependencies in text. - -- **Time-series Forecasting**: - LSTMs can predict future values in time-series data, making them valuable for financial forecasting, stock price prediction, and weather forecasting. - -- **Speech Recognition**: - LSTMs process sequential audio data to recognize speech patterns and convert them into text. - -- **Music Generation**: - LSTMs can generate new music by learning patterns from existing music sequences. - -- **Video Analysis**: - LSTMs can analyze video sequences by processing frames in order and learning patterns over time. - -### Conclusion: -Long Short-Term Memory (LSTM) networks are a powerful type of recurrent neural network that can capture long-term dependencies in sequential data. With their gated architecture, LSTMs overcome the vanishing diff --git a/docs/machine-learning/PC_Visualizations.md b/docs/machine-learning/PC_Visualizations.md deleted file mode 100644 index 24bb41ac4..000000000 --- a/docs/machine-learning/PC_Visualizations.md +++ /dev/null @@ -1,145 +0,0 @@ ---- - -id: pca-visualizations -title: PCA Visualizations -sidebar_label: PCA -description: "Implement Principal Component Analysis (PCA) to reduce the dimensionality of high-dimensional data while preserving its essential features. Visualize the transformed data to gain insights into underlying patterns." -tags: [data science, dimensionality reduction, PCA, data visualization, machine learning] - ---- - -### Definition: -**Principal Component Analysis (PCA)** is a statistical technique used for dimensionality reduction. It transforms high-dimensional data into a lower-dimensional space, capturing the most variance in the data while minimizing loss of information. PCA helps simplify complex datasets, making them easier to visualize and analyze. - -### Characteristics: -- **Dimensionality Reduction**: - PCA reduces the number of variables (dimensions) in a dataset while retaining the essential patterns and structures. - -- **Eigenvalues and Eigenvectors**: - PCA identifies principal components by calculating the eigenvalues and eigenvectors of the covariance matrix of the data. - -- **Variance Explained**: - Each principal component captures a portion of the total variance, allowing users to understand how much information is retained. - -### Components of PCA: -1. **Data Standardization**: - Standardize the dataset to have a mean of zero and a standard deviation of one to ensure each feature contributes equally. - -2. **Covariance Matrix**: - Compute the covariance matrix to examine the relationships between different features in the dataset. - -3. **Eigen Decomposition**: - Calculate the eigenvalues and eigenvectors of the covariance matrix to determine the principal components. - -4. **Projection**: - Transform the original data onto the new principal component axes, reducing its dimensionality. - -### Steps Involved: -1. **Standardize the Data**: - Center and scale the data to prepare it for PCA. - -2. **Compute the Covariance Matrix**: - Analyze the relationships between features by calculating the covariance matrix. - -3. **Calculate Eigenvalues and Eigenvectors**: - Find the eigenvalues and eigenvectors to determine the direction of the principal components. - -4. **Sort Eigenvalues**: - Sort the eigenvalues and their corresponding eigenvectors in descending order to identify the most significant components. - -5. **Select Principal Components**: - Choose the top k eigenvectors (principal components) based on the desired level of variance explained. - -6. **Project the Data**: - Transform the original data onto the selected principal components to achieve dimensionality reduction. - -### Key Concepts: -- **Variance Explained Ratio**: - Indicates how much of the total variance is captured by each principal component, helping determine how many components to retain. - -- **Scree Plot**: - A graphical representation of the eigenvalues that helps visualize the importance of each principal component. - -- **Biplot**: - A visualization that combines the principal component scores and the loading vectors, providing insights into the relationships between variables. - -### Advantages of PCA: -- **Reduces Complexity**: - Simplifies high-dimensional datasets, making them easier to visualize and interpret. - -- **Improves Model Performance**: - By reducing noise and redundancy, PCA can enhance the performance of machine learning models. - -- **Facilitates Visualization**: - Enables effective visualization of complex datasets by projecting them into two or three dimensions. - -### Limitations of PCA: -- **Linear Assumption**: - PCA assumes linear relationships among features, which may not hold in all datasets. - -- **Loss of Information**: - Some information is inevitably lost during dimensionality reduction, potentially impacting analysis. - -- **Interpretability**: - The transformed components may not have clear meanings, making it difficult to interpret results in context. - -### Popular Applications of PCA: -1. **Data Visualization**: - Reduce dimensions for visual exploration of high-dimensional data. - -2. **Image Compression**: - Compress images by retaining only the most significant principal components. - -3. **Genomics**: - Analyze genetic data to identify patterns and relationships among genes. - -4. **Market Research**: - Explore customer data to uncover underlying factors influencing purchasing behavior. - -5. **Anomaly Detection**: - Detect outliers in high-dimensional datasets by examining the variance captured by principal components. - -### Example of PCA in Python: -```python -import numpy as np -import pandas as pd -from sklearn.decomposition import PCA -import matplotlib.pyplot as plt - -# Sample dataset -data = pd.DataFrame(np.random.rand(100, 5), columns=['A', 'B', 'C', 'D', 'E']) - -# Standardize the data -data_standardized = (data - data.mean()) / data.std() - -# Apply PCA -pca = PCA(n_components=2) # Reduce to 2 dimensions -pca_result = pca.fit_transform(data_standardized) - -# Create a DataFrame for the PCA results -pca_df = pd.DataFrame(data=pca_result, columns=['Principal Component 1', 'Principal Component 2']) - -# Visualize the PCA results -plt.figure(figsize=(8, 6)) -plt.scatter(pca_df['Principal Component 1'], pca_df['Principal Component 2'], alpha=0.7) -plt.title('PCA Result') -plt.xlabel('Principal Component 1') -plt.ylabel('Principal Component 2') -plt.grid() -plt.show() -``` - -### Time and Space Complexity: -- **Time Complexity**: - The dominant factor is the eigen decomposition, which typically runs in $O(n^3)$, where $n$ is the number of features. - -- **Space Complexity**: - The space required is $O(n^2)$ for storing the covariance matrix and eigenvectors. - -### Summary & Applications: -- **PCA** is a powerful technique for simplifying data analysis and visualization by reducing dimensionality while retaining essential information. - -- **Applications**: - Widely used in exploratory data analysis, image processing, and machine learning to enhance interpretability and model performance. - ---- diff --git a/docs/machine-learning/Recurrent_Neural_Network.md b/docs/machine-learning/Recurrent_Neural_Network.md deleted file mode 100644 index 46faaea07..000000000 --- a/docs/machine-learning/Recurrent_Neural_Network.md +++ /dev/null @@ -1,174 +0,0 @@ ---- - -id: recurrent-neural-networks -title: Recurrent Neural Networks (RNN) -sidebar_label: RNNs -description: "This post explores Recurrent Neural Networks (RNN), a class of neural networks designed to handle sequential data and time-series information, commonly used for tasks involving natural language processing, speech recognition, and more." -tags: [machine learning, deep learning, rnn, neural networks, time series, NLP] - ---- - -### Definition: -**Recurrent Neural Networks (RNNs)** are a class of artificial neural networks designed for modeling sequential data by introducing loops that allow information to persist across time steps. They are widely used for tasks like time-series forecasting, natural language processing (NLP), and speech recognition because of their ability to process and maintain information from previous inputs. - -### Characteristics: -- **Sequential Data Handling**: - RNNs excel at learning from and making predictions based on sequential data, where the order and context of the input are crucial. - -- **Shared Weights**: - Unlike traditional neural networks, RNNs share the same parameters (weights) across different time steps, which allows them to process variable-length sequences without increasing the number of parameters. - -- **Memory**: - RNNs have internal memory due to their recurrent connections, which allows them to store information about previous inputs and use it to influence future predictions. - -### Components of RNN: -1. **Hidden State**: - RNNs maintain a hidden state that captures information from previous time steps. At each time step, the hidden state is updated based on the current input and the previous hidden state. - -2. **Recurrent Connection**: - The recurrent connection is the key feature of RNNs. It enables information to flow from one time step to the next, creating a loop in the network's structure. - -3. **Activation Function**: - The hidden state is passed through an activation function, typically **tanh** or **ReLU**, to introduce non-linearity into the network and allow it to model complex patterns in sequential data. - -4. **Output Layer**: - The output at each time step is computed based on the current hidden state and can be used for predictions, classification, or further processing. - -### RNN Architecture: -1. **Input Layer**: - Sequential data, such as a series of time steps (e.g., words in a sentence or stock prices over time), is provided as input to the RNN. - -2. **Recurrent Hidden Layer(s)**: - The hidden layer(s) process the input data one time step at a time, updating the hidden state based on both the current input and the previous hidden state. - -3. **Output Layer**: - Depending on the task, RNNs can produce output at each time step (e.g., for translation or generation tasks) or at the end of the sequence (e.g., for sentiment analysis or time-series prediction). - -### Types of RNNs: -1. **Vanilla RNN**: - The simplest form of RNN, where the hidden state is updated using the same weights at each time step. However, vanilla RNNs struggle with learning long-term dependencies due to the vanishing gradient problem. - -2. **Long Short-Term Memory (LSTM)**: - LSTMs are a more advanced form of RNN designed to overcome the vanishing gradient problem. They use gates (input, forget, output) to control the flow of information and can learn long-term dependencies. - -3. **Gated Recurrent Unit (GRU)**: - GRUs are a simplified version of LSTMs that combine the input and forget gates into a single update gate. GRUs are computationally cheaper while still addressing the vanishing gradient problem. - -4. **Bidirectional RNN (BiRNN)**: - In a bidirectional RNN, two RNNs are run in parallel: one processes the sequence from left to right, and the other processes it from right to left. This architecture is useful for tasks where future context is as important as past context. - -### Problem Statement: -Given a sequential dataset (e.g., a sentence for language modeling or a time-series for prediction), the goal of an RNN is to predict the next element in the sequence or classify the entire sequence based on its content. - -### Key Concepts: -- **Sequential Processing**: - RNNs process input sequences step by step, maintaining a hidden state that is updated at each step based on both the current input and previous hidden state. - -- **Vanishing Gradient Problem**: - In vanilla RNNs, gradients may become very small (vanish) during backpropagation through time (BPTT), making it difficult to learn long-term dependencies. This is alleviated by architectures like LSTM and GRU. - -- **Backpropagation Through Time (BPTT)**: - RNNs use BPTT to train the network, where gradients are propagated backward through each time step in the sequence. - -- **Long-term Dependencies**: - RNNs struggle with learning long-term dependencies (i.e., when the gap between relevant inputs and outputs is large), but LSTMs and GRUs address this challenge by incorporating gating mechanisms. - -### Steps Involved: -1. **Input Data**: - Sequential data, such as a series of time steps (e.g., stock prices, words in a sentence), is fed into the RNN one time step at a time. - -2. **Hidden State Update**: - At each time step, the hidden state is updated based on the current input and the previous hidden state, capturing information from earlier time steps. - -3. **Output Generation**: - The output can be generated at each time step or at the end of the sequence, depending on the task. In tasks like language modeling, the RNN predicts the next word at each step. - -4. **Loss Calculation and Backpropagation**: - The loss is calculated based on the predicted output and the true target. Backpropagation through time (BPTT) is used to update the weights. - -5. **Final Prediction**: - The RNN produces a final prediction, which could be a classification of the entire sequence (e.g., sentiment analysis) or a prediction for the next time step in the sequence (e.g., time-series forecasting). - -### Split Criteria: -RNNs handle sequential data where each input depends on the previous elements. The network processes the data one time step at a time, updating the hidden state with each new input. - -### Time Complexity: -- **Training Complexity**: - The time complexity of training an RNN depends on the number of time steps $T$, the size of the input $n$, and the number of hidden units $h$. It is roughly $O(T \cdot n \cdot h^2)$. - -- **Prediction Complexity**: - For inference, the time complexity is also dependent on the sequence length, as each time step requires an update to the hidden state. - -### Space Complexity: -- **Space Complexity**: - The space complexity depends on the number of hidden units and time steps. Since RNNs store the hidden state at each time step, they require memory proportional to $O(T \cdot h)$, where $T$ is the number of time steps and $h$ is the size of the hidden state. - -### Example: -Consider an example where we use an RNN to perform text generation: - -```python -import numpy as np -import tensorflow as tf -from tensorflow.keras import layers, models - -# Sample training data (e.g., text sequence) -text = "hello world" -char_to_idx = {ch: idx for idx, ch in enumerate(set(text))} -idx_to_char = {idx: ch for ch, idx in char_to_idx.items()} -input_seq = [char_to_idx[ch] for ch in text] - -# Prepare input data -input_seq = np.array(input_seq).reshape(1, -1) - -# RNN Model -model = models.Sequential() - -# Recurrent Layer (Simple RNN) -model.add(layers.SimpleRNN(50, input_shape=(None, len(char_to_idx)), return_sequences=True)) -model.add(layers.Dense(len(char_to_idx), activation='softmax')) - -# Compile model -model.compile(optimizer='adam', loss='categorical_crossentropy') - -# Train the model (for illustration, usually longer training is needed) -model.fit(input_seq, input_seq, epochs=100) - -# Predict the next character -prediction = model.predict(input_seq) -predicted_char = idx_to_char[np.argmax(prediction[0])] -print(f"Predicted next character: {predicted_char}") -``` - -### Applications of RNNs: -- **Natural Language Processing (NLP)**: - RNNs are widely used in tasks like machine translation, text generation, sentiment analysis, and speech recognition due to their ability to model sequential dependencies in text and speech data. - -- **Time-series Forecasting**: - RNNs can predict future values in time-series data by learning patterns from historical data, making them useful in finance, weather forecasting, and more. - -- **Speech Recognition**: - RNNs are used to transcribe speech to text by processing sequential audio data and predicting the corresponding textual output. - -- **Sequence Generation**: - RNNs can generate new sequences based on learned patterns, such as generating text, music, or even video frames. - -- **Handwriting Recognition**: - RNNs can recognize handwritten text by processing sequential strokes or pixels in an image. - -- **Video Analysis**: - RNNs are applied to video data to analyze sequences of frames, often combined with convolutional layers for extracting spatial features from each frame. - -### Advantages: -- Can process sequences of varying lengths. -- Maintain information from previous inputs, making them well-suited for sequential tasks. -- LSTMs and GRUs help overcome the vanishing gradient problem, making RNNs capable of learning long-term dependencies. - -### Disadvantages: -- Vanilla RNNs struggle with long-term dependencies due to the vanishing gradient problem. -- Training can be slow and challenging, especially for very long sequences. -- Computationally expensive compared to feedforward neural networks. - -### Conclusion: -Recurrent Neural Networks (RNNs) are powerful tools for modeling sequential data. By maintaining a hidden state that captures information from previous time steps, RNNs can learn patterns in time-series data, text, and more. Advanced variants like LSTMs and GRUs address the shortcomings of vanilla RNNs, making them more effective for tasks requiring long-term memory. - ---- diff --git a/docs/machine-learning/Reinforcement_Learning.md b/docs/machine-learning/Reinforcement_Learning.md deleted file mode 100644 index 39231e5b5..000000000 --- a/docs/machine-learning/Reinforcement_Learning.md +++ /dev/null @@ -1,150 +0,0 @@ ---- - -id: reinforcement-learning -title: Reinforcement Learning -sidebar_label: Reinforcement Learning -description: "In this post, we'll explore Reinforcement Learning, a type of machine learning used for decision-making and optimizing actions." -tags: [machine learning, reinforcement learning, decision-making, AI] - ---- - -### Definition: -**Reinforcement Learning (RL)** is a type of machine learning where an **agent** learns to make decisions by interacting with an **environment** to achieve a specific goal. The agent takes actions, receives feedback in the form of rewards or penalties, and adjusts its behavior to maximize cumulative rewards over time. It is commonly used for tasks involving **sequential decision-making**. - -### Characteristics: -- **Trial-and-Error Learning**: - The agent learns through a process of trial and error, exploring different strategies to maximize rewards. - -- **Exploration vs. Exploitation**: - The agent balances between exploring new actions (exploration) and using known actions that give high rewards (exploitation). - -- **Delayed Rewards**: - In RL, rewards might not be immediate. The agent needs to consider future rewards when making decisions. - -### Key Components: -1. **Agent**: - The decision-maker in the RL system. The agent interacts with the environment, learns from it, and takes actions. - -2. **Environment**: - The external system the agent interacts with. It provides feedback to the agent in the form of rewards or penalties. - -3. **State**: - A representation of the current situation or environment that the agent observes. - -4. **Action**: - The set of all possible moves the agent can take to interact with the environment. - -5. **Reward**: - The feedback the agent receives from the environment after taking an action. The goal is to maximize cumulative rewards. - -6. **Policy**: - A strategy or mapping from states to actions that the agent follows to decide its next action. - -7. **Value Function**: - A function that estimates the expected long-term reward for a given state or state-action pair. - -### Reinforcement Learning Process: -1. **Observation**: - The agent observes the current state of the environment. - -2. **Action Selection**: - Based on the observation, the agent selects an action using its policy. - -3. **Interaction with Environment**: - The action affects the environment, transitioning it to a new state. - -4. **Reward**: - The agent receives a reward (positive or negative) based on the action taken. - -5. **Learning**: - The agent updates its knowledge (policy or value function) to improve future decisions. - -### Types of Reinforcement Learning: -1. **Model-Free RL**: - The agent learns directly from interactions with the environment without having any prior model of the environment. Examples include Q-learning and SARSA. - -2. **Model-Based RL**: - The agent builds a model of the environment and uses it to plan actions. It tries to predict future states and rewards. - -3. **On-Policy vs. Off-Policy RL**: - - **On-Policy**: The agent learns from the actions taken by the current policy (e.g., SARSA). - - **Off-Policy**: The agent learns from actions taken by a different policy (e.g., Q-learning). - -### Exploration vs. Exploitation: -One of the key challenges in RL is balancing between: -- **Exploration**: Trying out new actions to discover their potential rewards. -- **Exploitation**: Choosing actions that are known to yield high rewards based on the agent’s current knowledge. - -### Q-Learning: -**Q-Learning** is a popular model-free RL algorithm where the agent learns a **Q-value function** that represents the expected reward for taking an action in a given state. The update rule for Q-learning is: - -![image](https://github.com/user-attachments/assets/44d29298-4002-4fe2-8b87-a53e38f03c1a) - - -Where: -- $Q(s, a)$ is the Q-value of taking action $( a )$ in state $(s)$ -- $( r )$ is the reward received after taking action $( a )$ -- $α$ is the learning rate -- $γ$ is the discount factor (the weight of future rewards) -- ![image](https://github.com/user-attachments/assets/36e1cfa7-aa4f-457e-8b7f-ba485f205cc5) - is the maximum Q-value for the next state $s'$ - -### Policy Gradient Methods: -In **policy gradient** methods, the policy is parameterized, and the goal is to directly optimize the policy parameters. These methods are well-suited for high-dimensional action spaces and continuous control tasks. - -### Reward Signal: -The **reward signal** is crucial in RL. The agent's goal is to maximize the **cumulative reward** over time. It must learn which actions lead to higher rewards, even if the rewards are delayed. - -### Discount Factor: -The **discount factor** $γ$ controls the importance of future rewards. A discount factor close to 1 makes the agent prioritize long-term rewards, while a lower value emphasizes immediate rewards. - -### Example: -Consider a simple game where an agent has to move through a maze to reach the goal. The agent receives positive rewards for moving closer to the goal and negative rewards for hitting walls. - -Steps: -1. **State**: The current position of the agent in the maze. -2. **Action**: Move up, down, left, or right. -3. **Reward**: +10 for reaching the goal, -1 for hitting a wall. -4. **Learning**: The agent learns which actions lead it closer to the goal based on rewards. - -### Python Implementation: -Here is a basic implementation of Q-Learning for solving a simple gridworld problem: - -```python -import numpy as np - -# Define environment -grid_size = 4 -Q = np.zeros((grid_size, grid_size, 4)) # Q-table: (state, action) - -# Hyperparameters -alpha = 0.1 # Learning rate -gamma = 0.9 # Discount factor -epsilon = 0.1 # Exploration rate - -# Define actions (0: up, 1: right, 2: down, 3: left) -actions = [(0, 1), (1, 0), (0, -1), (-1, 0)] - -def choose_action(state): - if np.random.uniform(0, 1) < epsilon: - return np.random.choice(4) # Explore - else: - return np.argmax(Q[state[0], state[1]]) # Exploit - -# Example loop for training the agent -for episode in range(1000): - state = (0, 0) # Starting state - while state != (3, 3): # Goal state - action = choose_action(state) - next_state = (state[0] + actions[action][0], state[1] + actions[action][1]) - reward = -1 if next_state == (1, 1) else 10 if next_state == (3, 3) else 0 - Q[state[0], state[1], action] = (1 - alpha) * Q[state[0], state[1], action] + alpha * (reward + gamma * np.max(Q[next_state[0], next_state[1]])) - state = next_state -``` - -### Summary: -**Reinforcement Learning (RL)** is a powerful framework for solving complex decision-making tasks where an agent must learn to maximize cumulative rewards. By interacting with an environment, the agent learns from experience, balancing exploration and exploitation to improve its performance. RL is widely used in robotics, game playing, and automated control systems. - ---- - -This file explains the concept of reinforcement learning in the same structure as the logistic regression file, providing definitions, characteristics, examples, and code implementation. diff --git a/docs/machine-learning/RidgeRegression.md b/docs/machine-learning/RidgeRegression.md deleted file mode 100644 index 45da90716..000000000 --- a/docs/machine-learning/RidgeRegression.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: ridge-regression -title: Ridge Regression Algorithm -sidebar_label: Ridge Regression -descriptin: "In this post, we'll explore the Ridge Regression Algorithm, it is a type of linear regression that addresses some of the limitations of Ordinary Least Squares (OLS) regression." -tags: [machine learning, algorithms, linear regression, regression] - ---- - -### Definition: -**Ridge Regression** addresses some of the limitations of Ordinary Least Squares (OLS) regression, particularly when dealing with multicollinearity or highly correlated features. - -### Characteristics: -- **Regularization (L2 Penalty)** -Ridge Regression applies an L2 regularization penalty, which adds the square of the coefficient magnitudes to the cost function. This penalty term is what differentiates it from standard linear regression. - -- **Bias-Variance Tradeoff** -Ridge Regression helps to balance the bias-variance tradeoff by adjusting the regularization parameter 𝜆 - -- **Handling Multicollinearity** -Ridge Regression performs well when there is multicollinearity (high correlation between features). - -- **Continuous Shrinking of Coefficients** -Ridge Regression shrinks all coefficients continuously toward zero but does not set any coefficient to zero exactly, unlike Lasso regression. - -### How Ridge Regression Works: -1. **Regularization**: - The penalty term reduces the complexity of the model by shrinking the regression coefficients, which can help prevent overfitting. - -2. **Multicollinearity**: -When features are highly correlated, OLS estimates become unstable. Ridge Regression handles this by imposing a constraint on the size of the coefficients, making them more reliable. - -3. **Bias-Variance Tradeoff**: Increasing 𝜆 introduces bias but reduces variance, creating a tradeoff between the model’s accuracy and generalizability. - -### Choosing the Regularization Parameter (λ) -The regularization parameter λ is usually selected using cross-validation. Common techniques include grid search or randomized search to find the optimal value for λ that minimizes the error on a validation set. - -### Example: -Suppose we have a dataset with one feature 𝑥 and a target variable 𝑦: - -``` -| x | y | -|-------|-------| -| 1 | 1 | -| 2 | 2 | -| 3 | 3 | -| 4 | 4 | -| 5 | 5 | -``` - -Step-by-Step Execution: - -1. **Define the Problem**: -We want to fit a linear model of the form: - 𝑦 = β0 + β1*𝑥 - -where 𝛽0 is the intercept, and 𝛽1 is the coefficient for 𝑥. - -2. **Set Up the Ridge Regression Model in Python** -Using Python, we can compute the Ridge Regression model for this data. We'll use scikit-learn for simplicity and compare it to ordinary least squares (OLS) regression to see the effect of Ridge regularization. - -### Python Implementation: -Here is a basic implementation of Linear Regression in Python using **scikit-learn**: - -```python -from sklearn.linear_model import Ridge -from sklearn.model_selection import train_test_split -from sklearn.metrics import mean_squared_error -import numpy as np - -# Assume X and y are the features and target variables -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - -# Initialize the Ridge model with alpha as the regularization parameter (lambda) -ridge_reg = Ridge(alpha=1.0) -ridge_reg.fit(X_train, y_train) - -# Predictions and evaluation -y_pred = ridge_reg.predict(X_test) -mse = mean_squared_error(y_test, y_pred) -print("Mean Squared Error:", mse) -``` - -### Summary: -The **Ridge Regression Algorithm** is a powerful technique for addressing multicollinearity and overfitting in linear regression models. By introducing a penalty term, it stabilizes the estimates of regression coefficients, leading to more reliable and interpretable models. Ridge regression finds applications in various fields, including machine learning, genetic studies, econometrics, and engineering, making it an essential tool in the arsenal of statisticians and data scientists. - diff --git a/docs/machine-learning/SDG.md b/docs/machine-learning/SDG.md deleted file mode 100644 index b267be28c..000000000 --- a/docs/machine-learning/SDG.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: stochastic-gradient-descent -title: "Stochastic Gradient Descent (SGD)" -sidebar_label: SGD -description: "Stochastic Gradient Descent (SGD) is an optimization algorithm used to minimize the loss function in machine learning and deep learning models." -tags: [optimization, machine learning, deep learning] - ---- - -### Overview -Stochastic Gradient Descent (SGD) is an optimization algorithm used to minimize the loss function in machine learning and deep learning models. Unlike standard gradient descent, which calculates the gradient of the loss function for the entire dataset, SGD updates the model parameters for each training example one at a time, making it faster and more suitable for large datasets. - -### How It Works - -1. **Initialize Parameters**: Start with some initial values for the model parameters (weights and biases). -2. **Shuffle Data**: Randomly shuffle the training data. -3. **Parameter Update**: - - For each training example \( x_i \), compute the gradient of the loss function with respect to the model parameters. - - Update the parameters using the formula: - $\[\theta = \theta - \eta \cdot \nabla J(\theta; x_i, y_i)\]$ - where: - - \( \theta \) represents the model parameters (weights and biases). - - \( \eta \) is the learning rate (step size). - - \( \nabla J(\theta; x_i, y_i) \) is the gradient of the loss function for the training example \( (x_i, y_i) \). - -4. **Repeat**: Continue this process for multiple epochs (iterations over the entire dataset). - -### Advantages and Disadvantages - -#### Advantages -- **Faster convergence for large datasets**: Because SGD updates parameters for each training example, it can converge faster than batch gradient descent. -- **Better generalization**: The noisy updates can help escape local minima, potentially leading to better generalization on test data. - -#### Disadvantages -- **Noisy updates**: The parameter updates can be noisy because they are based on a single example, which can cause the loss function to fluctuate. -- **Sensitive to learning rate**: Choosing the right learning rate is crucial for proper convergence. - -### Example Code in Python - -Below is an example implementation of SGD to minimize a simple quadratic loss function using NumPy. - -#### Quadratic Loss Function Example - -Let's say we have a simple linear model \( y = wx + b \), and we want to minimize the mean squared error loss function. - -```python -import numpy as np - -# Generate some synthetic data -np.random.seed(0) -X = 2 * np.random.rand(100, 1) -y = 4 + 3 * X + np.random.randn(100, 1) - -# Hyperparameters -learning_rate = 0.01 -n_iterations = 1000 - -# Initialize weights (w) and bias (b) -w = np.random.randn(1) -b = np.random.randn(1) - -# Stochastic Gradient Descent -for iteration in range(n_iterations): - # Randomly select one data point - random_index = np.random.randint(0, len(X)) - x_i = X[random_index:random_index+1] - y_i = y[random_index:random_index+1] - - # Compute the prediction - y_pred = w * x_i + b - - # Compute the gradients - gradient_w = 2 * (y_pred - y_i) * x_i - gradient_b = 2 * (y_pred - y_i) - - # Update weights and bias - w -= learning_rate * gradient_w - b -= learning_rate * gradient_b - - # Print the progress every 100 iterations - if iteration % 100 == 0: - loss = np.mean((y - (w * X + b)) ** 2) - print(f"Iteration {iteration}: Loss = {loss}") - -print(f"Trained weight: {w[0]}, Trained bias: {b[0]}") -``` diff --git a/docs/machine-learning/SVM.md b/docs/machine-learning/SVM.md deleted file mode 100644 index 9770c42b6..000000000 --- a/docs/machine-learning/SVM.md +++ /dev/null @@ -1,167 +0,0 @@ ---- - -id: svm-visualization -title: Support Vector Machines (SVM) Visualization Algorithm -sidebar_label: SVM -description: "This post explores Support Vector Machines (SVM), a powerful classification algorithm that finds the optimal hyperplane to separate different classes in high-dimensional datasets." -tags: [classification, data visualization, machine learning, SVM, hyperplane, support vectors] - ---- - -### Definition: -**Support Vector Machine (SVM)** is a supervised machine learning algorithm primarily used for classification tasks. It aims to find the optimal hyperplane that maximally separates different classes in the dataset. By using kernel tricks, SVM can also handle non-linearly separable data in higher dimensions. - -### Characteristics: -- **Linear and Non-Linear Classification**: - SVM can perform both linear and non-linear classification by choosing appropriate kernel functions. Linear SVMs are faster but less flexible, while non-linear SVMs (using kernels) can handle complex data structures. - -- **Optimal Hyperplane**: - SVM finds a hyperplane that separates data points of different classes with the maximum possible margin. The data points closest to the hyperplane are called *support vectors* and determine the position of the hyperplane. - -- **Kernel Trick**: - SVM can transform input data into higher dimensions using kernel functions, making it possible to separate data that is not linearly separable in its original space. - -### Components of SVM: -1. **Hyperplane**: - A decision boundary that separates data points of different classes. In 2D, it's a line; in 3D, it's a plane; in higher dimensions, it's called a hyperplane. - -2. **Support Vectors**: - These are the critical data points that lie closest to the hyperplane. They define the margin of the classifier and are pivotal in calculating the optimal hyperplane. - -3. **Margin**: - The margin is the distance between the hyperplane and the closest support vectors from any class. SVM aims to maximize this margin to improve classification accuracy. - -### Steps Involved: -1. **Input Data**: - Provide the high-dimensional input data consisting of features and corresponding class labels. - -2. **Choosing a Kernel**: - Decide whether to use a linear or non-linear SVM. If non-linear, choose an appropriate kernel (e.g., polynomial, RBF). - -3. **Hyperplane Calculation**: - The SVM algorithm finds the optimal hyperplane that maximizes the margin between classes. - -4. **Optimization**: - Use quadratic programming to find the support vectors and the corresponding hyperplane parameters, minimizing classification errors. - -5. **Classification**: - Once trained, the SVM can classify new data points based on which side of the hyperplane they fall. - -### Key Concepts: -- **Hyperplane**: - A decision boundary that splits the data into different classes. SVM selects the hyperplane that maximizes the margin from the nearest data points of each class. - -- **Kernel**: - A function that transforms data into higher dimensions. Popular kernels include: - - **Linear**: Suitable for linearly separable data. - - **Polynomial**: A non-linear kernel using polynomial features. - - **Radial Basis Function (RBF)**: Maps data into an infinite-dimensional space, handling complex relationships. - - **Sigmoid**: Functions like a neural network layer. - -- **Regularization Parameter (C)**: - A hyperparameter that controls the trade-off between maximizing the margin and minimizing classification errors. A lower value allows a larger margin but more misclassification, while a higher value focuses on correctly classifying all training examples. - -### SVM Algorithm Architecture: -1. **Input Layer**: - Input data with features and corresponding class labels. Each observation is a data point in a high-dimensional space. - -2. **Kernel Transformation Layer**: - (Optional) If using a non-linear SVM, the data is transformed into a higher-dimensional space using a kernel function. - -3. **Hyperplane Calculation Layer**: - SVM calculates the optimal hyperplane, which separates data points by maximizing the margin. - -4. **Optimization Layer**: - A cost function is minimized to find the best position for the hyperplane, identifying support vectors that contribute to the decision boundary. - -5. **Classification Layer**: - After training, the model classifies new data points based on their position relative to the hyperplane. - -### Advantages of SVM: -- **Effective in High-Dimensional Spaces**: - SVM performs well in datasets with many features, making it suitable for high-dimensional spaces. - -- **Robust to Overfitting**: - With an appropriate choice of the regularization parameter, SVM is less prone to overfitting, especially in high-dimensional data. - -- **Versatile Kernel Choices**: - The ability to select from a variety of kernels makes SVM adaptable to different types of data distributions. - -### Limitations of SVM: -- **Computational Complexity**: - Training an SVM, especially with non-linear kernels, can be computationally expensive, particularly for large datasets. - -- **Choice of Kernel**: - Selecting the correct kernel and its parameters can be challenging, requiring domain knowledge and experimentation. - -- **No Probabilistic Output**: - SVM doesn’t inherently provide probability estimates, though methods like Platt scaling can add this functionality. - -### Use Cases: -1. **Binary Classification**: - SVM excels in binary classification problems, such as spam detection, where data is divided into two distinct categories. - -2. **Image Classification**: - SVM is commonly used in image recognition tasks due to its ability to handle high-dimensional feature spaces effectively. - -3. **Text Categorization**: - In Natural Language Processing (NLP), SVM can classify documents or sentiments by mapping word features into high dimensions. - -4. **Bioinformatics**: - SVM is popular in bioinformatics for gene classification and protein structure prediction due to its accuracy in high-dimensional biological data. - -### Example of SVM in Python: -```python -import numpy as np -import matplotlib.pyplot as plt -from sklearn import datasets -from sklearn.model_selection import train_test_split -from sklearn.svm import SVC - -# Load dataset -iris = datasets.load_iris() -X = iris.data[:, :2] # Use only the first two features for visualization -y = iris.target - -# Split dataset -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) - -# Train SVM -svm_model = SVC(kernel='linear', C=1) -svm_model.fit(X_train, y_train) - -# Plot decision boundary -plt.figure(figsize=(10, 6)) - -# Create a mesh to plot decision boundary -h = 0.02 -x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 -y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 -xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) -Z = svm_model.predict(np.c_[xx.ravel(), yy.ravel()]) - -# Put the result into a color plot -Z = Z.reshape(xx.shape) -plt.contourf(xx, yy, Z, alpha=0.4, cmap='coolwarm') -plt.scatter(X[:, 0], X[:, 1], c=y, edgecolor='k', s=50) -plt.title("SVM Decision Boundary for Iris Dataset (Linear Kernel)") -plt.xlabel('Feature 1') -plt.ylabel('Feature 2') -plt.show() -``` - -### Time and Space Complexity: -- **Time Complexity**: - The time complexity of SVM varies: - - **Linear SVM**: Approximately $O(n \cdot d)$, where $n$ is the number of samples and $d$ is the number of features. - - **Non-linear SVM**: Approximately $O(n^2)$ for training due to the quadratic programming involved. - -- **Space Complexity**: - The space complexity is $O(n^2)$ due to the storage of pairwise similarities between support vectors. - -### Summary & Applications: -- **SVM** is a powerful tool for classification, known for its ability to find the optimal decision boundary in high-dimensional data. It is versatile, capable of handling both linear and non-linear relationships with the help of kernels, making it widely used in various fields like text categorization, image classification, and bioinformatics. - -- **Applications**: - SVM is utilized in industries like finance, healthcare, and e-commerce for tasks such as fraud detection, medical diagnosis, and customer segmentation, offering a reliable solution for complex classification problems. - diff --git a/docs/machine-learning/Singular_Value_Decomposition_Algorithm.md b/docs/machine-learning/Singular_Value_Decomposition_Algorithm.md deleted file mode 100644 index bda107de4..000000000 --- a/docs/machine-learning/Singular_Value_Decomposition_Algorithm.md +++ /dev/null @@ -1,129 +0,0 @@ ---- - -id: singular-value-decomposition -title: Singular Value Decomposition (SVD) Algorithm -sidebar_label: Singular Value Decomposition -description: "In this post, we'll delve into Singular Value Decomposition (SVD), a matrix factorization technique used in linear algebra with applications in dimensionality reduction, image processing, and recommendation systems." -tags: [machine learning, linear algebra, SVD, dimensionality reduction, matrix factorization] - ---- - -### Definition: -**Singular Value Decomposition (SVD)** is a matrix factorization technique used in linear algebra to decompose a matrix into three other matrices. SVD is commonly used in dimensionality reduction, noise reduction, and feature extraction in data analysis and machine learning. - -### Characteristics: -- **Matrix Factorization**: - SVD decomposes a matrix $A$ into three matrices: $U$, $Σ$, and $V^T$, making it possible to analyze matrix properties and reduce dimensionality. - -- **Dimensionality Reduction**: - SVD is frequently used in applications like recommendation systems and image compression to reduce data dimensions while retaining important information. - -- **Orthogonality**: - The matrices $U$ and $V$ in SVD are orthogonal, allowing the representation of data with minimal redundancy. - -### Key Concepts: -1. **Decomposition**: - SVD decomposes a matrix $A$ (of size $m \times n$) into three matrices: - - ![image](https://github.com/user-attachments/assets/af1893e5-c973-472c-b40d-36a68efc6294) - - where: - - $U$ is an $m \times m$ orthogonal matrix (left singular vectors). - - $Σ$ is an $m \times n$ diagonal matrix containing singular values. - - $V^T$ is an $n \times n$ orthogonal matrix (right singular vectors). - -2. **Singular Values**: - The diagonal entries of $Σ$ are known as singular values of $A$. These values indicate the strength or importance of each dimension in the data. - -3. **Rank and Reconstruction**: - SVD can approximate a matrix by keeping only the largest singular values, helping reduce noise and dimensionality. The rank of $A$ corresponds to the number of non-zero singular values in $Σ$. - -4. **Truncated SVD**: - In practice, a truncated version of SVD can be used by retaining only the top $k$ singular values, which significantly reduces data size and is useful for noise reduction. - -### Singular Value Decomposition Process: -1. **Decompose the Matrix**: - Perform SVD on matrix $A$ to obtain $U$, $Σ$, and $V^T$. - -2. **Select Components**: - Choose the top $k$ singular values in $Σ$ for dimensionality reduction. - -3. **Reconstruct Matrix** (optional): - Use the truncated matrices $U_k$, $Σ_k$, and $V_k^T$ to approximate the original matrix $A$ while retaining most of the variance. - -### SVD Algorithm Steps: -1. **Calculate Singular Values**: - Compute the singular values of $A$ by solving for the eigenvalues of $A^T A$ or $A A^T$. - -2. **Form Matrices $U$, $Σ$, and $V^T$**: - The eigenvectors corresponding to the eigenvalues form $U$ and $V$, while $Σ$ holds the singular values. - -3. **Truncate if Necessary**: - For dimensionality reduction, use only the top $k$ singular values and the corresponding columns in $U$ and $V$. - -### Parameters: -- **Matrix $A$**: - The original matrix to be decomposed, often representing data or images. - -- **Rank $k$**: - The number of singular values to retain in truncated SVD, balancing dimensionality reduction and information retention. - -### Advantages of SVD: -- **Efficient Data Compression**: - SVD provides a way to reduce data size without significant loss of information, useful for applications like image compression. - -- **Noise Reduction**: - By omitting smaller singular values, SVD can reduce the noise in data, improving clarity or interpretability. - -- **Feature Extraction**: - SVD can uncover hidden features in data, useful in tasks like topic modeling in natural language processing. - -### Disadvantages of SVD: -- **Computationally Intensive**: - For large matrices, SVD computation can be expensive, as it involves solving eigenvalue problems. - -- **Sensitivity to Outliers**: - SVD can be affected by outliers in the data, potentially impacting the decomposition. - -### Python Implementation: -Here is an example implementation of SVD using **NumPy**: - -```python -import numpy as np - -# Define a sample matrix -A = np.array([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] -]) - -# Perform SVD -U, S, Vt = np.linalg.svd(A, full_matrices=False) - -print("U matrix:\n", U) -print("Singular values:\n", S) -print("Vt matrix:\n", Vt) - -# Reconstruct matrix -reconstructed_A = np.dot(U, np.dot(np.diag(S), Vt)) -print("Reconstructed Matrix:\n", reconstructed_A) -``` - -### SVD Parameters: -In the example above: -- `U`: Contains the left singular vectors. -- `S`: Holds the singular values. -- `Vt`: Contains the right singular vectors transposed. - -### Choosing Parameters: -1. **Rank $k$**: - Select a rank $k$ to retain based on the largest singular values that capture most of the data variance. - -2. **Thresholding Small Singular Values**: - Remove smaller singular values (in $Σ$) to reduce noise, especially in tasks like image or text processing. - -### Summary: -**Singular Value Decomposition (SVD)** is a powerful tool in linear algebra that decomposes a matrix into three simpler matrices, facilitating tasks like dimensionality reduction, noise reduction, and data compression. With applications across machine learning, data science, and signal processing, SVD enables efficient handling of high-dimensional data by capturing essential features while discarding noise. - ---- diff --git a/docs/machine-learning/Statistical_Anomaly_Detection.md b/docs/machine-learning/Statistical_Anomaly_Detection.md deleted file mode 100644 index adf7247f9..000000000 --- a/docs/machine-learning/Statistical_Anomaly_Detection.md +++ /dev/null @@ -1,184 +0,0 @@ ---- - -id: statistical-anomaly-detection -title: Statistical Anomaly Detection Algorithm -sidebar_label: Statistical Anomaly Detection -description: "This post covers Statistical Anomaly Detection, a technique used to identify data points that deviate significantly from the norm based on statistical models and methods." -tags: [anomaly detection, statistics, machine learning, outliers, data analysis] - ---- - -### Definition: -**Statistical Anomaly Detection** refers to methods used to detect data points, events, or observations that deviate significantly from the norm, based on statistical models and distributions. These anomalous points, often called *outliers*, may indicate unusual events or errors and are crucial in areas such as fraud detection, network security, quality control, and more. - -### Characteristics: -- **Model-Based**: - Statistical anomaly detection relies on statistical models such as normal distributions, moving averages, or more complex probabilistic models to define what is considered “normal” behavior. - -- **Data-Driven**: - It uses historical data to define normal ranges, thresholds, or patterns and flags any data point that falls outside these boundaries as an anomaly. - -- **Univariate and Multivariate**: - Anomalies can be detected in both univariate data (single variable) or multivariate data (multiple variables or features), depending on the complexity of the problem. - -### Types of Anomalies: -1. **Point Anomalies**: - A single data point is significantly different from the rest of the data (e.g., a temperature reading far beyond the normal range). - -2. **Contextual Anomalies**: - A data point is anomalous within a specific context, but may appear normal in a different context (e.g., a high temperature might be normal in summer but anomalous in winter). - -3. **Collective Anomalies**: - A group of data points is collectively anomalous, even if the individual points may not be (e.g., a sudden, unexpected trend in stock market prices). - -### Components of Statistical Anomaly Detection: -1. **Statistical Model**: - A statistical model is built to define the expected behavior of the data. This could involve normal distribution assumptions, Gaussian processes, or more complex probabilistic models. - -2. **Threshold Setting**: - Once the statistical model is established, thresholds are set. These can be based on standard deviations, percentiles, or confidence intervals that help determine the bounds for normal behavior. - -3. **Outlier Detection**: - Data points that fall outside the normal range or violate the statistical rules are flagged as anomalies. - -4. **Evaluation**: - After detection, the flagged anomalies are reviewed to determine whether they represent true anomalies (e.g., fraud, system malfunction) or false positives (normal data misclassified as anomalous). - -### Common Statistical Techniques for Anomaly Detection: -1. **Z-Score (Standard Score)**: - Measures how many standard deviations a data point is from the mean. A Z-score greater than a set threshold (e.g., |Z| > 3) indicates an anomaly. -![image](https://github.com/user-attachments/assets/da027485-d853-472f-93e4-84b1884fb977) - - where: - - $X$ = data point - - $\mu$ = mean of the data - - $\sigma$ = standard deviation - -2. **Moving Average**: - Anomalies are detected by calculating the moving average of data over a window and flagging points that deviate significantly from it. - -3. **Grubbs' Test**: - A statistical test used to detect outliers in a dataset that follows a normal distribution. Grubbs' Test compares the extreme value to the rest of the dataset, identifying whether it's significantly different. - -4. **IQR (Interquartile Range)**: - Based on the spread of the middle 50% of the data, points are flagged as anomalies if they fall below the 1st quartile or above the 3rd quartile by more than 1.5 times the interquartile range (IQR). -![image](https://github.com/user-attachments/assets/9d8d6719-26ae-465c-a0f5-003040975278) - - Points outside $(Q_1 - 1.5 \times \text{IQR}$ or $Q_3 + 1.5 \times \text{IQR})$ are considered outliers. - -5. **Chi-Square Test**: - For categorical data, this test checks if the observed frequencies differ from expected frequencies. Anomalies are detected if the difference is statistically significant. - -6. **Density Estimation (Gaussian)**: - The likelihood of a data point being part of a known distribution is estimated. Data points with low probability according to the fitted Gaussian distribution are flagged as anomalies. - -### Steps Involved in Statistical Anomaly Detection: -1. **Data Collection**: - Gather the data to be analyzed, which can be univariate or multivariate in nature, depending on the problem. - -2. **Statistical Modeling**: - Fit a statistical model to the data, such as a normal distribution, to understand its expected behavior. - -3. **Threshold Calculation**: - Determine thresholds or cutoff points that define the boundary between normal and anomalous behavior, often using confidence intervals or standard deviations. - -4. **Anomaly Detection**: - Compare incoming data points against the statistical model and thresholds to detect anomalies. Flag any data points that fall outside of the predefined range. - -5. **Post-Processing**: - Evaluate the flagged anomalies to determine if they represent true anomalies or if they are false positives, requiring further investigation or model tuning. - -### Key Concepts: -- **Z-Score**: - A measure of how far a data point is from the mean in terms of standard deviations, used to detect outliers. - -- **P-Value**: - In hypothesis testing, a p-value helps determine whether to reject the null hypothesis (normal behavior). Small p-values indicate anomalies. - -- **Threshold Setting**: - Thresholds define when a data point is considered anomalous, based on statistical rules such as being more than three standard deviations from the mean. - -- **Seasonality and Trend**: - In time series data, statistical models often account for seasonality (repeating patterns) and trends, as anomalies may be detected based on deviations from these patterns. - -### Statistical Anomaly Detection Architecture: -1. **Input Layer**: - The algorithm accepts the input data, which can be univariate (e.g., stock prices) or multivariate (e.g., sensor data). - -2. **Statistical Model Layer**: - The data is modeled using statistical methods like normal distribution, moving average, or hypothesis tests. - -3. **Anomaly Detection Layer**: - The model applies statistical tests or threshold-based rules to identify data points that are anomalous. - -4. **Flagging and Alerting Layer**: - Detected anomalies are flagged and often passed to a downstream system for further investigation or alerting. - -5. **Post-Processing Layer**: - False positives are filtered out, and true anomalies are prioritized for action. - -### Advantages of Statistical Anomaly Detection: -- **Simplicity**: - Statistical methods are easy to understand and implement, often providing a simple and interpretable framework for anomaly detection. - -- **Data-Agnostic**: - These methods can be applied to a wide range of datasets, from time series to categorical data, without needing complex feature engineering. - -- **Real-Time Detection**: - Statistical methods can be used in real-time systems to detect anomalies as new data arrives, enabling rapid response to unusual events. - -### Limitations of Statistical Anomaly Detection: -- **Assumptions About Data Distribution**: - Many statistical techniques assume that the data follows a normal distribution, which may not always be true in real-world scenarios. - -- **Sensitivity to Noise**: - Statistical methods can be sensitive to noise in the data, leading to false positives if the model is not tuned carefully. - -- **Scalability**: - For large datasets or high-dimensional data, statistical methods may become computationally expensive and require optimization. - -### Use Cases: -1. **Fraud Detection**: - In banking or e-commerce, statistical anomaly detection can be used to identify unusual transactions that may indicate fraud. - -2. **Network Intrusion Detection**: - Monitoring network traffic for patterns that deviate from the norm can help detect potential security breaches. - -3. **Quality Control**: - In manufacturing, anomalies detected in sensor data or production metrics can indicate defects or equipment malfunctions. - -4. **Medical Diagnosis**: - Detecting abnormal health metrics in patient data can help identify early signs of medical conditions or anomalies in diagnostic tests. - -### Example of Statistical Anomaly Detection in Python: -```python -import numpy as np -import matplotlib.pyplot as plt -from scipy import stats - -# Generate sample data -np.random.seed(42) -data = np.random.normal(loc=50, scale=5, size=1000) - -# Z-Score calculation -z_scores = np.abs(stats.zscore(data)) - -# Define threshold for anomalies -threshold = 3 -anomalies = np.where(z_scores > threshold) - -# Plot data with anomalies highlighted -plt.figure(figsize=(8, 6)) -plt.plot(data, label='Data') -plt.scatter(anomalies, data[anomalies], color='red', label='Anomalies') -plt.legend() -plt.title("Anomaly Detection using Z-Score") -plt.show() -``` - -### Time and Space Complexity: -- **Time Complexity**: - The time complexity depends on the statistical method used. For example, calculating the Z-score has a linear time complexity of $O(n)$ for n data points. - -- **Space Complexity**: - Space complexity is typically linear, $O(n)$, as the data points need to be stored and diff --git a/docs/machine-learning/Time_Series_Forecasting_Algo.md b/docs/machine-learning/Time_Series_Forecasting_Algo.md deleted file mode 100644 index 58dc46257..000000000 --- a/docs/machine-learning/Time_Series_Forecasting_Algo.md +++ /dev/null @@ -1,199 +0,0 @@ ---- - -id: time-series-forecasting -title: Time Series Forecasting Algorithms -sidebar_label: Time Series Forecasting -description: "This post covers Time Series Forecasting, a method used to predict future data points in a time-ordered sequence based on past data." -tags: [time series, forecasting, machine learning, ARIMA, LSTM, statistics, predictive analysis] - ---- - -### Definition: -**Time Series Forecasting** is a technique used to predict future values based on previously observed time-ordered data. Time series data are sequences of data points collected or recorded at specific time intervals. Forecasting techniques attempt to model the underlying patterns such as trend, seasonality, and noise to make accurate future predictions. - -### Characteristics: -- **Temporal Dependency**: - Time series forecasting depends heavily on the sequential nature of the data, with future values influenced by past observations. - -- **Pattern Recognition**: - Models identify patterns like trends (long-term increases or decreases), seasonality (cyclic behaviors), and random noise to make predictions. - -- **Extrapolation**: - The goal is to extrapolate the future behavior of the data based on patterns found in historical data. - -- **Real-Time or Batch Predictions**: - Time series models can be applied in real-time scenarios (e.g., stock prices) or for batch forecasting (e.g., sales forecasting for the next quarter). - -### Types of Time Series Components: -1. **Trend**: - A long-term increase or decrease in the data. - -2. **Seasonality**: - A repeating pattern of behavior at regular intervals (e.g., daily, weekly, monthly). - -3. **Cyclical**: - Fluctuations that occur but are not as regular as seasonal patterns, often linked to economic or business cycles. - -4. **Residual (Noise)**: - Irregular, random variations that are not captured by trend or seasonal components. - -### Common Time Series Forecasting Techniques: -1. **ARIMA (AutoRegressive Integrated Moving Average)**: - A widely used statistical method that combines autoregression (AR), differencing to make the data stationary (I), and moving average (MA) to handle the noise in the data. ARIMA is suitable for univariate time series data. - - $y_t = c + \phi_1 y_{t-1} + \phi_2 y_{t-2} + \dots + \theta_1 e_{t-1} + \theta_2 e_{t-2} + \dots + e_t$ - -3. **SARIMA (Seasonal ARIMA)**: - Extends ARIMA by accounting for seasonal effects, which can occur in time series data with repeating cycles over time. - -4. **Exponential Smoothing (ETS Models)**: - Assigns exponentially decreasing weights to past observations, placing more importance on recent data. Variants include Simple Exponential Smoothing, Holt’s Linear Trend Model, and Holt-Winters Seasonal Model. - -5. **Prophet**: - Developed by Facebook, Prophet is an additive model suitable for forecasting time series with daily, weekly, and yearly seasonality. It’s designed to handle missing data and outliers. - -6. **LSTM (Long Short-Term Memory Networks)**: - A type of Recurrent Neural Network (RNN) used for time series forecasting due to its ability to remember long-term dependencies and patterns in sequential data. LSTM is particularly useful for complex, non-linear patterns. - -7. **VAR (Vector AutoRegression)**: - A multivariate time series forecasting method where each variable is predicted using a linear combination of its own past values and the past values of other variables. - -8. **TBATS (Exponential Smoothing State Space Model)**: - A method used for time series with complex seasonalities, such as hourly, daily, and yearly patterns, combining trend, seasonality, and a Box-Cox transformation. - -9. **XGBoost for Time Series**: - Although traditionally used for classification and regression, XGBoost can be adapted for time series forecasting by engineering features such as lags, rolling means, and other relevant variables. - -### Steps in Time Series Forecasting: -1. **Data Collection**: - Gather historical time series data relevant to the problem, ensuring data is consistently spaced in time. - -2. **Data Preprocessing**: - Handle missing values, smooth noisy data, and scale or transform variables if needed. Differencing can be applied to remove trends. - -3. **Stationarity Check**: - Check whether the time series data is stationary (i.e., its statistical properties do not change over time). Techniques like the Augmented Dickey-Fuller (ADF) test can be used. - -4. **Model Selection**: - Choose an appropriate model (e.g., ARIMA, LSTM, Prophet) based on the nature of the time series data and its components (trend, seasonality, etc.). - -5. **Model Training and Validation**: - Split the data into training and validation sets, then train the model on the historical data and evaluate its performance on the validation set. - -6. **Hyperparameter Tuning**: - Adjust model hyperparameters to improve accuracy, such as the order of ARIMA components (p, d, q) or the number of LSTM units. - -7. **Forecasting**: - Generate future predictions based on the trained model, extrapolating the patterns it has learned from the historical data. - -8. **Evaluation**: - Use metrics such as Mean Absolute Error (MAE), Mean Squared Error (MSE), or Mean Absolute Percentage Error (MAPE) to evaluate the model's accuracy on unseen data. - -### Common Metrics for Forecast Accuracy: -- **Mean Absolute Error (MAE)**: - The average of the absolute differences between predicted and actual values. It provides a direct measure of error. -![image](https://github.com/user-attachments/assets/5753d782-2b4d-41d1-9233-1df8440ee3e3) - - -- **Mean Squared Error (MSE)**: - The average of the squared differences between predicted and actual values. It penalizes larger errors more than MAE. -![image](https://github.com/user-attachments/assets/a94b022d-48cf-4a05-8d6f-7baba9315c42) - - -- **Root Mean Squared Error (RMSE)**: - The square root of the MSE, providing an error metric in the same units as the target variable. -![image](https://github.com/user-attachments/assets/61e63777-6a25-43a8-9475-9a92853ece4f) - - -- **Mean Absolute Percentage Error (MAPE)**: - The average of the percentage errors between predicted and actual values. It’s useful for understanding the error in relative terms. -![image](https://github.com/user-attachments/assets/888a2a78-2423-475d-ac4c-b9c9cd270e89) - - -### Time Series Forecasting Algorithms Architecture: -1. **Input Layer**: - The historical time series data is fed into the model, which could be univariate (a single series) or multivariate (multiple series). - -2. **Transformation Layer**: - The data is preprocessed and transformed (e.g., differenced, scaled) to make it suitable for model training. - -3. **Model Layer**: - The chosen model (ARIMA, LSTM, etc.) is applied to capture patterns like trend, seasonality, and noise from the data. - -4. **Prediction Layer**: - The model forecasts future values based on the learned patterns. - -5. **Evaluation Layer**: - Forecasted values are compared against actual values to measure performance and accuracy. - -### Advantages of Time Series Forecasting: -- **Temporal Awareness**: - Time series models are designed to handle sequential data and temporal dependencies, making them ideal for forecasting problems. - -- **Predictive Power**: - With the right model, time series forecasting can produce highly accurate predictions that capture trends, seasonality, and other patterns. - -- **Wide Applicability**: - These methods can be applied in various domains such as finance, sales, weather forecasting, and operations management. - -### Simple Python Implementation for Time Series Forecasting using ARIMA - - ```python - -import pandas as pd -import matplotlib.pyplot as plt -from statsmodels.tsa.arima.model import ARIMA -from sklearn.metrics import mean_squared_error - -#Load sample time series dataset -#Dataset should have a 'Date' column and a 'Value' column (e.g., stock prices, sales data) -data = pd.read_csv('sample_time_series.csv', parse_dates=['Date'], index_col='Date') - -#Split the data into training and testing sets -train_size = int(len(data) * 0.8) -train, test = data[0:train_size], data[train_size:] - -#Fit the ARIMA model -model = ARIMA(train['Value'], order=(5, 1, 0)) # (p, d, q) parameters -model_fit = model.fit() - -#Forecast the next values (based on the test size) -forecast = model_fit.forecast(steps=len(test)) - -#Plot the forecast vs actual values -plt.figure(figsize=(10,6)) -plt.plot(train.index, train['Value'], label='Training Data') -plt.plot(test.index, test['Value'], label='Actual Data', color='green') -plt.plot(test.index, forecast, label='Forecasted Data', color='red') -plt.legend() -plt.title('Time Series Forecasting - ARIMA') -plt.show() - -#Evaluate the model with MSE -mse = mean_squared_error(test['Value'], forecast) -print(f'Mean Squared Error: {mse}') - -``` - -### Explanation of the Code: -1. **Data Loading**: - Load a time series dataset that includes a 'Date' column and a 'Value' column (e.g., stock prices, sales data). - -2. **Train-Test Split**: - The dataset is split into a training set (80% of the data) and a testing set (20%). - -3. **ARIMA Model**: - The ARIMA model is fitted to the training data. The `(5, 1, 0)` parameters are the ARIMA model’s hyperparameters: `p`, `d`, and `q`. These need to be tuned for your specific dataset. - -4. **Forecasting**: - The model forecasts values for the test period. - -5. **Plotting**: - The forecasted data is plotted against the actual test data to visualize the performance. - -6. **Model Evaluation**: - The Mean Squared Error (MSE) is calculated to quantify the forecast accuracy. - -### Conclusion: -Time series forecasting provides essential insights and predictive power for data that follows a sequential or time-dependent structure. Whether using traditional models like ARIMA or advanced models like LSTM, these methods help extract patterns from historical data to forecast future values. - diff --git a/docs/machine-learning/XGBoost.md b/docs/machine-learning/XGBoost.md deleted file mode 100644 index 284c8f07e..000000000 --- a/docs/machine-learning/XGBoost.md +++ /dev/null @@ -1,102 +0,0 @@ ---- - -id: xgboost -title: XGBoost Algorithm -sidebar_label: XGBoost -description: "XGBoost is a highly efficient and scalable machine learning algorithm known for its accuracy and speed in solving both classification and regression problems." -tags: [machine learning, algorithms, xgboost, classification, regression] - ---- - -### Definition: -**XGBoost (eXtreme Gradient Boosting)** is a supervised learning algorithm that implements gradient boosting for classification and regression tasks. It builds an ensemble of decision trees in a sequential manner, where each subsequent tree aims to reduce the errors of the previous trees, improving accuracy through boosting techniques. - -### Characteristics: -- **Boosting Technique**: - XGBoost uses a boosting method where weak learners (shallow trees) are combined iteratively to create a strong predictive model. Each tree tries to correct the errors made by the previous one, focusing on harder-to-predict instances. - -- **Highly Efficient**: - XGBoost is known for its speed and performance optimizations, utilizing techniques such as parallel tree boosting and hardware optimization to handle large-scale datasets efficiently. - -- **Regularization**: - Unlike traditional boosting, XGBoost includes regularization parameters to prevent overfitting, making it a robust choice even for noisy data. - - -### Steps Involved: -1. **Initialize the Model**: - XGBoost starts by initializing predictions with a base value (such as the average of the target values in regression). - -2. **Fit Gradient-Boosted Trees**: - Sequentially add decision trees, each one trained to reduce the residual errors of the model’s predictions from the previous iteration. - -3. **Update Weights**: - At each step, the algorithm updates the weights of misclassified instances, assigning higher weights to the harder-to-predict instances in classification or high-error instances in regression. - -4. **Predict and Aggregate**: - The final model aggregates the predictions of all trees, weighted by their learning rates, to output the final classification or regression prediction. - -### Problem Statement: -Given a dataset, the goal of XGBoost is to iteratively build a model that minimizes the prediction error by adding trees that improve upon the mistakes of previous ones, effectively handling both classification and regression tasks. - -### Key Concepts: -- **Boosting**: - A technique that combines multiple weak learners (e.g., shallow decision trees) into a strong predictive model. - -- **Learning Rate**: - A parameter that scales the contribution of each new tree added to the model, balancing the trade-off between the speed of learning and generalization. - -- **Max Depth**: - Limits the depth of the trees to prevent overfitting, controlling model complexity. - -### Objective Function: -The objective function minimized by XGBoost is defined as: - -$Obj(\Theta) = \sum_{i=1}^{n} L(y_i, \hat{y}) + \sum_{k=1}^{K} \Omega(f_k)$ - - - -Where: -- $L(y_i, \hat{y}_i)$ is the loss function measuring the difference between true values ($y_i$) and predicted values \($\hat{y}_i$). -- $\Omega(f_k)$ is the regularization term penalizing the complexity of the model. - -### Time Complexity: -- **Best, Average, and Worst Case: $O(n \log n)$** - XGBoost optimizes tree construction with a greedy algorithm, achieving logarithmic time complexity for each tree based on the number of training instances `n`. - -### Space Complexity: -- **Space Complexity: $O(n)$** - The memory footprint grows with the number of data points, as XGBoost needs to store gradient and Hessian information for each instance during training. - -### Python Implementation: -Here is a basic implementation of XGBoost in Python using the **XGBoost** library: - -```python -import xgboost as xgb -from sklearn.model_selection import train_test_split -from sklearn.datasets import load_boston -from sklearn.metrics import mean_squared_error - -# Load dataset -data = load_boston() -X, y = data.data, data.target - -# Split into training and testing sets -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - -# Create XGBoost model -model = xgb.XGBRegressor(objective='reg:squarederror', n_estimators=100, learning_rate=0.1) - -# Train model -model.fit(X_train, y_train) - -# Make predictions -predictions = model.predict(X_test) - -# Calculate mean squared error -mse = mean_squared_error(y_test, predictions) -print(f'Mean Squared Error: {mse}') -``` - -### Summary: -**XGBoost** is a powerful, efficient, and scalable machine learning algorithm. Its regularization capabilities, combined with its use of gradient boosting, make it a popular choice for a wide range of tasks. - diff --git a/docs/machine-learning/decisionTree.md b/docs/machine-learning/decisionTree.md deleted file mode 100644 index 974370c0c..000000000 --- a/docs/machine-learning/decisionTree.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: decision-tree -title: Decision Tree Algorithm -sidebar_label: Decision Tree -description: "In this post, we'll explore the Decision Tree Algorithm, a popular machine learning model used for classification and regression tasks." -tags: [machine learning, algorithms, decision tree, classification, regression] - ---- - -### Definition: -The **Decision Tree Algorithm** is a supervised machine learning algorithm used for both **classification** and **regression** tasks. It splits data into subsets based on feature values, creating a tree-like structure where each internal node represents a decision based on a feature, and each leaf node represents an outcome (class label or continuous value). - -### Characteristics: -- **Recursive Partitioning**: - A decision tree recursively splits the dataset based on specific conditions (features) to form a tree structure that leads to a prediction at each leaf node. - -- **Interpretability**: - Decision trees are highly interpretable because the decision-making process is clear and transparent. You can easily follow the path of decisions from root to leaf to understand how a prediction is made. - -- **Non-parametric**: - This algorithm doesn’t make any assumptions about the underlying data distribution, making it suitable for a variety of datasets. - -### Types of Decision Trees: -1. **Classification Tree**: - Used when the target variable is categorical (e.g., yes/no, spam/ham). It predicts the class label based on the features. - -2. **Regression Tree**: - Used when the target variable is continuous (e.g., predicting a price). It predicts a real number based on the features. - -### Steps Involved: -1. **Choose the Best Split**: - The dataset is split based on the feature that maximizes some criteria. For classification, **Gini Index** or **Entropy** (used in information gain) is commonly used. For regression, **mean squared error** is often the criterion. - -2. **Recursively Split**: - The process is repeated recursively for each subset, creating branches until no further meaningful splits can be made (e.g., when the data is perfectly classified or a stopping criterion like maximum depth is reached). - -3. **Assign Leaf Nodes**: - Once the splitting stops, the leaf nodes are assigned a class label (for classification) or a value (for regression). - -### Problem Statement: -Given a dataset with features and target values, the goal is to build a decision tree that can **classify** data points into categories or **predict** continuous values based on the features. - -### Key Concepts: -- **Root Node**: - The top-most node in the tree, where the first feature split occurs. - -- **Internal Nodes**: - Nodes where further feature splits occur based on the conditions. - -- **Leaf Nodes**: - Terminal nodes that hold the final prediction (class or value). - -### Split Criteria: -- **Gini Impurity** (for classification): - Measures the probability of a randomly chosen element being misclassified. - -![image](https://github.com/user-attachments/assets/505d8d21-3f41-4bba-9120-4ad98beec8c1) - - - Where \( p_i \) is the probability of the class label at node \( i \). - -- **Entropy** (for classification): - Measures the disorder or impurity in the dataset. - -![image](https://github.com/user-attachments/assets/954fa9ab-f3d6-4055-8c12-7630dd8e6a50) - - - Where \( p_i \) is the proportion of data points in class \( i \). - -- **Information Gain**: - Measures the reduction in entropy after a dataset is split on a feature. - -![image](https://github.com/user-attachments/assets/e0eecef3-6e4d-414c-a963-19708922ed91) - - -- **Mean Squared Error (MSE)** (for regression): - Measures the variance between the predicted and actual values at each node. - -### Time Complexity: -- **Best, Average, and Worst Case: $O(n \log n)$** - The time complexity depends on sorting the dataset at each node. For `n` data points, the overall complexity is logarithmic in depth with respect to the size of the dataset. - -### Space Complexity: -- **Space Complexity: $O(n)$** - The space complexity arises from storing the tree structure and the data used for training. - -### Example: -Consider a dataset for predicting whether someone buys a product based on their **age** and **income**: - -- Dataset: - ``` - | Age | Income | Buys Product | - |-------|---------|--------------| - | 25 | High | Yes | - | 45 | Medium | No | - | 35 | Low | Yes | - | 22 | Low | Yes | - ``` - -Step-by-Step Execution: - -1. **Choose the best split**: - Using a criterion like Gini Impurity or Information Gain, the algorithm will decide which feature (Age or Income) provides the best split. - -2. **Recursively split**: - It splits the data and continues until leaf nodes are formed, which represent the final decision (Yes/No for classification). - -### Python Implementation: -Here is a basic implementation of a Decision Tree in Python using **scikit-learn**: - -```python -from sklearn.datasets import load_iris -from sklearn.tree import DecisionTreeClassifier -from sklearn import tree -import matplotlib.pyplot as plt - -# Load dataset -iris = load_iris() -X, y = iris.data, iris.target - -# Create Decision Tree classifier -clf = DecisionTreeClassifier() - -# Train model -clf = clf.fit(X, y) - -# Plot the tree -plt.figure(figsize=(12,8)) -tree.plot_tree(clf, filled=True, feature_names=iris.feature_names, class_names=iris.target_names) -plt.show() -``` - -### Summary: -The **Decision Tree Algorithm** is a simple yet powerful model that can be used for both classification and regression tasks. Its ease of interpretation, ability to handle both categorical and numerical data, and non-parametric nature make it a versatile choice for many machine learning problems. However, decision trees are prone to **overfitting**, which can be mitigated by techniques like **pruning**, **random forests**, or **ensemble methods**. - diff --git a/docs/machine-learning/hierarchical-clustering-visualizations.md b/docs/machine-learning/hierarchical-clustering-visualizations.md deleted file mode 100644 index 4e82312d5..000000000 --- a/docs/machine-learning/hierarchical-clustering-visualizations.md +++ /dev/null @@ -1,129 +0,0 @@ ---- - -id: hierarchical-clustering-visualizations -title: Hierarchical Clustering Visualizations -sidebar_label: Hierarchical Clustering -description: "Implement hierarchical clustering algorithms that build a hierarchy of clusters using either agglomerative or divisive methods. This feature will include visualizations to help users understand the clustering process." -tags: [data science, clustering, hierarchical clustering, data visualization, machine learning] - ---- - -### Definition: -**Hierarchical Clustering** is an unsupervised machine learning technique that creates a hierarchy of clusters, allowing data points to be grouped based on their similarities. This method can be performed in two ways: agglomeratively (bottom-up) and divisively (top-down). - -### Characteristics: -- **Dendrogram Representation**: - Hierarchical clustering can be visualized using a dendrogram, which illustrates the relationships between clusters at various levels of granularity. - -- **Flexible Number of Clusters**: - Unlike K-Means, hierarchical clustering does not require specifying the number of clusters in advance. - -- **Distance Metrics**: - Various distance metrics (e.g., Euclidean, Manhattan) and linkage criteria (e.g., single, complete, average) can be used to determine how clusters are formed. - -### Components of Hierarchical Clustering: -1. **Clusters**: - Groups of similar data points that are merged or split during the clustering process. - -2. **Dendrogram**: - A tree-like diagram that shows the arrangement of clusters and the distances at which merges or splits occur. - -3. **Linkage Criteria**: - Methods used to define the distance between clusters, affecting the shape and size of the resulting clusters. - -### Steps Involved: -1. **Choose a Distance Metric**: - Select a method to measure the distance between data points. - -2. **Build the Dendrogram**: - Start with each data point as its own cluster and iteratively merge clusters based on the selected distance metric and linkage criteria. - -3. **Cut the Dendrogram**: - Determine the number of clusters by cutting the dendrogram at a specified height. - -4. **Assign Clusters**: - Based on the cuts, assign data points to their respective clusters. - -### Key Concepts: -- **Agglomerative Clustering**: - A bottom-up approach where each data point starts as a separate cluster and clusters are merged based on distance. - -- **Divisive Clustering**: - A top-down approach that starts with one cluster and recursively splits it into smaller clusters. - -- **Linkage Methods**: - Common methods include single linkage (minimum distance), complete linkage (maximum distance), and average linkage (mean distance). - -### Advantages of Hierarchical Clustering: -- **Intuitive Visualization**: - The dendrogram provides a clear visual representation of the clustering process and relationships. - -- **No Need for Predefined K**: - Users can choose the number of clusters after inspecting the dendrogram. - -- **Handles Different Cluster Shapes**: - Can capture clusters of various shapes and sizes, unlike K-Means. - -### Limitations of Hierarchical Clustering: -- **Computationally Intensive**: - The time complexity can be high, especially for large datasets, making it less suitable for very large datasets. - -- **Sensitive to Noise**: -Outliers can distort the clustering structure and affect results. - -- **Linkage Dependency**: -The choice of linkage method can significantly influence the resulting clusters. - -### Popular Applications of Hierarchical Clustering: -1. **Genomics**: - Used to group genes or samples based on expression data to identify biological patterns. - -2. **Market Research**: - Helps in segmenting customers based on purchasing behavior for targeted marketing strategies. - -3. **Document Clustering**: - Groups similar documents for efficient retrieval and organization. - -4. **Image Segmentation**: - Clusters similar pixels to delineate objects within images. - -5. **Social Network Analysis**: - Identifies communities or groups within social networks based on interaction patterns. - -### Example of Hierarchical Clustering in Python: -```python -import numpy as np -import matplotlib.pyplot as plt -import seaborn as sns -from sklearn.datasets import make_blobs -from scipy.cluster.hierarchy import dendrogram, linkage - -# Create a sample dataset -X, _ = make_blobs(n_samples=100, centers=3, cluster_std=0.60, random_state=0) - -# Perform hierarchical clustering -linked = linkage(X, method='ward') - -# Create a dendrogram -plt.figure(figsize=(10, 7)) -dendrogram(linked, orientation='top', distance_sort='descending', show_leaf_counts=True) -plt.title('Hierarchical Clustering Dendrogram') -plt.xlabel('Sample Index') -plt.ylabel('Distance') -plt.show() -``` - -### Time and Space Complexity: -- **Time Complexity**: - The time complexity is generally $O(n^3)$ for the basic implementation, but more efficient methods exist. - -- **Space Complexity**: - The space required is $O(n^2)$ for storing distance matrices. - -### Summary & Applications: -- **Hierarchical Clustering** is a versatile technique that provides valuable insights into data structures and relationships, making it essential for exploratory data analysis. - -- **Applications**: - Effective in various fields such as genomics, marketing, and image processing, helping uncover patterns and facilitate decision-making. - ---- \ No newline at end of file diff --git a/docs/machine-learning/naive-bayes.md b/docs/machine-learning/naive-bayes.md deleted file mode 100644 index ecf4fe56a..000000000 --- a/docs/machine-learning/naive-bayes.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -id: naive-bayes-theorem -title: Naive Bayes Algorithm -sidebar_label: Naive Bayes -description: "In this post, we’ll explore the Naive Bayes Theorem, a fundamental probabilistic algorithm used for classification tasks based on Bayes' Theorem and the assumption of conditional independence." -tags: [machine learning, algorithms, naive bayes, classification, bayes theorem, probability] ---- - -### Definition: -The **Naive Bayes** algorithm is a probabilistic classifier based on **Bayes' Theorem** with the assumption that the features are conditionally independent given the class label. Despite the "naive" assumption of feature independence, it is highly effective for various real-world applications such as spam filtering, text classification, and recommendation systems. - - - -### Characteristics: -- **Probabilistic Model**: - Naive Bayes predicts the class label by calculating the posterior probability of each class based on the input features and selecting the class with the highest probability. - -- **Conditional Independence Assumption**: - Naive Bayes assumes that each feature is independent of others given the class label, which simplifies the calculation of probabilities but may not always hold in practice. - -- **Efficient and Scalable**: - Naive Bayes is computationally efficient and can scale well to large datasets with multiple features. - -### Types of Naive Bayes: -1. **Gaussian Naive Bayes**: - Used when the features are continuous and follow a Gaussian (normal) distribution. Commonly applied in cases where the data can be assumed to be normally distributed. - -2. **Multinomial Naive Bayes**: - Used for discrete data, often applied in text classification, where the features represent counts or frequencies of words (e.g., spam detection). - -3. **Bernoulli Naive Bayes**: - Applied to binary data, where the features take on binary values (e.g., presence or absence of a word in text classification). - - - -### Steps Involved: -1. **Input the Data**: - The algorithm receives labelled training data, where each example consists of a set of features and a corresponding class label. - -2. **Calculate Prior Probabilities**: - The prior probability of each class is computed based on the frequency of each class in the training data. - -3. **Calculate Likelihood**: - For each feature and class, the likelihood is calculated by determining how likely it is to observe a particular feature value given the class. - -4. **Apply Bayes' Theorem**: - Using Bayes' Theorem, the posterior probability of each class is calculated based on the priors and likelihoods: - - $$ - P(y|X) = \frac{P(X|y) \cdot P(y)}{P(X)} - $$ - - where $P(y|X)$ is the posterior probability of the class given the feature vector, $P(X|y)$ is the likelihood, $P(y)$ is the prior, and $P(X)$ is the evidence. - -5. **Classify New Data**: - For a new data point, the algorithm computes the posterior probability for each class and assigns the label of the class with the highest probability. - - - -### Problem Statement: -Given a dataset with multiple features and corresponding class labels, the objective is to train a Naive Bayes classifier that can predict the class label for new, unseen data based on the calculated probabilities. - -### Key Concepts: -- **Bayes' Theorem**: - Bayes' Theorem is a mathematical formula used to calculate conditional probabilities. It is expressed as: - - $$ - P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} - $$ - - where: - - $P(A|B)$ is the posterior probability of event $A$ given that $B$ is true. - - $P(B|A)$ is the likelihood of observing $B$ given that $A$ is true. - - $P(A)$ is the prior probability of event $A$. - - $P(B)$ is the total probability of event $B$. - -- **Prior Probability**: - The prior probability represents the initial belief about the class labels before considering any feature values, based on the distribution of classes in the training data. - -- **Likelihood**: - The likelihood is the probability of observing the feature values given a specific class label. - -- **Posterior Probability**: - The posterior probability is the probability of a class label after considering the observed feature values, which is what Naive Bayes uses to make predictions. - -- **Naive Assumption**: - Naive Bayes assumes that all features are independent given the class, simplifying the probability calculations. This assumption, although unrealistic in many cases, allows for efficient computation and often leads to good results. - - - -### Split Criteria: -Naive Bayes splits data based on the **highest posterior probability** for each class, assigning the class label that maximizes this probability. - -### Time Complexity: -- **Training Complexity**: - Training involves calculating probabilities for each feature and class, resulting in a time complexity of $ O(n \cdot k) $, where $ n $ is the number of features and $ k $ is the number of classes. - -- **Prediction Complexity**: - For predicting the class of a new data point, the time complexity is $ O(n \cdot k) $, as it requires computing the posterior probability for each class. - -### Space Complexity: -- **Space Complexity**: - The space complexity is mainly determined by storing the calculated probabilities, which depends on the number of features, classes, and their possible values. - -### Example: -Consider a spam detection system that classifies emails as "spam" or "not spam" based on features such as the presence of certain words (binary features). - -**Dataset:** - -| Word 'Free' | Word 'Money' | Spam | -|-------------|--------------|------| -| Yes | Yes | Yes | -| Yes | No | No | -| No | Yes | Yes | -| No | No | No | - -Step-by-Step Execution: - -1. **Input Data**: - The model receives training data with features (words) and labels (spam/not spam). - -2. **Calculate Priors**: - The prior probabilities of the classes (spam and not spam) are calculated based on the class distribution: - - $$ - P(\text{Spam}) = \frac{\text{Number of spam emails}}{\text{Total number of emails}} - $$ - - $$ - P(\text{Not Spam}) = \frac{\text{Number of non-spam emails}}{\text{Total number of emails}} - $$ - -3. **Calculate Likelihoods**: - For each word (feature) and class, the likelihood is calculated. For example: - - $$ - P(\text{Free}|\text{Spam}) = \frac{\text{Number of spam emails containing 'Free'}}{\text{Total number of spam emails}} - $$ - -4. **Apply Bayes' Theorem**: - Using Bayes' Theorem, the posterior probabilities for new emails are calculated. - -5. **Make Predictions**: - The class with the highest posterior probability is predicted (spam or not spam). - - - -### Python Implementation: -Here is a basic implementation of Naive Bayes using **scikit-learn**: - -```python -from sklearn.datasets import load_iris -from sklearn.model_selection import train_test_split -from sklearn.naive_bayes import GaussianNB -from sklearn.metrics import accuracy_score - -# Load dataset -iris = load_iris() -X, y = iris.data, iris.target - -# Split dataset -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - -# Create Gaussian Naive Bayes model -nb = GaussianNB() - -# Train model -nb.fit(X_train, y_train) - -# Predict -y_pred = nb.predict(X_test) - -# Evaluate -accuracy = accuracy_score(y_test, y_pred) -print(f"Accuracy: {accuracy:.2f}") -``` diff --git a/docs/machine-learning/neuralNetworks.md b/docs/machine-learning/neuralNetworks.md deleted file mode 100644 index 9fb24dfad..000000000 --- a/docs/machine-learning/neuralNetworks.md +++ /dev/null @@ -1,178 +0,0 @@ ---- - -id: neural-networks-visualizations -title: Neural Networks Visualizations -sidebar_label: Neural Networks -description: "Build and visualize neural networks with support for feedforward, convolutional, and recurrent architectures. Explore how these models learn from data using backpropagation and gradient descent." -tags: [machine learning, neural networks, deep learning, data visualization, feedforward networks, CNN, RNN] - ---- - -### Definition: -**Neural Networks** are a class of machine learning algorithms inspired by the human brain. They consist of interconnected layers of nodes (neurons) that process data by learning patterns and relationships from examples. Neural networks are the foundation of deep learning, used in various domains, including computer vision, natural language processing, and reinforcement learning. - -### Characteristics: -- **Layered Architecture**: - Neural networks are typically organized into layers — an input layer, one or more hidden layers, and an output layer. - -- **Activation Functions**: - Each neuron uses an activation function (e.g., sigmoid, ReLU, softmax) to determine the output, adding non-linearity to the network. - -- **Backpropagation**: - A key algorithm used for training neural networks, where the error is propagated back through the layers to update the weights. - -### Components of Neural Networks: -1. **Neurons**: - The basic units that receive input, apply an activation function, and pass the output to the next layer. - -2. **Weights and Biases**: - Parameters that determine the strength of connections between neurons. Weights are adjusted during training to minimize the error. - -3. **Activation Functions**: - Functions applied to the weighted sum of inputs to introduce non-linearity (e.g., ReLU, sigmoid, tanh). - -4. **Loss Function**: - A function that quantifies the difference between the predicted and actual outputs, guiding the learning process. - -5. **Optimizer**: - An algorithm (e.g., SGD, Adam) that adjusts the weights during training to minimize the loss function. - -### Steps Involved: -1. **Initialize the Model**: - Define the architecture, including the number of layers, neurons per layer, activation functions, and initialization of weights. - -2. **Forward Propagation**: - Input data passes through each layer, and neurons apply their activation functions to produce the output. - -3. **Compute Loss**: - Calculate the difference between the predicted and actual output using a loss function. - -4. **Backpropagation**: - Compute gradients of the loss function concerning weights and biases, adjusting them to minimize the error. - -5. **Update Weights**: - Adjust weights using an optimizer algorithm to improve the network's predictions iteratively. - -6. **Iterate**: - Repeat the forward and backward propagation steps for multiple iterations (epochs) until convergence. - -### Key Concepts: -- **Feedforward Networks (FFNN)**: - Data flows unidirectionally from input to output. Often used for regression and classification tasks. - -- **Convolutional Neural Networks (CNN)**: - Specialized for image processing, CNNs use convolutional layers to detect patterns such as edges, shapes, and textures. - -- **Recurrent Neural Networks (RNN)**: - Designed for sequential data, RNNs have connections that loop, allowing them to maintain memory of previous inputs — ideal for time-series or language data. - -- **Deep Learning**: - Refers to neural networks with many hidden layers (deep networks) that can capture complex relationships in data. - -### Neural Networks Architecture: -1. **Input Layer**: - Accepts raw input data, such as images, text, or numerical values, and passes it to the first hidden layer. - -2. **Hidden Layers**: - Each hidden layer processes the data using weights, biases, and activation functions. These layers extract features or patterns from the data. - -3. **Output Layer**: - Produces the final prediction, often using a softmax (classification) or linear activation (regression) function. - -4. **Connections**: - Fully connected, convolutional, or recurrent connections between neurons define how data flows through the network. - -### Advantages of Neural Networks: -- **High Accuracy**: - Neural networks can achieve state-of-the-art results in various domains, particularly with deep architectures. - -- **Versatility**: - They can handle different data types — images, text, audio, video, and time-series. - -- **Feature Learning**: - Automatically learn features from raw data, reducing the need for manual feature engineering. - -### Limitations of Neural Networks: -- **Computationally Intensive**: - Neural networks, especially deep ones, require significant computational resources (GPU/TPU) for training. - -- **Data Hungry**: - Large amounts of labeled data are often necessary for training effective models. - -- **Interpretability**: - Neural networks are sometimes seen as "black boxes," making it difficult to interpret how they make decisions. - -### Popular Neural Network Architectures: -1. **Feedforward Neural Networks (FFNN)**: - The simplest form of neural networks with no cycles. Each layer's output is passed directly to the next layer. - -2. **Convolutional Neural Networks (CNN)**: - Use convolutional layers for feature extraction, making them powerful for tasks like image classification, object detection, and segmentation. - -3. **Recurrent Neural Networks (RNN)**: - Designed to handle sequential data, RNNs are commonly used for tasks like language modeling, time-series forecasting, and machine translation. - -4. **Generative Adversarial Networks (GANs)**: - Consist of two networks — a generator and a discriminator — working against each other to produce realistic data, such as images. - -5. **Transformers**: - Advanced architecture that uses self-attention mechanisms, revolutionizing natural language processing tasks like translation, summarization, and sentiment analysis. - -### Use Cases: -1. **Image Classification**: - CNNs are used to classify images into categories (e.g., identifying objects in photos). - -2. **Natural Language Processing (NLP)**: - RNNs, LSTMs, and Transformers are used for tasks like sentiment analysis, machine translation, and chatbots. - -3. **Speech Recognition**: - Deep neural networks process audio data for speech-to-text conversion and voice assistants. - -4. **Time-Series Prediction**: - RNNs are employed for forecasting future trends based on past data in finance, weather, or inventory management. - -5. **Autonomous Driving**: - CNNs analyze images from cameras to detect lanes, vehicles, and pedestrians. - -### Example of Neural Networks in Python: -```python -import numpy as np -import tensorflow as tf -from tensorflow.keras.models import Sequential -from tensorflow.keras.layers import Dense - -# Create a simple Feedforward Neural Network using TensorFlow -model = Sequential([ - Dense(32, activation='relu', input_shape=(10,)), # Hidden Layer 1 - Dense(16, activation='relu'), # Hidden Layer 2 - Dense(1, activation='sigmoid') # Output Layer for Binary Classification -]) - -# Compile the model -model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) - -# Sample training data -X_train = np.random.rand(100, 10) # 100 samples, 10 features -y_train = np.random.randint(2, size=100) # Binary target - -# Train the model -model.fit(X_train, y_train, epochs=10, batch_size=8) - -# Summary of the model architecture -model.summary() -``` - -### Time and Space Complexity: -- **Time Complexity**: - Forward and backward propagation in a neural network is roughly $O(d \cdot n \cdot k)$, where $d$ is the number of layers, $n$ is the number of neurons per layer, and $k$ is the number of training samples. - -- **Space Complexity**: - The memory required is $O(d \cdot n)$ for storing weights, biases, and intermediate activations. - -### Summary & Applications: -- **Neural Networks** are powerful algorithms capable of learning complex patterns from data. They have revolutionized many fields, including computer vision, natural language processing, and autonomous systems. - -- **Applications**: - Widely used in image recognition, speech synthesis, language translation, game playing, and anomaly detection. - ---- diff --git a/docs/machine-learning/random-forest.md b/docs/machine-learning/random-forest.md deleted file mode 100644 index ed06157da..000000000 --- a/docs/machine-learning/random-forest.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -id: random-forest -title: Random Forest Algorithm -sidebar_label: Random Forest -description: "In this post, we’ll dive into the Random Forest Algorithm, an ensemble learning model used for classification and regression tasks, known for its robustness and versatility." -tags: [machine learning, algorithms, random forest, classification, regression] ---- - -### Definition: -The **Random Forest Algorithm** is a versatile and widely-used ensemble learning technique that builds multiple decision trees during training and combines their predictions to improve accuracy and robustness. This algorithm is applicable to both **classification** and **regression** tasks. The core idea behind random forests is that by averaging or "voting" across many decision trees, the overall prediction is more reliable and less prone to overfitting compared to individual trees. - -### Characteristics: -- **Ensemble Learning**: - Random forest is an ensemble method, meaning it aggregates the outputs of many decision trees to make a final prediction, which helps to enhance performance and reduce overfitting. - -- **Randomness in Trees**: - The algorithm introduces randomness in two main ways: it selects random subsets of features at each split, and it trains each tree on a random subset of the training data (with replacement, known as **bootstrap sampling**). This leads to diverse trees, improving model accuracy. - -- **Robustness**: - Random forest is robust against overfitting, especially when compared to single decision trees. It can handle missing values, and because it averages predictions, it is less sensitive to noise in the data. - -### Types of Random Forest: -1. **Classification Forest**: - Used when the target variable is categorical (e.g., yes/no, dog/cat). It uses majority voting across multiple trees to assign a class label. - -2. **Regression Forest**: - Used when the target variable is continuous (e.g., predicting a price). It takes the average of the predictions from all the trees to generate a final output. - -### Steps Involved: -1. **Bootstrap Sampling**: - For each tree, the algorithm randomly selects a subset of the training data with replacement (bootstrapping). This ensures each tree is trained on different data, promoting diversity among the trees. - -2. **Feature Randomness**: - At each node of a tree, a random subset of features is selected to find the best possible split. This further diversifies the trees and prevents overfitting. - -3. **Grow Decision Trees**: - Each tree is grown to its maximum depth without pruning. However, individual trees may be weak, but the ensemble (forest) of many trees is strong. - -4. **Aggregate Results**: - For classification tasks, the forest takes a majority vote across all trees to decide the final class. For regression tasks, it takes the average of the predictions from all trees. - -### Problem Statement: -Given a dataset with features and target values, the goal is to build a random forest that can **classify** data points into categories or **predict** continuous values by leveraging the power of multiple decision trees. - -### Key Concepts: -- **Bootstrap Aggregation (Bagging)**: - This technique trains each tree on a randomly selected subset of the dataset (with replacement), promoting diversity in the ensemble. - -- **Out-of-Bag (OOB) Error**: - Since each tree is trained on a random subset of the data, about one-third of the data is not used during training and can be used to estimate the model’s accuracy (out-of-bag error) without the need for a separate validation set. - -- **Majority Voting (for Classification)**: - The final prediction for a classification task is based on the class that gets the most votes from the trees. - -- **Averaging (for Regression)**: - The final prediction for a regression task is the average of the predictions from all trees. - -### Split Criteria: -- **Gini Impurity**: - Like in decision trees, Gini impurity is used for evaluating splits in classification problems. It measures how often a randomly chosen element would be misclassified if it was randomly labeled. - -- **Mean Squared Error (MSE)**: - For regression tasks, the mean squared error is used to find the optimal splits that minimize the variance between predicted and actual values. - -### Time Complexity: -- **Training Complexity**: - For a random forest of `T` trees, each trained on `n` samples and with `d` features, the time complexity for training is approximately $O(T \cdot n \cdot d \cdot \log n)$. - -- **Prediction Complexity**: - For making predictions, each tree in the forest contributes, so the complexity is $O(T \cdot \log n)$ for a forest with `T` trees and `n` data points. - -### Space Complexity: -- **Space Complexity**: - The space complexity is $O(T \cdot n \cdot d)$ due to the storage of `T` trees, each with `n` samples and `d` features. - -### Example: -Consider a dataset to classify whether a customer will churn based on factors like age, income, and customer activity: - -- Dataset: -| Age | Income | Active | Churned | -|-----|--------|--------|---------| -| 25 | High | Yes | No | -| 45 | Medium | No | Yes | -| 35 | Low | Yes | No | -| 22 | Low | No | Yes | - - - -Step-by-Step Execution: - -1. **Bootstrap Sampling**: - Each tree gets a random sample of the data to train on, with some data points potentially appearing multiple times in the sample. - -2. **Random Feature Selection**: - At each node, a random subset of features (e.g., Age or Income) is selected to find the best split. - -3. **Grow Trees**: - Each tree grows fully, creating a deep structure that may not generalize well individually but contributes to the overall accuracy when combined. - -4. **Aggregate Predictions**: - After all trees are grown, the final prediction is made based on the majority vote for classification tasks or averaging for regression tasks. - -### Python Implementation: -Here is a basic implementation of a Random Forest in Python using **scikit-learn**: - -```python -from sklearn.datasets import load_iris -from sklearn.ensemble import RandomForestClassifier -from sklearn.model_selection import train_test_split -from sklearn.metrics import accuracy_score - -# Load dataset -iris = load_iris() -X, y = iris.data, iris.target - -# Split dataset -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - -# Create Random Forest classifier -clf = RandomForestClassifier(n_estimators=100, random_state=42) - -# Train model -clf.fit(X_train, y_train) - -# Predict -y_pred = clf.predict(X_test) - -# Evaluate -accuracy = accuracy_score(y_test, y_pred) -print(f"Accuracy: {accuracy:.2f}") -``` diff --git a/docs/machine-learning/regression_algorithm.md b/docs/machine-learning/regression_algorithm.md deleted file mode 100644 index ff17f3195..000000000 --- a/docs/machine-learning/regression_algorithm.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -id: regression -title: "Regression Algorithm (Supervised learning)" -sidebar_label: Regression Algorithms -description: "In this post, we’ll explore the concept of regression in supervised learning, a fundamental approach used for predicting continuous outcomes based on input features." -tags: [machine learning, algorithms, supervised learning, regression] ---- - -### Definition: -**Regression** is a type of supervised learning algorithm used to predict continuous outcomes based on one or more input features. The model learns from labeled training data to establish a relationship between the input variables and the target variable. - - - -### Characteristics: -- **Continuous Output**: - Regression algorithms are used when the output variable is continuous, such as predicting prices, temperatures, or scores. - -- **Predictive Modeling**: - The primary goal is to create a model that can accurately predict numerical values for new, unseen data based on learned relationships. - -- **Evaluation Metrics**: - Regression models are evaluated using metrics such as Mean Squared Error (MSE), R-squared (R²), and Root Mean Squared Error (RMSE). - -### Types of Regression Algorithms: -1. **Linear Regression**: - A simple approach that models the relationship between one or more independent variables and a dependent variable by fitting a linear equation. - -2. **Polynomial Regression**: - Extends linear regression by fitting a polynomial equation to the data, allowing for more complex relationships. - -3. **Ridge and Lasso Regression**: - Regularization techniques that add penalties to the loss function to prevent overfitting. Ridge uses L2 regularization, while Lasso uses L1 regularization. - -4. **Support Vector Regression (SVR)**: - An extension of Support Vector Machines (SVM) that can be used for regression tasks by finding a hyperplane that best fits the data. - -5. **Decision Tree Regression**: - Uses decision trees to model relationships between features and target values by splitting data into subsets based on feature values. - -6. **Random Forest Regression**: - An ensemble method that combines multiple decision trees to improve prediction accuracy and control overfitting. - - - -### Steps Involved: -1. **Input the Data**: - The algorithm receives labeled training data consisting of features and corresponding target values. - -2. **Preprocess the Data**: - Data cleaning and preprocessing steps may include handling missing values, normalizing or scaling features, and encoding categorical variables. - -3. **Split the Dataset**: - The dataset is typically split into training and testing sets to evaluate model performance. - -4. **Select a Model**: - Choose an appropriate regression algorithm based on the problem type and data characteristics. - -5. **Train the Model**: - Fit the model to the training data using an optimization algorithm to minimize error. - -6. **Evaluate Model Performance**: - Use metrics such as MSE or R² score to assess how well the model performs on unseen data. - -7. **Make Predictions**: - Use the trained model to make predictions on new data points. - - - -### Problem Statement: -Given a labeled dataset with multiple features and corresponding continuous target values, the objective is to train a regression model that can accurately predict target values for new, unseen data based on learned patterns. - -### Key Concepts: -- **Training Set**: - The portion of the dataset used to train the model. - -- **Test Set**: - The portion of the dataset used to evaluate model performance after training. - -- **Overfitting and Underfitting**: - Overfitting occurs when a model learns noise in the training data rather than general patterns. Underfitting occurs when a model is too simple to capture underlying trends. - -- **Evaluation Metrics**: - Metrics used to assess model performance include MSE for regression tasks and R² score for measuring explained variance. - - - -### Split Criteria: -Regression algorithms typically split data based on minimizing prediction error or maximizing explained variance in predictions. - -### Time Complexity: -- **Training Complexity**: - Varies by algorithm; can range from linear time complexity for simple models like Linear Regression to polynomial time complexity for more complex models. - -- **Prediction Complexity**: -Also varies by algorithm; some algorithms allow for faster predictions after training (e.g., linear models). - -### Space Complexity: -- **Space Complexity**: -Depends on how much information about the training set needs to be stored (e.g., decision trees may require more space than linear models). - -### Example: -Consider a scenario where we want to predict house prices based on features such as size, number of bedrooms, and location. - -**Dataset Example:** - -| Size (sq ft) | Bedrooms | Price ($) | -|---------------|----------|-----------| -| 1500 | 3 | 300000 | -| 2000 | 4 | 400000 | -| 1200 | 2 | 250000 | -| 1800 | 3 | 350000 | - -Step-by-Step Execution: - -1. **Input Data**: - The model receives training data with features (size and bedrooms) and labels (price). - -2. **Preprocess Data**: - Handle any missing values or outliers if necessary. - -3. **Split Dataset**: - Divide the dataset into training and testing sets (e.g., 80% train, 20% test). - -4. **Select Model**: - Choose an appropriate regression algorithm like Linear Regression. - -5. **Train Model**: - Fit the model using the training set. - -6. **Evaluate Performance**: - Use metrics like R² score or mean squared error on the test set. - -7. **Make Predictions**: - Predict prices for new houses based on their features. - - - -### Python Implementation: -Here’s a basic implementation of Linear Regression using **scikit-learn**: - -```python -from sklearn.model_selection import train_test_split -from sklearn.linear_model import LinearRegression -from sklearn.metrics import mean_squared_error - -# Sample dataset -data = { - 'Size': [1500, 2000, 1200, 1800], - 'Bedrooms': [3, 4, 2, 3], - 'Price': [300000, 400000, 250000, 350000] -} - -# Convert to DataFrame -import pandas as pd -df = pd.DataFrame(data) - -# Features and target variable -X = df[['Size', 'Bedrooms']] -y = df['Price'] - -# Split dataset -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - -# Create Linear Regression model -model = LinearRegression() - -# Train model -model.fit(X_train, y_train) - -# Predict -y_pred = model.predict(X_test) - -# Evaluate -mse = mean_squared_error(y_test, y_pred) -print(f"Mean Squared Error: {mse:.2f}") -``` - diff --git a/docs/machine-learning/supervised_learning_algo.md b/docs/machine-learning/supervised_learning_algo.md deleted file mode 100644 index db31ce1ac..000000000 --- a/docs/machine-learning/supervised_learning_algo.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -id: supervised-learning-algorithm -title: Supervised Learning Algorithm -sidebar_label: Supervised Learning -description: "In this post, we’ll explore the concept of supervised learning, a fundamental approach in machine learning where models are trained using labeled data." -tags: [machine learning, algorithms, supervised learning] ---- - -### Definition: -**Supervised Learning** is a type of machine learning where an algorithm learns from labeled training data to make predictions or classifications on unseen data. The model is trained using input-output pairs, allowing it to learn the relationship between features and target labels. - - - -### Characteristics: -- **Labeled Data**: - Supervised learning requires a dataset that includes both input features and corresponding output labels. - -- **Predictive Modeling**: - The primary goal is to build a model that can accurately predict the output for new, unseen data based on the learned relationships. - -- **Feedback Mechanism**: - The model is evaluated based on its performance on a validation set, allowing for adjustments and improvements. - -### Types of Supervised Learning Algorithms: -1. **Regression Algorithms**: - Used when the output variable is continuous. Examples include Linear Regression and Polynomial Regression. - -2. **Classification Algorithms**: - Used when the output variable is categorical. Examples include Logistic Regression, Decision Trees, and Support Vector Machines (SVM). - - - -### Steps Involved: -1. **Input the Data**: - The algorithm receives labeled training data consisting of features and corresponding target labels. - -2. **Preprocess the Data**: - Data cleaning and preprocessing steps may include handling missing values, normalizing or scaling features, and encoding categorical variables. - -3. **Split the Dataset**: - The dataset is typically split into training and testing sets to evaluate model performance. - -4. **Select a Model**: - Choose an appropriate supervised learning algorithm based on the problem type (regression or classification). - -5. **Train the Model**: - Fit the model to the training data using an optimization algorithm to minimize error. - -6. **Evaluate Model Performance**: - Use metrics such as accuracy, precision, recall, or mean squared error (MSE) to assess how well the model performs on unseen data. - -7. **Make Predictions**: - Use the trained model to make predictions on new data points. - - - -### Problem Statement: -Given a labeled dataset with multiple features and corresponding target labels, the objective is to train a supervised learning model that can accurately predict target labels for new, unseen data based on learned patterns. - -### Key Concepts: -- **Training Set**: - The portion of the dataset used to train the model. - -- **Test Set**: - The portion of the dataset used to evaluate model performance after training. - -- **Overfitting and Underfitting**: - Overfitting occurs when a model learns noise in the training data rather than general patterns. Underfitting occurs when a model is too simple to capture underlying trends. - -- **Evaluation Metrics**: - Metrics used to assess model performance include accuracy for classification tasks and mean squared error for regression tasks. - - - -### Split Criteria: -Supervised learning algorithms typically split data based on minimizing prediction error or maximizing classification accuracy. - -### Time Complexity: -- **Training Complexity**: - Varies by algorithm; can range from linear to polynomial time complexity depending on data size and algorithm choice. - -- **Prediction Complexity**: - Also varies by algorithm; some algorithms allow for faster predictions after training (e.g., k-NN can be slower during prediction). - -### Space Complexity: -- **Space Complexity**: - Depends on how much information about the training set needs to be stored (e.g., decision trees may require more space than linear models). - -### Example: -Consider a scenario where we want to predict house prices based on features such as size, number of bedrooms, and location. - -**Dataset Example:** - -| Size (sq ft) | Bedrooms | Price ($) | -|---------------|----------|-----------| -| 1500 | 3 | 300000 | -| 2000 | 4 | 400000 | -| 1200 | 2 | 250000 | -| 1800 | 3 | 350000 | - -Step-by-Step Execution: - -1. **Input Data**: - The model receives training data with features (size and bedrooms) and labels (price). - -2. **Preprocess Data**: - Handle any missing values or outliers if necessary. - -3. **Split Dataset**: - Divide the dataset into training and testing sets (e.g., 80% train, 20% test). - -4. **Select Model**: - Choose an appropriate regression algorithm like Linear Regression. - -5. **Train Model**: - Fit the model using the training set. - -6. **Evaluate Performance**: - Use metrics like R² score or mean squared error on the test set. - -7. **Make Predictions**: - Predict prices for new houses based on their features. - - - -### Python Implementation: -Here’s a basic implementation of a supervised learning algorithm using **scikit-learn**, specifically Linear Regression: - -```python -from sklearn.model_selection import train_test_split -from sklearn.linear_model import LinearRegression -from sklearn.metrics import mean_squared_error - -# Sample dataset -data = { - 'Size': [1500, 2000, 1200, 1800], - 'Bedrooms': [3, 4, 2, 3], - 'Price': [300000, 400000, 250000, 350000] -} - -# Convert to DataFrame -import pandas as pd -df = pd.DataFrame(data) - -# Features and target variable -X = df[['Size', 'Bedrooms']] -y = df['Price'] - -# Split dataset -X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - -# Create Linear Regression model -model = LinearRegression() - -# Train model -model.fit(X_train, y_train) - -# Predict -y_pred = model.predict(X_test) - -# Evaluate -mse = mean_squared_error(y_test, y_pred) -print(f"Mean Squared Error: {mse:.2f}") -``` diff --git a/docs/machine-learning/support-vector-machine.md b/docs/machine-learning/support-vector-machine.md deleted file mode 100644 index f06f6c750..000000000 --- a/docs/machine-learning/support-vector-machine.md +++ /dev/null @@ -1,126 +0,0 @@ ---- - -id: support-vector-machine -title: Support Vector Machine (SVM) Algorithm -sidebar_label: Support Vector Machine -description: "SVM is a powerful machine learning model known for its effectiveness in classification tasks and its ability to handle high-dimensional data." -tags: [machine learning, algorithms, SVM, classification, regression] - ---- - -### Definition: -The **Support Vector Machine (SVM)** is a supervised machine learning algorithm commonly used for **classification** and sometimes for **regression**. It works by finding the optimal hyperplane that separates different classes in the feature space, ensuring that the margin between the nearest points (support vectors) of each class is maximized. - -### Characteristics: -- **Margin Maximization**: - SVM aims to maximize the distance between the hyperplane and the nearest data points from each class (support vectors). This helps in achieving better generalization. - -- **Kernel Trick**: - SVM uses kernel functions to project data into higher dimensions where a linear separation between classes may be easier to achieve. Common kernels include linear, polynomial, and radial basis function (RBF). - -- **Effective in High-Dimensional Spaces**: - SVM is particularly effective in cases where the number of dimensions exceeds the number of samples, making it suitable for complex datasets. - -### Types of SVM: -1. **Binary SVM**: - The most common type, where the algorithm separates data into two distinct classes. - -2. **Multiclass SVM**: - By using strategies like one-vs-one or one-vs-all, SVM can handle multiple classes. - -3. **Support Vector Regression (SVR)**: - A version of SVM that handles regression tasks by finding a margin of tolerance (epsilon) and minimizing the prediction error outside of this margin. - -### Steps Involved: -1. **Select the Kernel**: - Choose a kernel function (e.g., linear, RBF) that can help separate the data points in the feature space. - -2. **Maximize the Margin**: - SVM computes the hyperplane that maximizes the margin between the closest data points of each class (support vectors). - -3. **Handle Non-Linearly Separable Data**: - If data is not linearly separable, SVM applies the **kernel trick** to project the data into higher-dimensional space where it becomes separable. - -4. **Regularization**: - Introduce a regularization parameter (C) to control the trade-off between maximizing the margin and allowing some misclassifications (soft margin). - -### Problem Statement: -Given a dataset with features and target labels, the objective of SVM is to find a hyperplane that best separates the different classes in the feature space, while maximizing the margin and minimizing classification error. - -### Key Concepts: -- **Hyperplane**: - A decision boundary that separates different classes in the feature space. - -- **Support Vectors**: - The data points that are closest to the hyperplane, which directly influence its position and orientation. - -- **Margin**: - The distance between the hyperplane and the nearest data points from each class. A wider margin leads to better generalization. - -### Kernel Functions: -- **Linear Kernel**: - Used when the data is linearly separable. The decision boundary is a straight line (or hyperplane). - - $$K(x, y) = x \cdot y$$ - -- **Polynomial Kernel**: - Creates a non-linear decision boundary by raising the dot product of input vectors to a specified degree. - - $$K(x, y) = (x \cdot y + c)^d$$ - -- **Radial Basis Function (RBF)**: - A popular kernel for non-linearly separable data, mapping data points into higher-dimensional space. - - $$K(x, y) = \exp(-\gamma ||x - y||^2)$$ - -### Time Complexity: -- **Training Time Complexity: $O(n^2)$ to $O(n^3)$** - Training an SVM can be computationally expensive, especially for large datasets, due to the quadratic or cubic time complexity with respect to the number of samples (n). - -### Space Complexity: -- **Space Complexity: $O(n)$** - The space complexity depends on the number of support vectors, which are usually a subset of the data points. - -### Example: -Consider a dataset of people’s heights and weights to predict whether they are athletes or not: - -- Dataset: - ``` - | Height (cm) | Weight (kg) | Athlete | - |-------------|-------------|---------| - | 170 | 70 | Yes | - | 160 | 60 | No | - | 180 | 85 | Yes | - | 155 | 55 | No | - ``` - -Step-by-Step Execution: - -1. **Choose the kernel**: - Select the appropriate kernel (e.g., linear or RBF) based on the data's distribution. - -2. **Maximize the margin**: - SVM computes the hyperplane and support vectors, ensuring the widest possible margin between the classes (Athlete/Not Athlete). - -### Python Implementation: -Here is a basic implementation of SVM in Python using **scikit-learn**: - -```python -from sklearn import datasets -from sklearn.svm import SVC -import matplotlib.pyplot as plt - -# Load dataset -iris = datasets.load_iris() -X, y = iris.data[:, :2], iris.target # Using only two features for simplicity - -# Create SVM classifier -clf = SVC(kernel='linear') - -# Train model -clf.fit(X, y) - -``` - -### Summary: -The **Support Vector Machine (SVM)** is a robust and versatile algorithm, particularly well-suited for classification tasks with high-dimensional data. Its ability to maximize margins and its use of kernel functions make it a powerful tool, though it can be computationally intensive for large datasets. Careful selection of kernels and regularization parameters is key to achieving good results. diff --git a/docs/machine-learning/t-SNE_Dimensionality_Reduction.md b/docs/machine-learning/t-SNE_Dimensionality_Reduction.md deleted file mode 100644 index dcfa28858..000000000 --- a/docs/machine-learning/t-SNE_Dimensionality_Reduction.md +++ /dev/null @@ -1,154 +0,0 @@ ---- - -id: tsne-dimensionality-reduction -title: t-SNE Dimensionality Reduction Algorithm -sidebar_label: t-SNE -description: "This post explores t-SNE (t-distributed Stochastic Neighbor Embedding), a popular dimensionality reduction technique used to visualize high-dimensional data in a low-dimensional space." -tags: [dimensionality reduction, data visualization, machine learning, tsne, high-dimensional data] - ---- - -### Definition: -**t-SNE (t-distributed Stochastic Neighbor Embedding)** is a non-linear dimensionality reduction technique commonly used for the visualization of high-dimensional datasets. Unlike linear techniques like PCA, t-SNE excels at preserving the local structure of data, making it highly effective for visualizing clusters or groups in lower dimensions (typically 2D or 3D). - -### Characteristics: -- **Non-linear Mapping**: - t-SNE captures non-linear relationships in high-dimensional data, making it suitable for datasets where linear techniques like PCA fall short. - -- **Emphasis on Local Structure**: - t-SNE preserves the local structure of the data by ensuring that similar data points in the high-dimensional space remain close together in the lower-dimensional representation. - -- **Perplexity as a Key Parameter**: - t-SNE uses a parameter called *perplexity*, which influences the balance between local and global aspects of the data. Higher perplexity values tend to focus on global structure, while lower values emphasize local details. - -### Components of t-SNE: -1. **High-Dimensional Pairwise Similarities**: - t-SNE starts by calculating the pairwise similarities between all points in the high-dimensional space using a probability distribution (Gaussian distribution). - -2. **Low-Dimensional Mapping**: - The algorithm then aims to find a low-dimensional representation of the data by minimizing the difference (KL divergence) between the high-dimensional and low-dimensional distributions. In the lower-dimensional space, it uses a *t-distribution* to handle the long tails, ensuring that distant points don’t get overly compressed. - -3. **Gradient Descent Optimization**: - The optimization process uses gradient descent to iteratively adjust the low-dimensional embedding, ensuring that similar points in the high-dimensional space remain close together while dissimilar points are further apart. - -### Steps Involved: -1. **High-Dimensional Input Data**: - The algorithm accepts data in high-dimensional space (e.g., a dataset with hundreds of features). - -2. **Pairwise Similarity Calculation**: - It computes the pairwise similarities between all points in the high-dimensional space using a Gaussian distribution. - -3. **Low-Dimensional Embedding Initialization**: - The low-dimensional space (usually 2D or 3D) is initialized, and points are randomly positioned. - -4. **KL Divergence Minimization**: - t-SNE minimizes the Kullback-Leibler (KL) divergence between the distributions of pairwise similarities in the high- and low-dimensional spaces. - -5. **Iteration & Optimization**: - Using gradient descent, the algorithm iteratively updates the positions of points in the low-dimensional space to better represent the structure of the high-dimensional data. - -6. **Final Low-Dimensional Representation**: - The final output is a low-dimensional mapping that preserves the local relationships of the data, which can be used for visualization. - -### Key Concepts: -- **Perplexity**: - Perplexity controls the balance between the attention t-SNE gives to local versus global structure. It's a measure of how many neighbors each point should consider when calculating pairwise similarities. - -- **KL Divergence**: - A measure of the difference between two probability distributions. In t-SNE, KL divergence is used to minimize the difference between the high-dimensional and low-dimensional representations of the data. - -- **Learning Rate**: - The learning rate controls the step size during gradient descent optimization. Too high a value may result in poor convergence, while too low a value may cause slow optimization. - -- **Early Exaggeration**: - In the early stages of the t-SNE optimization, distances between points are exaggerated to help the algorithm find a meaningful structure before settling into the final low-dimensional representation. - -### t-SNE Algorithm Architecture: -1. **Input Layer**: - The input data consists of high-dimensional points (e.g., each point representing an observation with hundreds of features). - -2. **Pairwise Similarity Layer**: - For each point, t-SNE calculates pairwise similarities to other points using a Gaussian distribution in the high-dimensional space. - -3. **Low-Dimensional Embedding Layer**: - Points are placed randomly in the low-dimensional space (usually 2D or 3D), and the layout is iteratively adjusted using gradient descent. - -4. **Optimization Layer**: - The positions of points in the low-dimensional space are updated to minimize the KL divergence between the high-dimensional and low-dimensional similarities. - -5. **Output Layer**: - The final low-dimensional representation, suitable for visualization, is produced, preserving the local neighborhood structure of the original data. - -### Advantages of t-SNE: -- **Visualization Power**: - t-SNE is exceptionally good at visualizing high-dimensional data, especially when the data exhibits clusters or subgroups. - -- **Captures Non-Linear Structures**: - Unlike linear methods like PCA, t-SNE captures complex, non-linear structures, which is essential for many real-world datasets. - -- **User-Friendly Parameters**: - While t-SNE has a few key parameters like perplexity and learning rate, they are relatively easy to tune and often produce meaningful results across a wide range of values. - -### Limitations of t-SNE: -- **Computational Complexity**: - t-SNE can be computationally expensive for very large datasets due to the pairwise similarity calculations and iterative optimization. - -- **No Preserved Global Structure**: - While t-SNE does a great job preserving local structure, it often sacrifices global relationships in the data, making it less ideal for tasks where global geometry is important. - -- **Sensitive to Parameter Tuning**: - The choice of perplexity and learning rate can significantly impact the resulting embedding, requiring careful experimentation. - -### Use Cases: -1. **Data Visualization**: - t-SNE is widely used for visualizing high-dimensional datasets in machine learning, helping to identify clusters or patterns in the data. - -2. **Exploratory Data Analysis**: - t-SNE is effective for uncovering hidden structures, making it a valuable tool for exploratory data analysis before more formal modeling. - -3. **Dimensionality Reduction for Feature Engineering**: - t-SNE can be used as a pre-processing step to reduce the number of features in a dataset while preserving important relationships. - -4. **Biological Data**: - t-SNE is commonly applied to gene expression and single-cell RNA sequencing data to explore the relationships between different cell types. - -### Example of t-SNE in Python: -```python -import matplotlib.pyplot as plt -from sklearn.manifold import TSNE -from sklearn.datasets import load_digits -from sklearn.preprocessing import StandardScaler - -# Load dataset -digits = load_digits() -X = digits.data -y = digits.target - -# Standardize the features -X_scaled = StandardScaler().fit_transform(X) - -# Perform t-SNE -tsne = TSNE(n_components=2, perplexity=30, random_state=42) -X_tsne = tsne.fit_transform(X_scaled) - -# Plot the result -plt.figure(figsize=(8, 6)) -plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap='jet', s=30) -plt.colorbar() -plt.title("t-SNE Visualization of Digits Dataset") -plt.show() -``` - -### Time and Space Complexity: -- **Time Complexity**: - The time complexity of t-SNE is approximately $O(n^2)$, where $n$ is the number of data points. This makes it slow for large datasets. - -- **Space Complexity**: - The space complexity of t-SNE is also $O(n^2)$ due to the storage requirements for pairwise similarities. - -### Summary & Applications: -- **t-SNE** is a powerful tool for visualizing high-dimensional data in a lower-dimensional space, making it widely used in tasks involving clustering, pattern recognition, and exploratory data analysis. It is particularly popular in fields like genomics, image processing, and text mining. - -- **Applications**: - t-SNE is used in various industries for data visualization, including finance, healthcare, e-commerce, and bioinformatics, enabling professionals to gain insights into complex datasets. - diff --git a/docs/machine-learning/unsupervised_learning_algo.md b/docs/machine-learning/unsupervised_learning_algo.md deleted file mode 100644 index 6da62152c..000000000 --- a/docs/machine-learning/unsupervised_learning_algo.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: unsupervised-learning-algorithms -title: Unsupervised Learning Algorithms -sidebar_label: Unsupervised Learning -description: "In this post, we’ll explore the concept of unsupervised learning, a fundamental approach in machine learning where models are trained using unlabeled data." -tags: [machine learning, algorithms, unsupervised learning] ---- - -### Definition: -**Unsupervised Learning** is a type of machine learning where an algorithm learns from unlabeled data to identify patterns, groupings, or structures within the data. Unlike supervised learning, there are no predefined labels or outcomes to guide the learning process. - - - -### Characteristics: -- **Unlabeled Data**: - Unsupervised learning requires a dataset that does not include output labels; the algorithm must discover the inherent structure of the data on its own. - -- **Pattern Recognition**: - The primary goal is to uncover hidden patterns or groupings in the data without prior knowledge of what those patterns may be. - -- **Exploratory Analysis**: - Often used for exploratory data analysis to understand the underlying distribution and relationships in data. - -### Types of Unsupervised Learning Algorithms: - -1. **Clustering Algorithms**: - Used to group similar data points together. Examples include: - - **K-Means Clustering**: Partitions data into K clusters based on feature similarity. - - **Hierarchical Clustering**: Builds a hierarchy of clusters using either agglomerative or divisive approaches. - - **DBSCAN (Density-Based Spatial Clustering of Applications with Noise)**: Groups points that are closely packed together while marking outliers. - -2. **Dimensionality Reduction Algorithms**: - Used to reduce the number of features in a dataset while preserving its essential structure. Examples include: - - **Principal Component Analysis (PCA)**: Transforms data into a lower-dimensional space while retaining variance. - - **t-SNE (t-distributed Stochastic Neighbor Embedding)**: A technique for visualizing high-dimensional data in two or three dimensions. - -3. **Association Rule Learning**: - A method for discovering interesting relations between variables in large databases. An example is: - - **Apriori Algorithm**: Used for mining frequent itemsets and relevant association rules. - - - -### Steps Involved: -1. **Input the Data**: - The algorithm receives unlabeled training data consisting of features without corresponding target labels. - -2. **Preprocess the Data**: - Data cleaning and preprocessing steps may include handling missing values, normalizing or scaling features, and encoding categorical variables. - -3. **Select an Algorithm**: - Choose an appropriate unsupervised learning algorithm based on the problem type (clustering, dimensionality reduction, etc.). - -4. **Fit the Model**: - Apply the chosen algorithm to the dataset to identify patterns or groupings. - -5. **Evaluate Results**: - Use metrics such as silhouette score for clustering or explained variance for dimensionality reduction to assess how well the model performs. - -6. **Interpret Findings**: - Analyze the results to draw insights or make decisions based on identified patterns. - - - -### Problem Statement: -Given an unlabeled dataset with multiple features, the objective is to identify patterns, group similar observations, or reduce dimensionality to facilitate further analysis. - -### Key Concepts: -- **Clustering**: - The process of grouping a set of objects in such a way that objects in the same group (or cluster) are more similar than those in other groups. - -- **Dimensionality Reduction**: - Techniques used to reduce the number of input variables in a dataset while preserving important information. - -- **Association Rules**: - Rules that describe how items are associated with each other in transactional datasets. - - - -### Split Criteria: -Unsupervised learning algorithms typically split data based on inherent structures or distances between points rather than minimizing prediction error. - -### Time Complexity: -- **Training Complexity**: - Varies by algorithm; can range from linear time complexity for simple clustering methods to polynomial time complexity for more complex algorithms. - -- **Prediction Complexity**: -Also varies by algorithm; some algorithms allow for faster predictions after training (e.g., K-Means can be efficient during prediction). - -### Space Complexity: -- **Space Complexity**: -Depends on how much information about the training set needs to be stored (e.g., clustering algorithms may require more space than dimensionality reduction techniques). - -### Example: -Consider a scenario where we want to segment customers based on purchasing behavior without labeled outcomes. - -**Dataset Example:** - -| Customer ID | Age | Annual Income | Spending Score | -|-------------|-----|---------------|----------------| -| 1 | 25 | 50K | 39 | -| 2 | 30 | 60K | 81 | -| 3 | 22 | 45K | 6 | -| 4 | 35 | 70K | 77 | - -Step-by-Step Execution: - -1. **Input Data**: - The model receives training data with features (age, income, spending score). - -2. **Preprocess Data**: - Handle any missing values and scale features if necessary. - -3. **Select Algorithm**: - Choose K-Means for clustering customers based on their spending behavior. - -4. **Fit Model**: - Apply K-Means to group customers into clusters based on their features. - -5. **Evaluate Performance**: - Use silhouette score to evaluate how well-defined the clusters are. - -6. **Interpret Findings**: - Analyze customer segments to tailor marketing strategies accordingly. - - - -### Python Implementation: -Here’s a basic implementation of K-Means clustering using **scikit-learn**: - -```python -from sklearn.cluster import KMeans -import pandas as pd -import matplotlib.pyplot as plt - -# Sample dataset -data = { - 'Age': [25, 30, 22, 35], - 'Annual Income': [50000, 60000, 45000, 70000], - 'Spending Score': [39, 81, 6, 77] -} - -# Convert to DataFrame -df = pd.DataFrame(data) - -# Create KMeans model -kmeans = KMeans(n_clusters=2, random_state=42) - -# Fit model -kmeans.fit(df) - -# Predict cluster labels -labels = kmeans.predict(df) - -# Visualize results -plt.scatter(df['Annual Income'], df['Spending Score'], c=labels) -plt.scatter(kmeans.cluster_centers_[:, 1], kmeans.cluster_centers_[:, 2], s=300, c='red', label='Centroids') -plt.title('Customer Segmentation using K-Means') -plt.xlabel('Annual Income') -plt.ylabel('Spending Score') -plt.legend() -plt.show() -``` - diff --git a/docs/programming-fundamentals/Arrays.md b/docs/programming-fundamentals/Arrays.md deleted file mode 100644 index 8e4f08e32..000000000 --- a/docs/programming-fundamentals/Arrays.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -id: Arrays -title: Introduction to Arrays fundamentals -sidebar_label: Arrays -sidebar_position: 1 -description: "Information About Arrays in progamming" -tags: [arrays,fundamentals] ---- - - -# Arrays in C - -## What is an Array? -An array is a collection of elements of the same type, stored in contiguous memory locations. It allows you to store multiple values in a single variable, making it easier to manage and access data efficiently. - -## Characteristics of Arrays -- **Homogeneous**: All elements in an array must be of the same data type. -- **Fixed Size**: The size of an array is defined at the time of declaration and cannot be changed during runtime. -- **Contiguous Memory**: The elements of an array are stored in consecutive memory locations. - -## Declaration of Arrays -To declare an array in C, you specify the data type followed by the array name and size in square brackets. - -### Syntax: -```c -data_type array_name[array_size]; -``` -### Example: -```C -int numbers[5]; // Declaration of an integer array of size 5 -``` - -## Initialization of Arrays -You can initialize an array at the time of declaration using curly braces. - -### Syntax: -```C -data_type array_name[array_size] = {value1, value2, ..., valueN}; -``` - -### Example: -```C -int numbers[5] = {1, 2, 3, 4, 5}; // Initialization with values -``` -If the size is omitted, the compiler counts the number of initializers: - -```C -int numbers[] = {1, 2, 3, 4, 5}; // Compiler determines the size (5 in this case) -``` - -## Accessing Array Elements -Array elements can be accessed using the index, which starts from 0. - -### Syntax: -```C -array_name[index]; -``` - -### Example: -```C -int firstElement = numbers[0]; // Accessing the first element (1) -``` - -## Modifying Array Elements -You can modify an element of the array using its index. - -### Example: -```C -numbers[0] = 10; // Changing the first element from 1 to 10 -``` - -## Multidimensional Arrays -C also supports multidimensional arrays, such as two-dimensional arrays (like matrices). - -### Declaration: -```C -data_type array_name[row_size][column_size]; -``` - -#### Example: -```C -int matrix[3][3]; // Declaration of a 3x3 integer matrix -``` - -### Initialization: -```C -int matrix[3][3] = { - {1, 2, 3}, - {4, 5, 6}, - {7, 8, 9} -}; // Initialization of a 3x3 matrix -``` - -### Accessing Elements: -```C -int element = matrix[1][2]; // Accessing the element in the second row and third column (6) -``` - -## Common Operations on Arrays -1. Traversing an Array -You can iterate through an array using a loop to access or modify each element. - -``` -for (int i = 0; i < 5; i++) { - printf("%d ", numbers[i]); // Prints each element -} -``` - -2. Searching an Array -You can search for an element using linear or binary search. - -Linear Search Example: -```C -int search(int arr[], int size, int key) { - for (int i = 0; i < size; i++) { - if (arr[i] == key) { - return i; // Return the index if found - } - } - return -1; // Return -1 if not found -} -``` - -3. Sorting an Array -You can sort an array using various algorithms like bubble sort, selection sort, or quicksort. - -Bubble Sort Example: -```C -void bubbleSort(int arr[], int size) { - for (int i = 0; i < size - 1; i++) { - for (int j = 0; j < size - i - 1; j++) { - if (arr[j] > arr[j + 1]) { - // Swap arr[j] and arr[j+1] - int temp = arr[j]; - arr[j] = arr[j + 1]; - arr[j + 1] = temp; - } - } - } -} -``` - -## Summary -- An array is a collection of elements of the same type stored in contiguous memory locations. -- Arrays can be one-dimensional or multi-dimensional. -- Elements can be accessed and modified using their index. -- Common operations on arrays include traversing, searching, and sorting. diff --git a/docs/programming-fundamentals/Conditionals.md b/docs/programming-fundamentals/Conditionals.md deleted file mode 100644 index 00be5153d..000000000 --- a/docs/programming-fundamentals/Conditionals.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -id: Conditionals -title: Introduction to conditinols fundamentals -sidebar_label: Conditionals -sidebar_position: 2 -description: "Information About conditionals in progamming" -tags: [conditionals,fundamentals] ---- - - -# Conditionals in C - -## What are Conditionals? -Conditionals in C allow you to execute different parts of your code based on certain conditions. They help control the flow of the program by making decisions. - -## Types of Conditional Statements - -### 1. `if` Statement -The `if` statement executes a block of code if a specified condition is true. - -#### Syntax: -```c -if (condition) { - // code to be executed if condition is true -} -``` - -### Example: -```C -int num = 10; -if (num > 0) { - printf("Number is positive.\n"); -} -``` - -### 2. if-else Statement -The if-else statement executes one block of code if the condition is true and another block if the condition is false. - -### Syntax: -```C -if (condition) { - // code to be executed if condition is true -} else { - // code to be executed if condition is false -} -``` - -### Example: -```C -int num = -5; -if (num > 0) { - printf("Number is positive.\n"); -} else { - printf("Number is non-positive.\n"); -} -``` - -### 3. else if Statement -You can chain multiple conditions using else if to check multiple conditions in sequence. - -### Syntax: -```C -if (condition1) { - // code for condition1 -} else if (condition2) { - // code for condition2 -} else { - // code if none of the above conditions are true -} -``` - -### Example: -```C -int num = 0; -if (num > 0) { - printf("Number is positive.\n"); -} else if (num < 0) { - printf("Number is negative.\n"); -} else { - printf("Number is zero.\n"); -} -``` - -### 4. switch Statement -The switch statement is used to select one of many blocks of code to be executed. It is often used as a more readable alternative to a series of if-else statements. - -### Syntax: -```C -switch (expression) { - case constant1: - // code to be executed if expression equals constant1 - break; - case constant2: - // code to be executed if expression equals constant2 - break; - default: - // code to be executed if expression doesn't match any constant -} -``` - -### Example: -```C -int day = 3; -switch (day) { - case 1: - printf("Monday\n"); - break; - case 2: - printf("Tuesday\n"); - break; - case 3: - printf("Wednesday\n"); - break; - default: - printf("Not a valid day\n"); -} -``` - -## Conditional Operators -C also provides several operators that can be used to form conditions. - -### 1. Relational Operators -- == : Equal to -- != : Not equal to -- > : Greater than -- < : Less than -- >= : Greater than or equal to -- <= : Less than or equal to - -### 2. Logical Operators -- && : Logical AND -- || : Logical OR -- ! : Logical NOT - -### Example: -```C -int a = 5, b = 10; -if (a < b && a > 0) { - printf("a is positive and less than b.\n"); -} -``` - -Summary -- Conditionals allow you to control the flow of your program based on certain conditions. -- The primary conditional statements are if, if-else, else if, and switch. -- Relational and logical operators are used to create complex conditions. diff --git a/docs/programming-fundamentals/Data_Structures.md b/docs/programming-fundamentals/Data_Structures.md deleted file mode 100644 index 953b8b58a..000000000 --- a/docs/programming-fundamentals/Data_Structures.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -id: Data Structures -title: Introduction to Data Structures fundamentals -sidebar_label: Data Structures -sidebar_position: 3 -description: "Information About Data structures in progamming" -tags: [Data structures,fundamentals] ---- - - -# Data Structures in C - -## What are Data Structures? -Data structures are specialized formats for organizing, processing, and storing data. They provide a way to manage large amounts of data efficiently for various operations such as searching, inserting, updating, and deleting. - -## Types of Data Structures - -### 1. Primitive Data Structures -Primitive data structures are the basic building blocks of data handling in C. They include: - -- **Integers (`int`)**: Used to store whole numbers. -- **Floats (`float`)**: Used to store single-precision floating-point numbers. -- **Doubles (`double`)**: Used to store double-precision floating-point numbers. -- **Characters (`char`)**: Used to store single characters. -- **Boolean (`_Bool`)**: Used to store true/false values. - -### 2. Non-Primitive Data Structures -Non-primitive data structures are more complex structures built from primitive data types. They include: - -#### a. Arrays -An array is a collection of elements of the same type, stored in contiguous memory locations. - -- **Declaration**: - ```c - int arr[10]; // Array of integers - ``` - -- **Initialization**: - ```c - int arr[5] = {1, 2, 3, 4, 5}; - ``` - -- **Accessing Elements**: - ```c - int first = arr[0]; // Accessing the first element - ``` - -#### b. Structures -Structures allow you to group different data types under a single name. - -- **Declaration**: - ```c - struct Person { - char name[50]; - int age; - }; - ``` - -- **Initialization**: - ```c - struct Person person1 = {"Alice", 30}; - ``` - -- **Accessing Members**: - ```c - printf("%s is %d years old.", person1.name, person1.age); - ``` - -#### c. Unions -Unions allow you to store different data types in the same memory location. Only one member can hold a value at any given time. - -- **Declaration**: - ```c - union Data { - int intVal; - float floatVal; - char charVal; - }; - ``` - -- **Initialization**: - ```c - union Data data; - data.intVal = 5; // Only intVal holds a value at this moment - ``` - -#### d. Enumerations -An enumeration is a user-defined data type consisting of a set of named integer constants. - -- **Declaration**: - ```c - enum Day { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; - ``` - -- **Using Enumerations**: - ```c - enum Day today = Friday; - ``` - -### 3. Abstract Data Types (ADTs) -ADTs are data structures defined by their behavior (operations) rather than their implementation. - -#### a. Linked Lists -A linked list is a collection of nodes where each node contains data and a pointer to the next node. - -- **Node Structure**: - ```c - struct Node { - int data; - struct Node* next; - }; - ``` - -- **Example of Inserting a Node**: - ```c - void insert(struct Node** head, int newData) { - struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); - newNode->data = newData; - newNode->next = (*head); - (*head) = newNode; - } - ``` - -#### b. Stacks -A stack is a linear data structure that follows the Last In First Out (LIFO) principle. - -- **Operations**: - - **Push**: Add an element to the top. - - **Pop**: Remove an element from the top. - - **Peek**: Get the top element without removing it. - -#### c. Queues -A queue is a linear data structure that follows the First In First Out (FIFO) principle. - -- **Operations**: - - **Enqueue**: Add an element to the rear. - - **Dequeue**: Remove an element from the front. - -### 4. Trees -A tree is a hierarchical data structure consisting of nodes. The top node is called the root, and each node can have child nodes. - -- **Binary Tree**: Each node has at most two children. -- **Binary Search Tree (BST)**: A binary tree where the left child is less than the parent and the right child is greater. - -### 5. Graphs -A graph is a collection of nodes (vertices) connected by edges. Graphs can be directed or undirected. - -- **Representation**: - - **Adjacency Matrix**: A 2D array to represent the graph. - - **Adjacency List**: An array of lists to represent the graph. - -## Summary -- Data structures are crucial for organizing and managing data effectively. -- C provides both primitive and non-primitive data structures. -- Understanding various data structures helps optimize algorithms and enhances programming skills. diff --git a/docs/programming-fundamentals/Loops.md b/docs/programming-fundamentals/Loops.md deleted file mode 100644 index 1bc300d69..000000000 --- a/docs/programming-fundamentals/Loops.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -id: Loops -title: Introduction to loops fundamentals -sidebar_label: Loops -sidebar_position: 5 -description: "Information About loops in progamming" -tags: [loops,fundamentals] ---- - -# Loops in C - -## What are Loops? -Loops in C are used to execute a block of code repeatedly until a specified condition is met. They are essential for performing repetitive tasks efficiently. - -## Types of Loops - -### 1. `for` Loop -The `for` loop is used when the number of iterations is known beforehand. It consists of three parts: initialization, condition, and increment/decrement. - -#### Syntax: -```c -for (initialization; condition; increment/decrement) { - // code to be executed -} -``` - -#### Example: -```C -for (int i = 0; i < 5; i++) { - printf("Iteration: %d\n", i); -} -``` - -### 2. while Loop -The while loop is used when the number of iterations is not known, and the loop continues until the condition is false. - -#### Syntax: -```C -while (condition) { - // code to be executed -} -``` - -#### Example: -```C -int i = 0; -while (i < 5) { - printf("Iteration: %d\n", i); - i++; -} -``` - -### 3. do-while Loop -The do-while loop is similar to the while loop, but it guarantees that the loop body will be executed at least once, as the condition is checked after the execution of the loop body. - -#### Syntax: -```C -do { - // code to be executed -} while (condition); -``` - -#### Example: -```C -int i = 0; -do { - printf("Iteration: %d\n", i); - i++; -} while (i < 5); -``` - -## Loop Control Statements -Loop control statements allow you to control the flow of the loop. - -### 1. break -The break statement is used to exit a loop prematurely. - -#### Example: -```C -for (int i = 0; i < 10; i++) { - if (i == 5) { - break; // Exit the loop when i is 5 - } - printf("%d\n", i); -} -```` - -### 2. continue -The continue statement is used to skip the current iteration of the loop and move to the next iteration. - -#### Example: -```C -for (int i = 0; i < 10; i++) { - if (i % 2 == 0) { - continue; // Skip even numbers - } - printf("%d\n", i); -} -``` - -### Nested Loops -You can use loops inside other loops, known as nested loops. This is useful for working with multi-dimensional data structures. - -#### Example: -```C -for (int i = 0; i < 3; i++) { - for (int j = 0; j < 2; j++) { - printf("i: %d, j: %d\n", i, j); - } -} -``` - -### Summary -- Loops allow you to execute a block of code repeatedly based on a condition. -- The primary types of loops are for, while, and do-while. -- Loop control statements like break and continue help manage the flow of loops. -- Nested loops can be used for working with multi-dimensional data. diff --git a/docs/programming-fundamentals/OOPS/oops-01.md b/docs/programming-fundamentals/OOPS/oops-01.md deleted file mode 100644 index f250fcd4d..000000000 --- a/docs/programming-fundamentals/OOPS/oops-01.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -id: intro-to-oops -title: Introduction to Object-Oriented Programming (OOP) -sidebar_label: Introduction to OOP -sidebar_position: 1 -description: "Object-Oriented Programming (OOP) is a programming paradigm based on the concept of objects, which can contain data and code to manipulate that data. It promotes concepts like encapsulation, inheritance, and polymorphism." -tags: [oops, object-oriented-programming] ---- - -# **Introduction to Object-Oriented Programming (OOPs)** - -Object-Oriented Programming (OOPs) is a **programming paradigm** that organizes software design around data, or objects, rather than functions and logic. It helps in breaking down complex problems into smaller, manageable units by representing real-world entities as objects. - -## **Key Concepts of OOPs** - -OOPs is built on four main pillars: -1. **Encapsulation** -2. **Abstraction** -3. **Inheritance** -4. **Polymorphism** - - -These core concepts help developers create software that is more modular, reusable, and scalable. We will explore these in detail in the following sections. - ---- - -## **Advantages of OOPs over Procedure-Oriented Programming** - -Object-oriented programming (OOP) offers several key advantages over procedural programming: - -- **Code Reusability**: OOP promotes code reusability by using objects and classes. This leads to less duplication and more efficient development, as you can create reusable components that can be leveraged in different parts of your application. - -- **Enhanced Code Organization**: OOP provides a clear and logical structure, making the code easier to understand, maintain, and debug. By organizing code into objects, related functionalities are grouped together. - -- **Support for DRY Principle**: OOP supports the DRY (Don’t Repeat Yourself) principle, encouraging the minimization of code repetition. This leads to cleaner, more maintainable code, as common functionalities are placed in a single location and reused, reducing redundancy. - -- **Faster Development**: OOP enables faster development by reusing existing code and creating modular components. This allows for quicker and more efficient application development, as developers can build upon already existing codebases. - ---- - -## **Why OOPs is Important?** - -OOPs mirrors real-world entities and their interactions, making it a natural way to structure code for many applications. This approach is widely used in designing software systems that require high levels of flexibility and extensibility, such as video games, graphical user interfaces (GUIs), and complex enterprise applications. - ---- - -The next sections will delve deeper into each of these principles and other related concepts like **Classes and Objects**, **Constructors**, **Interfaces**, and **Real-World Examples**. diff --git a/docs/programming-fundamentals/OOPS/oops-02.md b/docs/programming-fundamentals/OOPS/oops-02.md deleted file mode 100644 index 23582f43a..000000000 --- a/docs/programming-fundamentals/OOPS/oops-02.md +++ /dev/null @@ -1,161 +0,0 @@ ---- -id: classes-and-objects -title: "Classes and Objects in OOP" -sidebar_label: Classes and Objects -sidebar_position: 2 -description: "In OOP, a class is a blueprint for creating objects (instances), providing initial values for state (member variables) and implementations of behavior (member functions or methods)." -tags: [oops, classes, objects] ---- - -# **Classes and Objects in Object-Oriented Programming** - -In Object-Oriented Programming (OOP), **classes** and **objects** are fundamental concepts that help structure your code. - -## **What is a Class?** - -A **class** is a blueprint or template for creating objects. It defines a datatype by bundling data and methods that work on the data. Classes encapsulate data for the object and define methods for manipulating that data. - -### **Key Components of a Class:** -- **Attributes**: Variables that hold data for the class. -- **Methods**: Functions defined inside the class that can manipulate the attributes. - -### **Example of a Class** - -

    -C++ Code - -```cpp -class Car { -private: - string model; - int year; - -public: - // Constructor - Car(string m, int y) : model(m), year(y) {} - - // Method to display car details - void display() { - cout << "Model: " << model << ", Year: " << year << endl; - } -}; -``` -
    - -
    -Java Code - -```java -class Car { - private String model; - private int year; - - // Constructor - Car(String m, int y) { - model = m; - year = y; - } - - // Method to display car details - void display() { - System.out.println("Model: " + model + ", Year: " + year); - } -} -``` -
    - -
    -JavaScript Code - -```js -class Car { - #model; // Private field - #year; // Private field - - // Constructor - constructor(model, year) { - this.#model = model; - this.#year = year; - } - - // Method to display car details - display() { - console.log(`Model: ${this.#model}, Year: ${this.#year}`); - } -} - -const myCar = new Car("Toyota", 2020); -myCar.display(); // Output: Model: Toyota, Year: 2020 - -``` -
    - ---- - -## **What is an Object?** - -An **object** is an instance of a class. When you create an object, you create a specific instance of a class with its own unique set of attributes. Objects interact with one another and can have their own state and behavior. - -### **Creating Objects** - -
    -C++ Code - -```cpp -int main() { - Car myCar("Toyota", 2020); - myCar.display(); // Output: Model: Toyota, Year: 2020 - return 0; -} -``` -
    - -
    -Java Code - -```java -public class Main { - public static void main(String[] args) { - Car myCar = new Car("Toyota", 2020); - myCar.display(); // Output: Model: Toyota, Year: 2020 - } -} -``` -
    - -
    -JavaScript Code - -```js -class Car { - constructor(model, year) { - this.model = model; - this.year = year; - } - display() { - console.log(`Model: ${this.model}, Year: ${this.year}`); - } -} -const myCar = new Car("Toyota", 2020); -myCar.display(); // Output: Model: Toyota, Year: 2020 -``` -
    - ---- - -## **Key Differences Between Classes and Objects:** -- **Definition**: A class is a blueprint; an object is an instance of that blueprint. -- **Memory**: Class is a logical entity; an object is a physical entity in memory. -- **Instantiation**: Classes need to be instantiated to create objects. - - -*Diagram illustrating the relationship between classes and objects in OOP.* - ---- - -## **Conclusion** - -Classes and objects are the cornerstones of OOP, enabling developers to create modular, reusable, and maintainable code. Understanding these concepts is essential for mastering object-oriented design and programming. - ---- - diff --git a/docs/programming-fundamentals/OOPS/oops-03.md b/docs/programming-fundamentals/OOPS/oops-03.md deleted file mode 100644 index 6adae1c0b..000000000 --- a/docs/programming-fundamentals/OOPS/oops-03.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -id: constructors-and-destructors -title: Constructors and Destructors in OOP -sidebar_label: Constructors and Destructors -sidebar_position: 3 -description: "Constructors and destructors are special methods in OOP that handle object initialization and cleanup. Constructors set up the initial state, while destructors handle object destruction and resource management." -tags: [oops, constructors, destructors] ---- - -# **Constructors and Destructors** - -Constructors and destructors are **special member functions** in object-oriented programming (OOP) that are automatically called when an object is created or destroyed, respectively. They are essential for initializing and cleaning up resources used by objects. - ---- - -## **1. What is a Constructor?** - -A **constructor** is a special function that initializes an object when it is created. It has the same name as the class and does not have a return type. Constructors can take parameters to initialize object attributes. - -### **Types of Constructors** -- **Default Constructor**: A constructor that does not take any parameters. -- **Parameterized Constructor**: A constructor that takes parameters to set initial values for the object. - -### **Example of Constructors** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Rectangle { -private: - int width, height; - -public: - // Default Constructor - Rectangle() { - width = 0; - height = 0; - } - - // Parameterized Constructor - Rectangle(int w, int h) { - width = w; - height = h; - } - - void display() { - cout << "Width: " << width << ", Height: " << height << endl; - } -}; - -int main() { - Rectangle rect1; // Default constructor - Rectangle rect2(10, 5); // Parameterized constructor - - rect1.display(); - rect2.display(); - return 0; -} -``` -
    - -
    -Java Code - -```java -class Rectangle { - private int width, height; - - // Default Constructor - Rectangle() { - width = 0; - height = 0; - } - - // Parameterized Constructor - Rectangle(int w, int h) { - width = w; - height = h; - } - - void display() { - System.out.println("Width: " + width + ", Height: " + height); - } -} - -public class Main { - public static void main(String[] args) { - Rectangle rect1 = new Rectangle(); // Default constructor - Rectangle rect2 = new Rectangle(10, 5); // Parameterized constructor - - rect1.display(); - rect2.display(); - } -} -``` -
    - -
    -JavaScript Code - -```js -class Rectangle { - // Default Constructor - constructor(width = 0, height = 0) { - this.width = width; - this.height = height; - } - - // Method to display width and height - display() { - console.log(`Width: ${this.width}, Height: ${this.height}`); - } -} - -// Main code to demonstrate constructors -const rect1 = new Rectangle(); // Default constructor -const rect2 = new Rectangle(10, 5); // Parameterized constructor - -rect1.display(); // Output: Width: 0, Height: 0 -rect2.display(); // Output: Width: 10, Height: 5 - -``` -
    - ---- - -## **2. What is a Destructor?** - -A **destructor** is a special function that is called when an object is destroyed. It has the same name as the class but is preceded by a tilde (~) in C++. Destructors are used to release resources allocated to the object, such as memory or file handles. - -### **Example of Destructors** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Rectangle { -private: - int width, height; - -public: - Rectangle(int w, int h) : width(w), height(h) { - cout << "Constructor called!" << endl; - } - - ~Rectangle() { - cout << "Destructor called!" << endl; - } - - void display() { - cout << "Width: " << width << ", Height: " << height << endl; - } -}; - -int main() { - Rectangle rect(10, 5); - rect.display(); - return 0; // Destructor is called automatically here -} -``` -
    - -
    -Java Code - -```java -class Rectangle { - private int width, height; - - Rectangle(int w, int h) { - width = w; - height = h; - System.out.println("Constructor called!"); - } - - // Finalize method acts as a destructor in Java - protected void finalize() { - System.out.println("Destructor called!"); - } - - void display() { - System.out.println("Width: " + width + ", Height: " + height); - } -} - -public class Main { - public static void main(String[] args) { - Rectangle rect = new Rectangle(10, 5); - rect.display(); - rect = null; // Request garbage collection - System.gc(); // Calling garbage collector - } -} -``` -
    - -
    -JavaScript Code - -```js -// In JavaScript, there is no explicit destructor like in Java or C++. Instead, memory management is handled -// automatically by the garbage collector. However, you can mimic the behavior of a destructor using the -// finalize method available via the FinalizationRegistry, which lets you run cleanup code when an object -// is garbage collected. - -class Rectangle { - #width; // Private field - #height; // Private field - - constructor(width, height) { - this.#width = width; - this.#height = height; - console.log("Constructor called!"); - } - - // Method to display width and height - display() { - console.log(`Width: ${this.#width}, Height: ${this.#height}`); - } -} - -// Create a FinalizationRegistry to simulate destructor -const registry = new FinalizationRegistry(() => { - console.log("Destructor called!"); -}); - -// Main code -let rect = new Rectangle(10, 5); -rect.display(); - -// Register the object for cleanup when it's garbage collected -registry.register(rect, "Rectangle Instance"); - -// Simulate object being nullified and garbage collected -rect = null; -globalThis.gc?.(); // This is optional; the garbage collector runs automatically - -``` -
    - ---- - -## **3. Importance of Constructors and Destructors** - -- **Resource Management**: Constructors are used to allocate resources, while destructors are used to release them. This ensures that resources are properly managed and prevents memory leaks. -- **Initialization**: Constructors allow for setting initial values for object attributes, providing a clear and consistent way to create objects. - ---- \ No newline at end of file diff --git a/docs/programming-fundamentals/OOPS/oops-04.md b/docs/programming-fundamentals/OOPS/oops-04.md deleted file mode 100644 index 50af7daa9..000000000 --- a/docs/programming-fundamentals/OOPS/oops-04.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -id: interface-vs-abstract-class -title: Interface vs Abstract Class in OOP -sidebar_label: Interface vs Abstract Class -sidebar_position: 5 -description: "An interface defines a contract for behavior, whereas an abstract class provides partial implementation. Both are used to achieve abstraction but differ in their design and use cases." -tags: [oops, interface, abstract-class] ---- - -# **Interface vs Abstract Classes** - -In object-oriented programming, both **interfaces** and **abstract classes** are used to achieve abstraction, allowing you to define methods that must be implemented by derived classes. However, they serve different purposes and have distinct characteristics. - ---- - -## **1. What is an Abstract Class?** - -An **abstract class** is a class that cannot be instantiated on its own and is meant to be subclassed. It can contain both abstract methods (without implementation) and concrete methods (with implementation). Abstract classes are used to provide a common base for derived classes. - -### **Key Features of Abstract Classes** -- Can have both abstract and concrete methods. -- Can have member variables. -- Can provide a default implementation for some methods. - -### **Example of Abstract Class** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Animal { -public: - // Abstract method - virtual void sound() = 0; // Pure virtual function - - void sleep() { - cout << "Sleeping..." << endl; - } -}; - -class Dog : public Animal { -public: - void sound() { - cout << "Woof!" << endl; - } -}; - -int main() { - Dog dog; - dog.sound(); // Calls the sound method - dog.sleep(); // Calls the sleep method from the Animal class - return 0; -} -``` -
    - -
    -Java Code - -```java -abstract class Animal { - // Abstract method - abstract void sound(); - - void sleep() { - System.out.println("Sleeping..."); - } -} - -class Dog extends Animal { - void sound() { - System.out.println("Woof!"); - } -} - -public class Main { - public static void main(String[] args) { - Dog dog = new Dog(); - dog.sound(); // Calls the sound method - dog.sleep(); // Calls the sleep method from the Animal class - } -} -``` -
    - -
    -JavaScript Code - -```js -//JavaScript doesn't have a built-in concept of abstract classes like in Java or C++, but you can mimic this -//behavior using a combination of class inheritance and throwing errors when an abstract method is not implemented. - -class Animal { - // Abstract method - sound() { - throw new Error("Abstract method 'sound' must be implemented by subclass"); - } - - // Concrete method - sleep() { - console.log("Sleeping..."); - } -} - -class Dog extends Animal { - // Implement the abstract method - sound() { - console.log("Woof!"); - } -} - -// Main code -const dog = new Dog(); -dog.sound(); // Calls the sound method -dog.sleep(); // Calls the sleep method from the Animal class - -``` -
    - ---- -## **2. What is an Interface?** - -An **interface** is a contract that defines a set of methods that implementing classes must provide. It cannot contain any implementation itself (in languages like Java) and is used to achieve multiple inheritance. - -### **Key Features of Interfaces** -- Can only contain abstract methods (Java 8 and above allows default methods). -- Cannot have member variables (only constants). -- Supports multiple inheritance. - -### **Example of Interface** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class IAnimal { -public: - virtual void sound() = 0; // Pure virtual function -}; - -class Cat : public IAnimal { -public: - void sound() { - cout << "Meow!" << endl; - } -}; - -int main() { - Cat cat; - cat.sound(); // Calls the sound method - return 0; -} -``` -
    - -
    -Java Code - -```java -interface IAnimal { - void sound(); // Abstract method -} - -class Cat implements IAnimal { - public void sound() { - System.out.println("Meow!"); - } -} - -public class Main { - public static void main(String[] args) { - Cat cat = new Cat(); - cat.sound(); // Calls the sound method - } -} -``` -
    - -
    -JavaScript Code - -```js -// JavaScript does not have a built-in concept of interfaces like Java or C++, but you can simulate -// interfaces by defining a structure that classes must follow. - -class IAnimal { - sound() { - throw new Error("Method 'sound()' must be implemented"); - } -} - -class Cat extends IAnimal { - // Implementing the sound method - sound() { - console.log("Meow!"); - } -} - -// Main code -const cat = new Cat(); -cat.sound(); // Calls the sound method - -``` -
    - - ---- - -## **3. Key Differences Between Abstract Classes and Interfaces** - -| Feature | Abstract Class | Interface | -|------------------------------|----------------------------------------|---------------------------------------------| -| **Instantiation** | Cannot be instantiated | Cannot be instantiated | -| **Method Implementation** | Can have both abstract and concrete methods | Can only have abstract methods (until Java 8) | -| **Inheritance** | Can extend only one abstract class | Can implement multiple interfaces | -| **Access Modifiers** | Can use any access modifier | All methods are public by default | -| **Member Variables** | Can have member variables | Cannot have member variables | - ---- \ No newline at end of file diff --git a/docs/programming-fundamentals/OOPS/oops-05.md b/docs/programming-fundamentals/OOPS/oops-05.md deleted file mode 100644 index 2d6896a54..000000000 --- a/docs/programming-fundamentals/OOPS/oops-05.md +++ /dev/null @@ -1,486 +0,0 @@ ---- -id: pillars-of-oops -title: "Pillars of OOP: Abstraction, Encapsulation, Inheritance, Polymorphism" -sidebar_label: Pillars of OOP -sidebar_position: 4 -description: "The four main pillars of OOP are abstraction, encapsulation, inheritance, and polymorphism. These principles provide a foundation for creating robust and reusable code in object-oriented systems." -tags: [oops, abstraction, encapsulation, inheritance, polymorphism] ---- - -# **Pillars of OOPs** - -Object-Oriented Programming (OOP) is built on four main pillars: **Abstraction**, **Encapsulation**, **Inheritance**, and **Polymorphism**. Each of these concepts plays a crucial role in creating modular, reusable, and maintainable code. - ---- - -## **1. Abstraction** - -Abstraction is the process of hiding the complex implementation details and showing only the essential features of an object. It allows developers to reduce complexity by providing a simplified interface. - -### **Key Points** -- Focuses on **what** an object does rather than **how** it does it. -- Achieved through abstract classes and interfaces. - -### **Example of Abstraction** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Shape { -public: - virtual void draw() = 0; // Pure virtual function -}; - -class Circle : public Shape { -public: - void draw() { - cout << "Drawing Circle" << endl; - } -}; - -int main() { - Circle circle; - circle.draw(); // Calls the draw method - return 0; -} -``` -
    - -
    -Java Code - -```java -abstract class Shape { - abstract void draw(); // Abstract method -} - -class Circle extends Shape { - void draw() { - System.out.println("Drawing Circle"); - } -} - -public class Main { - public static void main(String[] args) { - Circle circle = new Circle(); - circle.draw(); // Calls the draw method - } -} -``` -
    - -
    -JavaScript Code - -```js -// In JavaScript, abstract methods are not natively supported, but we can simulate abstract behavior -// by throwing an error in the base class method and forcing subclasses to implement it. -class Shape { - // Simulate an abstract method - draw() { - throw new Error("Method 'draw()' must be implemented"); - } -} - -class Circle extends Shape { - // Implementing the abstract method - draw() { - console.log("Drawing Circle"); - } -} - -// Main code -const circle = new Circle(); -circle.draw(); // Output: Drawing Circle - -``` -
    - ---- - -## **2. Encapsulation** - -Encapsulation is the bundling of data (attributes) and methods (functions) that operate on the data into a single unit called a class. It restricts direct access to some of the object's components, which is a means of preventing unintended interference and misuse. - -### **Key Points** -- Protects an object's state by restricting access to its internal data. -- Achieved using access modifiers (private, protected, public). - -### **Example of Encapsulation** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class BankAccount { -private: - double balance; // Private data member - -public: - BankAccount() : balance(0) {} // Constructor - - void deposit(double amount) { - balance += amount; - } - - void displayBalance() { - cout << "Balance: " << balance << endl; - } -}; - -int main() { - BankAccount account; - account.deposit(1000); - account.displayBalance(); // Displays the balance - return 0; -} -``` -
    - -
    -Java Code - -```java -class BankAccount { - private double balance; // Private data member - - public BankAccount() { - balance = 0; // Constructor - } - - public void deposit(double amount) { - balance += amount; - } - - public void displayBalance() { - System.out.println("Balance: " + balance); - } -} - -public class Main { - public static void main(String[] args) { - BankAccount account = new BankAccount(); - account.deposit(1000); - account.displayBalance(); // Displays the balance - } -} -``` -
    - -
    -JavaScript Code - -```js -class BankAccount { - #balance; // Private field - - constructor() { - this.#balance = 0; // Initialize balance in constructor - } - - // Method to deposit money - deposit(amount) { - this.#balance += amount; - } - - // Method to display balance - displayBalance() { - console.log(`Balance: ${this.#balance}`); - } -} - -// Main code -const account = new BankAccount(); -account.deposit(1000); -account.displayBalance(); // Output: Balance: 1000 - -``` -
    - ---- - -## **3. Inheritance** - -Inheritance is a mechanism that allows one class to inherit the properties and behaviors (methods) of another class. It promotes code reusability and establishes a hierarchical relationship between classes. - -### **Key Points** -- The class that inherits is called the **derived class** or **child class**, and the class being inherited from is called the **base class** or **parent class**. -- Supports "is-a" relationship. - -### **Example of Inheritance** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Animal { -public: - void eat() { - cout << "Eating..." << endl; - } -}; - -class Dog : public Animal { // Dog inherits from Animal -public: - void bark() { - cout << "Woof!" << endl; - } -}; - -int main() { - Dog dog; - dog.eat(); // Inherited method - dog.bark(); // Dog's own method - return 0; -} -``` -
    - -
    -Java Code - -```java -class Animal { - void eat() { - System.out.println("Eating..."); - } -} - -class Dog extends Animal { // Dog inherits from Animal - void bark() { - System.out.println("Woof!"); - } -} - -public class Main { - public static void main(String[] args) { - Dog dog = new Dog(); - dog.eat(); // Inherited method - dog.bark(); // Dog's own method - } -} -``` -
    - -
    -JavaScript Code - -```js -class Animal { - eat() { - console.log("Eating..."); - } -} - -class Dog extends Animal { // Dog inherits from Animal - bark() { - console.log("Woof!"); - } -} - -// Main code -const dog = new Dog(); -dog.eat(); // Inherited method -dog.bark(); // Dog's own method - -``` -
    - ---- - -## **4. Polymorphism** - -Polymorphism allows methods to do different things based on the object it is acting upon. It means "many forms" and can be classified into two types: **Compile-time polymorphism** and **Runtime polymorphism**. - -### **4.1 Compile-time Polymorphism** - -Also known as **method overloading**, it occurs when multiple methods in the same class have the same name but different parameters. - -#### **Example of Compile-time Polymorphism** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Math { -public: - int add(int a, int b) { - return a + b; - } - - double add(double a, double b) { - return a + b; - } -}; - -int main() { - Math math; - cout << "Int Addition: " << math.add(5, 10) << endl; // Calls int version - cout << "Double Addition: " << math.add(5.5, 10.5) << endl; // Calls double version - return 0; -} -``` -
    - -
    -Java Code - -```java -class Math { - int add(int a, int b) { - return a + b; - } - - double add(double a, double b) { - return a + b; - } -} - -public class Main { - public static void main(String[] args) { - Math math = new Math(); - System.out.println("Int Addition: " + math.add(5, 10)); // Calls int version - System.out.println("Double Addition: " + math.add(5.5, 10.5)); // Calls double version - } -} -``` -
    - -
    -JavaScript Code - -```js -// JavaScript does not support method overloading in the same way that Java does. -// Instead, you can achieve similar functionality by using a single method that checks -// the types of its arguments and performs the appropriate operation. - -class Math { - add(a, b) { - // Check types of a and b - if (typeof a === 'number' && typeof b === 'number') { - return a + b; // Addition - } else { - throw new Error("Invalid arguments: Both arguments must be numbers"); - } - } -} - -// Main code -const math = new Math(); -console.log("Int Addition: " + math.add(5, 10)); // Output: Int Addition: 15 -console.log("Double Addition: " + math.add(5.5, 10.5)); // Output: Double Addition: 16 - -``` -
    - -### **4.2 Runtime Polymorphism** - -Also known as **method overriding**, it occurs when a derived class provides a specific implementation of a method that is already defined in its base class. The decision about which method to call is made at runtime. - -#### **Example of Runtime Polymorphism** - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Animal { -public: - virtual void sound() { // Virtual method - cout << "Animal sound" << endl; - } -}; - -class Dog : public Animal { -public: - void sound() override { // Override method - cout << "Woof!" << endl; - } -}; - -int main() { - Animal* animal = new Dog(); // Pointer to base class - animal->sound(); // Calls Dog's sound method - delete animal; - return 0; -} -``` -
    - -
    -Java Code - -```java -class Animal { - void sound() { // Base class method - System.out.println("Animal sound"); - } -} - -class Dog extends Animal { - void sound() { // Override method - System.out.println("Woof!"); - } -} - -public class Main { - public static void main(String[] args) { - Animal animal = new Dog(); // Reference to base class - animal.sound(); // Calls Dog's sound method - } -} -``` -
    - -
    -JavaScript Code - -```js -class Animal { - sound() { // Base class method - console.log("Animal sound"); - } -} - -class Dog extends Animal { - sound() { // Override method - console.log("Woof!"); - } -} - -// Main code -const animal = new Dog(); // Reference to base class -animal.sound(); // Calls Dog's sound method, Output: Woof! - -``` -
    - ---- - -### Differences between Compile-time and Runtime Polymorphism - -| **Feature** | **Compile-time Polymorphism** | **Runtime Polymorphism** | -|-------------------------|---------------------------------------------|------------------------------------------| -| **Definition** | Achieved through method overloading. | Achieved through method overriding. | -| **Binding Time** | Resolved during compilation. | Resolved during runtime. | -| **Method Resolution** | The compiler determines which method to call. | The JVM determines which method to call. | -| **Performance** | Generally faster due to early binding. | Slightly slower due to late binding. | -| **Flexibility** | Less flexible as the decision is made at compile time. | More flexible as the decision is made at runtime. | -| **Example** | Overloading methods with different parameters. | Overriding a method in a derived class. | - ---- diff --git a/docs/programming-fundamentals/OOPS/oops-06.md b/docs/programming-fundamentals/OOPS/oops-06.md deleted file mode 100644 index f6c7078be..000000000 --- a/docs/programming-fundamentals/OOPS/oops-06.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: encapsulation -title: "Encapsulation in Object-Oriented Programming (OOP)" -sidebar_label: Encapsulation -sidebar_position: 2 -description: "Encapsulation is the process of bundling data and methods that operate on that data into a single unit, and restricting access to internal details." -tags: [oops, encapsulation, object-oriented programming] ---- - -# **Encapsulation in OOP** - -Encapsulation is a core concept in Object-Oriented Programming (OOP) that involves bundling the data (attributes) and methods (functions) that operate on the data into a single unit, typically a class. It restricts direct access to some of the object's components, thereby protecting the object's internal state. - ---- - -## **Key Features of Encapsulation** -- **Data hiding**: Prevents direct access to internal data members. -- Promotes **modularity** by ensuring that the internal workings of an object are hidden from the outside world. -- Achieved using **access modifiers** like `private`, `protected`, and `public`. - ---- - -### **Example of Encapsulation** - - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Employee { -private: - int salary; // Private data member - -public: - void setSalary(int s) { - salary = s; - } - - int getSalary() { - return salary; - } -}; - -int main() { - Employee emp; - emp.setSalary(5000); - cout << "Employee Salary: " << emp.getSalary() << endl; - return 0; -} -``` - -
    - -
    -JavaScript Code - -```js -class Employee { - #salary; // Private field - - // Setter method for salary - setSalary(salary) { - this.#salary = salary; - } - - // Getter method for salary - getSalary() { - return this.#salary; - } -} - -// Main code to demonstrate encapsulation -const emp = new Employee(); -emp.setSalary(5000); -console.log(`Employee Salary: ${emp.getSalary()}`); // Output: Employee Salary: 5000 - -``` - -
    - -## Advantages of Encapsulation -Increased security by restricting access to sensitive data. -Modular design allows changes to internal implementation without affecting the external interface. -Improved maintainability as the code is organized and modular. \ No newline at end of file diff --git a/docs/programming-fundamentals/OOPS/oops-07.md b/docs/programming-fundamentals/OOPS/oops-07.md deleted file mode 100644 index d0d302723..000000000 --- a/docs/programming-fundamentals/OOPS/oops-07.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -id: inheritance -title: "Inheritance in Object-Oriented Programming (OOP)" -sidebar_label: Inheritance -sidebar_position: 3 -description: "Inheritance allows one class to inherit properties and behaviors from another class, promoting code reuse and creating a hierarchy." -tags: [oops, inheritance, object-oriented programming] ---- - -# **Inheritance in OOP** - -Inheritance is a fundamental principle in Object-Oriented Programming (OOP) that allows a class to inherit properties and behaviors (methods) from another class. This helps in code reuse and establishes a parent-child relationship between classes. - ---- - -## **Key Features of Inheritance** -- Establishes a **hierarchical relationship** between classes. -- Promotes **code reuse** by allowing derived classes to use methods and attributes of the base class. -- Supports an **"is-a" relationship** between objects. - ---- - -### **Example of Inheritance** - - -
    -C++ Code - -```cpp -#include -using namespace std; - -class Vehicle { -public: - void move() { - cout << "Vehicle is moving" << endl; - } -}; - -class Car : public Vehicle { // Car inherits from Vehicle -public: - void honk() { - cout << "Car is honking" << endl; - } -}; - -int main() { - Car car; - car.move(); // Inherited method - car.honk(); // Car's own method - return 0; -} -``` -
    - -
    -JavaScript Code - -```js -class Vehicle { - move() { - console.log("Vehicle is moving"); - } -} - -class Car extends Vehicle { // Car inherits from Vehicle - honk() { - console.log("Car is honking"); - } -} - -// Main code -const car = new Car(); -car.move(); // Inherited method -car.honk(); // Car's own method - -``` -
    - -## Advantages of Inheritance -Code reuse: Common code is written in the parent class and reused by child classes. -Extensibility: New features can be added to the child class without modifying the parent class. -Polymorphism: Supports runtime polymorphism through method overriding. diff --git a/docs/programming-fundamentals/OOPS/oops-08.md b/docs/programming-fundamentals/OOPS/oops-08.md deleted file mode 100644 index 2e5e42d6a..000000000 --- a/docs/programming-fundamentals/OOPS/oops-08.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -id: polymorphism -title: "Polymorphism in Object-Oriented Programming (OOP)" -sidebar_label: Polymorphism -sidebar_position: 4 -description: "Polymorphism allows methods to take many forms, enabling flexibility in calling methods based on object type. It can be categorized into compile-time and runtime polymorphism." -tags: [oops, polymorphism, object-oriented programming] ---- - -# **Polymorphism in OOP** - -Polymorphism is a key concept in Object-Oriented Programming (OOP) that allows methods to perform different tasks based on the object that calls them. It can be categorized into two types: **compile-time polymorphism** and **runtime polymorphism**. - ---- - -## **Types of Polymorphism** - -### **1. Compile-time Polymorphism** -Also known as **method overloading**, it allows multiple methods with the same name but different parameters to coexist in the same class. - -### **Example of Compile-time Polymorphism** - - -```cpp -#include -using namespace std; - -class Math { -public: - int add(int a, int b) { - return a + b; - } - - double add(double a, double b) { - return a + b; - } -}; - -int main() { - Math math; - cout << "Int Addition: " << math.add(5, 10) << endl; - cout << "Double Addition: " << math.add(5.5, 10.5) << endl; - return 0; -} -``` - -2. Runtime Polymorphism -Also known as method overriding, it occurs when a child class provides a specific implementation of a method that is already defined in its parent class. This is determined at runtime. - -Example of Runtime Polymorphism -```cpp -#include -using namespace std; - -class Animal { -public: - virtual void sound() { - cout << "Animal sound" << endl; - } -}; - -class Dog : public Animal { -public: - void sound() override { - cout << "Woof!" << endl; - } -}; - -int main() { - Animal* animal = new Dog(); // Pointer to base class - animal->sound(); // Calls Dog's sound method - delete animal; - return 0; -} -``` -## Advantages of Polymorphism -Flexibility: The same method can perform different tasks based on the object it acts upon. -Extensibility: New behavior can be added by overriding existing methods without modifying the base class. -Dynamic method dispatch: At runtime, the correct method is chosen based on the object type. diff --git a/docs/programming-fundamentals/Variables.md b/docs/programming-fundamentals/Variables.md deleted file mode 100644 index f2303a160..000000000 --- a/docs/programming-fundamentals/Variables.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -id: Variables -title: Introduction to variables fundamentals -sidebar_label: Variables -sidebar_position: 6 -description: "Information About variables in progamming" -tags: [variables,fundamentals] ---- - -# Variables in C - -## What are Variables? -Variables in C are containers used to store data values. Each variable is given a specific type, which defines the kind of data it can hold, like integers, floating-point numbers, characters, etc. - -## Declaration and Initialization -A variable must be declared before it can be used. You can also initialize a variable with a value when you declare it. - -### Syntax: -```c -data_type variable_name; -data_type variable_name = value; -``` - -### Example: -```C -int age = 21; // Integer variable initialized with value 21 -float height = 5.9; // Float variable initialized with value 5.9 -char grade = 'A'; // Character variable initialized with value 'A' -``` - -### Multiple Declarations: -You can declare multiple variables of the same type in one line. - -```C -int a = 5, b = 10, c = 15; -``` - -### Types of Variables -C supports several data types to store various kinds of data: - -1. int: Used to store integer values (whole numbers). -int count = 10; -Range: -32,768 to 32,767 (typically 2 bytes, but depends on system). - -2. float: Used to store single-precision floating-point numbers (decimals). -float price = 19.99; -Precision: Up to 7 decimal digits. - -3. double: Used to store double-precision floating-point numbers (larger decimals). -double bigNumber = 12345.6789; -Precision: Up to 15 decimal digits. - -4. char: Used to store single characters. -char initial = 'A'; - -5. _Bool: Used to store boolean values (true/false). In C, true is represented by 1 and false by 0. -_Bool isTrue = 1; - -6. unsigned int: Used to store only non-negative integers. -unsigned int age = 25; -Range: 0 to 65,535 (for 2 bytes). - - -### Scope of Variables -The scope of a variable defines the region of the program where the variable can be accessed. - -1. Local Variables: Declared inside a function or block, and they can only be accessed within that function/block. -```C -void myFunction() { - int x = 10; // Local variable -} -``` - -2. Global Variables: Declared outside all functions, and they can be accessed by any function within the program. -```C -int globalVar = 20; - -void myFunction() { - // globalVar can be accessed here -} -``` - -3. Static Variables: Variables that maintain their value between function calls. They are initialized only once. -```C -void myFunction() { - static int counter = 0; // Static variable - counter++; -} -``` - -4. Register Variables: Stored in CPU registers instead of RAM, providing faster access. These are recommended for frequently used variables. -```C -register int fastCounter = 0; -``` - -### Storage Classes -Storage classes in C define the scope, lifetime, and visibility of variables. - -1. auto: The default storage class for local variables. -```C -auto int num = 10; -``` - -2. extern: Used to declare a global variable that is defined elsewhere. -```C -extern int globalVar; -``` - -3. static: Limits the scope of a variable to its source file or function, while preserving its value across function calls. -```C -static int count = 0; -``` - -4. register: Suggests that the compiler store the variable in a CPU register for faster access. -```C -register int i = 5; -``` - -### Variable Naming Rules -- Names can contain letters, digits, and underscores (_), but the first character must be a letter or underscore. -- Keywords cannot be used as variable names. -- C is case-sensitive, so num and Num would be considered different variables. - - -### Example: -```C -int count; -float _price; -double price123; -``` - -### Constants -Constants are variables whose values cannot be changed once initialized. In C, constants are defined using the const keyword or #define preprocessor directive. - -### Using `const`: -```C -const int MAX = 100; -``` - -### Using #define: -```C -#define PI 3.14159 -``` - -### Summary -- Variables store data and can be of different types such as int, float, char, etc. -- Variables have a scope that defines where they can be accessed within a program. -- Storage classes modify the scope and lifetime of a variable. -- Constants are variables whose value cannot be changed after initialization. diff --git a/docs/programming-fundamentals/_category_.json b/docs/programming-fundamentals/_category_.json deleted file mode 100644 index 8cc1338fd..000000000 --- a/docs/programming-fundamentals/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Programming Fundamentals", - "position": 4, - "link": { - "type": "generated-index", - "description": "Learn about Programming Fundamentals. This is the first step to become a good programmer." - } - } \ No newline at end of file diff --git a/docs/programming-fundamentals/functions.md b/docs/programming-fundamentals/functions.md deleted file mode 100644 index 0c72472d7..000000000 --- a/docs/programming-fundamentals/functions.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -id: functions -title: Introduction to functions fundamentals -sidebar_label: Functions -sidebar_position: 4 -description: "Information About functions in programming" -tags: [functions, fundamentals] ---- - - -## What are Functions? -Functions in C are self-contained blocks of code that perform a specific task. They allow for code reuse, modular programming, and improve the clarity of the code. - -## Defining a Function -A function is defined by specifying its return type, name, parameters (if any), and the body of the function. - -### Syntax: -```c -return_type function_name(parameter1_type parameter1, parameter2_type parameter2) { - // function body - // return statement (if return_type is not void) -} -``` - -### Example: -```C -int add(int a, int b) { - return a + b; -} -``` - -## Calling a Function -To use a function, you need to call it by its name and pass the required arguments. - -### Example: -```C -int sum = add(5, 10); // Calling the add function -printf("Sum: %d\n", sum); -``` - -## Types of Functions -### 1. Standard Library Functions -These are built-in functions provided by C libraries, such as printf(), scanf(), strlen(), etc. - -#### Example: -```C -#include - -int main() { - printf("Hello, World!\n"); // Standard library function - return 0; -} -``` - -### 2. User-Defined Functions -These are functions defined by the user to perform specific tasks. - -#### Example: -```C -void greet() { - printf("Hello, User!\n"); -} -``` - -##Function Parameters -Functions can accept parameters, which allow you to pass data into the function. - -### Types of Parameters: -1. Value Parameters: The function receives a copy of the argument. -2. Reference Parameters: The function receives a reference (address) to the argument. - -### Example of Value Parameter: -```C -void square(int num) { - num = num * num; // This does not affect the original argument -} -``` - -### Example of Reference Parameter: -```C -void square(int *num) { - *num = *num * *num; // This affects the original argument -} -``` - -## Return Statement -The return statement is used to return a value from a function. If the return type is void, the function does not return a value. - -### Example: -```C -double multiply(double x, double y) { - return x * y; // Returns the product of x and y -} -``` - -## Function Overloading -C does not support function overloading (defining multiple functions with the same name but different parameters) like C++. However, you can achieve similar functionality by using different names for functions. - -## Recursion -A function can call itself, which is known as recursion. It's useful for solving problems that can be broken down into smaller subproblems. - -### Example: -```C -int factorial(int n) { - if (n == 0) { - return 1; // Base case - } - return n * factorial(n - 1); // Recursive case -} -``` - -## Summary -- Functions are reusable blocks of code that perform specific tasks. -- They can accept parameters and return values. -- Functions can be standard library functions or user-defined functions. -Recursion allows functions to call themselves. diff --git a/docs/sortings/Sortings.md b/docs/sortings/Sortings.md deleted file mode 100644 index 5da7ddda1..000000000 --- a/docs/sortings/Sortings.md +++ /dev/null @@ -1,683 +0,0 @@ ---- -id: sortings -title: Sortings Data Structure -sidebar_label: Introduction to Sortings -description: 'Sorting algorithms are fundamental in computer science, used to arrange data in a particular order, typically ascending or descending. Various sorting techniques are designed to optimize performance based on factors like time complexity, space complexity.' -tags: [dsa, Sortings, Bubble sort, Insertion sort, Selection sort, Merge sort, Quick sort , C, Java, Heap Sort] ---- - -### Introduction to Sortings - -Sorting algorithms play a crucial role in organizing data for efficient access and manipulation. Different algorithms are optimized for various use cases based on their time complexity, space complexity, and stability. - -In this page we will learn about **Bubble Sort** , **Selection Sort** , **Insertion Sort** , **Merge Sort** and **Quick Sort**. - -### Bubble Sort - -Bubble sort is a simple, comparison-based sorting algorithm. It works by repeatedly stepping through the list, comparing adjacent elements, and swapping them if they are in the wrong order. This process is repeated until no more swaps are needed, indicating that the list is sorted. - -**Algorithm** - - - Start at the beginning of the array. - - Compare each pair of adjacent elements and then swap them if they are in the wrong order. - - Repeat the process for the entire list until no swaps are made during a pass. - -### Solution in C - ```c - #include - -// Function to display array elements -void display(int a[], int n) { - for (int i = 0; i < n; i++) { - printf("%d ", a[i]); - } - printf("\n"); -} - -// Function to perform bubble sort on an array -void bubble_sort(int a[], int n) { - int i, j, temp; - for (i = 1; i < n; i++) { - for (j = 0; j < n - i; j++) { - if (a[j] > a[j + 1]) { - temp = a[j]; - a[j] = a[j + 1]; - a[j + 1] = temp; - } - } - } - display(a, n); // Calling `display` after sorting -} - -int main() { - int a[] = {5, 2, 9, 1, 5, 6}; - int n = sizeof(a) / sizeof(a[0]); - bubble_sort(a, n); - return 0; -} - - ``` - -### Solution in Java -```java -import java.util.*; - -public class Main{ - - //function to print array - public static void printArray(int arr[]){ - for(int i=0; i arr[j+1]){ - //swap - int temp = arr[j]; - arr[j] = arr[j+1]; - arr[j+1] = temp; - } - } - } - - printArray(arr); - } -} -``` - -### Solution in JavaScript - -```javascript -// Function to print array -function printArray(arr) { - console.log(...arr); -} - -// Bubble sort function -function bubbleSort(arr) { - let n = arr.length; - for (let i = 0; i < n - 1; i++) { - // Loop to ignore sorted elements from previous iterations - for (let j = 0; j < n - i - 1; j++) { - if (arr[j] > arr[j + 1]) { - // Swap elements using destructuring - [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; - } - } - } - return arr; -} - -// Main function -function main() { - let arr = [7, 8, 3, 1, 2]; - - // Perform bubble sort - let sortedArr = bubbleSort(arr); - - // Print sorted array - printArray(sortedArr); -} - -// Call main function -main(); -``` - -**Time Complexity** - - **Worst Case**: O(n²) – when the array is sorted in reverse order. - - **Best Case**: O(n) – when the array is already sorted. - -**Space Complexity** - - O(1) – sorts the list in place without extra space. - -**Stability** - - Stable – equal elements remain in the same relative order after sorting. - -**Usage** - - Not used in practical applications due to its inefficiency, but useful for educational purposes. - -### Selection Sort - -Selection sort divides the array into a sorted and an unsorted region. It works by repeatedly selecting the smallest (or largest) element from the unsorted region and swapping it with the first unsorted element. This process continues until the entire array is sorted. - -**Algorithm** - - - Start at the beginning of the array. - - Find the minimum element from the unsorted portion of the array. - - Swap it with the first element in the unsorted portion and move forward. - - Repeat until the array is fully sorted. - -### Solution in C - ```text - void selection_sort(int a[],int n) - { - int i,j,k,temp,temper; - for(i=0;ia[j]) - { - k=j; - temp=a[j]; - } - if(k!=0){ - temper=a[i]; - a[i]=a[k]; - a[k]=temper; - } - } - display(a,n); - } - ``` - -### Solution in Java -```java -import java.util.*; - -public class Main{ - - //function to print array - public static void printArray(int arr[]){ - for(int i=0; i arr[j]){ - smallest = j; - } - } - //swapping after checking for each iteration - int temp = arr[smallest]; - arr[smallest] = arr[i]; - arr[i] = temp; - } - - printArray(arr); - } -} -``` - -**Time Complexity** - - **Worst Case**: O(n²) – as it performs n comparisons for each element. - - **Best Case**: O(n) – when the array is already sorted. - -**Space Complexity** - - O(1) – in-place sorting. - -**Stability** - - Unstable – equal elements may be swapped, changing their relative order. - -**Usage** - - Useful when memory space is limited due to its in-place nature. Not efficient for large datasets. - - -### Insertion Sort - -Insertion sort works similarly to how people arrange playing cards in their hands. It builds the sorted list one element at a time by inserting each new element into its proper position relative to the elements already sorted. - -**Algorithm** - - - Start at the beginning of the array. - - Assume the first element is sorted and pick the next element. - - Compare it to the elements in the sorted portion and shift elements larger than it to the right and insert the element in its correct position. - - Repeat until the array is fully sorted. - -### Solution in C - ```text - void insertion_sort(int a[],int n) - { - int i,j,temp; - for(i=1;i=0&&a[j]>temp;j--) - { - a[j+1]=a[j]; - a[j]=temp; - } - } - display(a,n); - } - ``` - -### Solution in Java -```java -import java.util.*; - -public class Main{ - - //function to print array - public static void printArray(int arr[]){ - for(int i=0; i= 0 && current < arr[j]){ - //element are pushed forward to make space for current element - arr[j+1] = arr[j]; - j--; - } - - //placement of current element after comparison has been done - arr[j+1] = current; - } - - printArray(arr); - } -} -``` -**Time Complexity** - - **Worst Case**: O(n²) – when the array is sorted in reverse order. - - **Best Case**: O(n) – when the array is already sorted. - -**Space Complexity** - - O(1) – in-place sorting. - -**Stability** - - Stable – maintains the relative order of equal elements. - -**Usage** - - Useful when memory space is limited due to its in-place nature. - - Efficient for small datasets or nearly sorted data. - - Commonly used in hybrid algorithms like Timsort. - -### Merge Sort - -Merge sort is a divide-and-conquer algorithm. It splits the array into two halves, recursively sorts each half, and then merges the sorted halves to produce the sorted array. - -**Algorithm** - - - Start at the beginning of the array. - - Divide the array into two halves. - - Recursively sort each half and merge the sorted halves into a single sorted array. - - Repeat until the array is fully sorted. - -### Solution in C - ```text - - //fUNCTION FOR MERGING - - void merge(int a[],int l,int mid,int u) - { - int i=l; - int j=mid+1; - int x=0; - int c[10]; - while(i<=mid&&j<=u) - { - if(a[i]<=a[j]) - { - c[x]=a[i]; - i++; - x++; - } - else - { - c[x]=a[j]; - j++; - x++; - } - } - while(i<=mid) - { - c[x]=a[i]; - i++;x++; - } - while(j<=u) - { - c[x]=a[j]; - j++;x++; - } - for(i=0,j=l;i= ei){ //either single element left or reached end of array - return; - } - int mid = si + (ei - si) / 2; // (si+ei)/2 might give TC for larger test cases - divide(arr, si, mid); - divide(arr, mid+1, ei); - - conquer(arr, si, mid, ei); - } - - public static void main(String[] args){ - int[] arr = {6, 3, 9, 5, 2, 8}; - int n = arr.length; - - divide(arr, 0, n-1); - for(int i=0; ipi); - if(i arr[largest]) - largest = left; - - if (right < n && arr[right] > arr[largest]) - largest = right; - - if (largest != i) { - swap(&arr[i], &arr[largest]); - heapify(arr, n, largest); - } -} - -// HEAP SORT FUNCTION -void heapSort(int arr[], int n) { - for (int i = n / 2 - 1; i >= 0; i--){ - heapify(arr, n, i); - } - - for (int i = n - 1; i > 0; i--) { - swap(&arr[0], &arr[i]); - heapify(arr, i, 0); - } -} - -// FUNCTION TO SWAP TWO ELEMENTS -void swap(int* a, int* b) { - int temp = *a; - *a = *b; - *b = temp; -} -``` - -**Time Complexity** -O(n log n) – consistently for all cases. - -**Space Complexity** -O(1) – in-place sorting, no extra space required. - -**Stability** -Unstable – the relative order of equal elements may change. - -**Usage** -Used in applications where a guarantee of O(n log n) time is necessary and space is limited. - -### Conclusion - -Choosing the right sorting algorithm ensures optimal performance, especially in applications involving large datasets or time-sensitive operations. Understanding these techniques allows developers to make informed decisions and write efficient code for a variety of sorting tasks. - -When implementing sorting in C, the standard library provides built-in functions like qsort() in stdlib.h, or you can create custom algorithms depending on the requirements. diff --git a/docusaurus.config.js b/docusaurus.config.js deleted file mode 100644 index 95a72f1bf..000000000 --- a/docusaurus.config.js +++ /dev/null @@ -1,230 +0,0 @@ -import { themes as prismThemes } from "prism-react-renderer"; -// import remarkPlugin from 'remark-plugin'; -import remarkMath from "remark-math"; -import rehypeKatex from "rehype-katex"; -const path = require("path"); - -/** @type {import('@docusaurus/types').Config} */ -const config = { - title: "Algo", - tagline: "Algo Mastery for Every Learner", - favicon: "logo/algo-3.png", - - url: "https://ajay-dhangar.github.io", - baseUrl: "/algo/", - organizationName: "codeharborhub", - projectName: "algo", - - onBrokenLinks: "throw", - onBrokenMarkdownLinks: "warn", - - presets: [ - [ - "classic", - /** @type {import('@docusaurus/preset-classic').Options} */ - ({ - debug: true, - docs: { - sidebarPath: "./sidebars.js", - editUrl: - "https://github.com/ajay-dhangar/algo/tree/main/packages/create-docusaurus/templates/shared/", - remarkPlugins: [remarkMath], - rehypePlugins: [rehypeKatex], - showLastUpdateAuthor: true, - showLastUpdateTime: true, - }, - blog: { - showReadingTime: true, - editUrl: - "https://github.com/ajay-dhangar/algo/tree/main/packages/create-docusaurus/templates/shared/", - remarkPlugins: [remarkMath], - rehypePlugins: [rehypeKatex], - }, - theme: { - customCss: "./src/css/custom.css", - }, - }), - ], - ], - - stylesheets: [ - { - href: "https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css", - type: "text/css", - integrity: - "sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM", - crossorigin: "anonymous", - }, - ], - - themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ - image: "/", - announcementBar: { - id: "announcementBar", - content: - '📢 Join our
    WhatsApp Channel for the latest updates and collaboration on exciting projects!', - isCloseable: true, - backgroundColor: "var(--docusaurus-highlighted-code-line-bg)", - }, - - algolia: { - apiKey: "865d7bd9906f532b1d8cb5cc0f02b383", - indexName: "ajay-dhangario", - appId: "T0I3F584D5", - contextualSearch: false, - }, - - navbar: { - title: "Algo", - logo: { - alt: "Algo Logo", - src: "logo/algo.png", - }, - items: [ - { - type: "docSidebar", - sidebarId: "tutorialSidebar", - position: "left", - label: "Tutorial", - }, - { - to: "blog", - label: "Blog", - position: "left", - }, - { - to: "faq", - label: "FAQ", - position: "left", - }, - { - to: "dsa-roadmap", - label: "Pick Topic For Contribution", - position: "left", - }, - { - to: "contributors", - label: "Contributors", - position: "left", - }, - { - type: "dropdown", - label: "More", - position: "right", - items: [ - { - to: "dsa-interview", - label: "Top DSA Questions", - }, - { - to: "roadmap", - label: "Roadmap", - }, - { - to: "challenges", - label: "Challenges", - }, - { - to: "practice", - label: "Practice", - }, - { - to: "quizes", - label: "Quizes", - }, - { - to: "quiz-solutions", - label: "Quizzes Solutions", - }, - { - to: "leaderboard", - label: "Leaderboard", - }, - { - to: "community", - label: "Community", - }, - { - to: "resources", - label: "Resources", - }, - { - to: "blogs", - label: "Blogs", - }, - ], - }, - { - href: "https://github.com/ajay-dhangar/algo", - label: "GitHub", - position: "right", - }, - { - type: "search", - position: "right", - }, - ], - }, - footer: { - style: "dark", - links: [ - { - title: "Docs", - items: [ - { - label: "Tutorial", - to: "/docs/", - }, - ], - }, - ], - logo: { - alt: "Ajay Dhangar", - src: "/logo/ft-copy.png", - href: "https://github.com/ajay-dhangar", - }, - copyright: `Copyright © ${new Date().getFullYear()} Algo, Inc. Built with Docusaurus.`, - }, - prism: { - theme: prismThemes.github, - darkTheme: prismThemes.dracula, - additionalLanguages: [ - 'java', - 'latex', - 'haskell', - 'matlab', - 'PHp', - 'powershell', - 'bash', - 'diff', - 'json', - 'scss', - ], - }, - docs: { - sidebar: { - hideable: true, - }, - }, - }), - - themes: ["@docusaurus/theme-mermaid"], - markdown: { - mermaid: true, - }, - - plugins: [ - [ - path.join(__dirname, "/plugins/my-plugin",), - { - settings: "Some20settings", - api: "Some-API", - keys: "Some-keys", - }, - ], - ], -}; - -export default config; diff --git a/festhack.jpg b/festhack.jpg deleted file mode 100644 index 1b21082df1c225519f7bf8d72ebde4d93ad21cca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 194570 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

    JMG1%gw}uR`|+6psgnBAey;?c-_w&etBlNYsRd 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 TS|8tqbhJ(iMgjx~KM(#N+AQ}6 diff --git a/girlscript.jpg b/girlscript.jpg deleted file mode 100644 index ab4b58dbc8e637a8626a1428b77d2364c53a2dcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16124 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 diff --git a/java/Armstrong-Number-Checker.md b/java/Armstrong-Number-Checker.md deleted file mode 100644 index d485639c3..000000000 --- a/java/Armstrong-Number-Checker.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -id: Armstrong-Number-Checker -sidebar_position: 3 -title: Armstrong Number Checker -sidebar_label: Armstrong Number Checker -description: "This document explains the implementation of an Armstrong number checker in Java, detailing its description, approach, and implementation." -tags: [java, numbers, armstrong-number, checker] ---- -# Armstrong Number Checker - -## Description -An Armstrong number (or Narcissistic number) is a number that is equal to the sum of its own digits each raised to the power of the number of digits. For example, 153 is an Armstrong number because 1^3+5^3+3^3=153. This program verifies whether a given number is an Armstrong number. - -## Approach -The approach involves iterating through each digit of the number, raising it to the power of the total number of digits, and summing these values. If the sum matches the original number, it is an Armstrong number. - -## Steps: -1.**Calculate the Number of Digits**: --Convert the number to a string or use a loop to count the digits. -2.**Compute the Armstrong Sum**: --For each digit in the number, raise it to the power of the number of digits and add it to a cumulative sum. -3.**Comparison**: --Check if the computed sum is equal to the original number. If yes, the number is an Armstrong number; otherwise, it is not. - -## Java Implementation -'''java -import java.util.Scanner; - -public class ArmstrongNumberChecker { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - - System.out.print("Enter a number: "); - int number = scanner.nextInt(); - int originalNumber = number; - int digits = String.valueOf(number).length(); - int sum = 0; - - while (number > 0) { - int digit = number % 10; - sum += Math.pow(digit, digits); - number /= 10; - } - - if (sum == originalNumber) { - System.out.println(originalNumber + " is an Armstrong number."); - } else { - System.out.println(originalNumber + " is not an Armstrong number."); - } - } -} -''' -## Complexity Analysis -**Time Complexity**: -O(d) — where d is the number of digits in the input number, as each digit is processed once. - -**Space Complexity**: -O(1) — only a few variables are used for storage. - -## Conclusion -In this document, we implemented an Armstrong number checker that determines whether a given integer is an Armstrong number. This program has efficient constant space usage and linear time complexity relative to the number of digits in the number, making it well-suited for checking small to moderately large integers. \ No newline at end of file diff --git a/java/Arrays/1.Easy/Find missing number.md b/java/Arrays/1.Easy/Find missing number.md deleted file mode 100644 index fbf4c768b..000000000 --- a/java/Arrays/1.Easy/Find missing number.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: find-missing-number -title: Find the Missing Number in Array -sidebar_label: Find Missing Number in Array -sidebar_position: 1 -description: Find the missing number in an array of size N containing numbers from 1 to N. -tags: [Array, XOR, DSA] ---- - -# Problem Statement -You are given an array `a` of size `N-1` containing numbers from `1` to `N`. The array has one number missing. Find the missing number. - -[LeetCode Problem Link](https://leetcode.com/problems/missing-number/description/) - ---- - -## Examples - -**Example 1**: -Input: -`a = [1, 2, 4, 5]`, `N = 5` - -Output: -`3` - -Explanation: -Numbers between `1` to `N` are `[1, 2, 3, 4, 5]`. The missing number is `3`. - ---- - -**Example 2**: -Input: -`a = [2, 3, 4, 5]`, `N = 5` - -Output: -`1` - -Explanation: -Numbers between `1` to `N` are `[1, 2, 3, 4, 5]`. The missing number is `1`. - ---- - -## Intuition -This problem can be solved using the properties of XOR: -1. **Property 1**: XOR of two identical numbers is always 0 (`a ^ a = 0`). -2. **Property 2**: XOR of a number with 0 results in the number itself (`0 ^ a = a`). - -### Key Idea: -- XOR all the numbers from `1` to `N`, which results in `xor1 = 1 ^ 2 ^ ... ^ N`. -- XOR all the elements in the array `a[]`, which results in `xor2 = 1 ^ 2 ^ ... ^ N` (excluding the missing number). -- The result of `xor1 ^ xor2` will cancel out all the numbers except the missing one, as explained by the XOR properties. Hence, `missing number = xor1 ^ xor2`. - ---- - -## Approach -1. Initialize two variables `xor1` and `xor2` to 0. -2. XOR all the numbers from `1` to `N` and store the result in `xor1`. -3. XOR all the elements of the array and store the result in `xor2`. -4. XOR the values of `xor1` and `xor2`. The result will be the missing number. - ---- - -## Java Implementation - -```java -import java.util.*; - -public class FindMissingNumber { - public static int missingNumber(int []a, int N) { - int xor1 = 0, xor2 = 0; - - for (int i = 0; i < N - 1; i++) { - xor2 = xor2 ^ a[i]; // XOR of array elements - xor1 = xor1 ^ (i + 1); // XOR up to [1...N-1] - } - xor1 = xor1 ^ N; // XOR up to [1...N] - - return (xor1 ^ xor2); // the missing number - } - - public static void main(String args[]) { - int N = 5; - int a[] = {1, 2, 4, 5}; - - int ans = missingNumber(a, N); - System.out.println("The missing number is: " + ans); - } -} -``` ---- -## Time Complexity -**Time Complexity**: `O(N)`, where N is the number of elements in the array. We only need to iterate over the array once to calculate the XORs. - -**Space Complexity**: `O(1)`, as we are only using a constant amount of extra space. - ---- -## Conclusion -Using XOR properties, we can find the missing number in linear time without using any extra space, making it an optimal solution for this problem. \ No newline at end of file diff --git a/java/Arrays/1.Easy/Remove Duplicates from Sorted Array.md b/java/Arrays/1.Easy/Remove Duplicates from Sorted Array.md deleted file mode 100644 index aec67e5f4..000000000 --- a/java/Arrays/1.Easy/Remove Duplicates from Sorted Array.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -id: remove-duplicates-sorted-array -title: Remove Duplicates in-place from Sorted Array -sidebar_label: Remove Duplicates in-place -sidebar_position: 1 -description: Given a sorted array, remove the duplicates in-place and return the new length. -tags: [Array, In-place, DSA] ---- - -# Remove Duplicates in-place from Sorted Array - -## Problem Statement -Given a sorted array `arr`, remove duplicates in-place such that each element appears only once and return the new length. The solution should modify the input array in-place and not use extra space. - -[LeetCode Problem Link](https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/) - ---- - -## Examples - -**Example 1**: -Input: -`arr = [1, 1, 2, 2, 2, 3, 3]` - -Output: -`arr = [1, 2, 3, _, _, _, _]` - -Explanation: -The unique elements are `[1, 2, 3]`, so the function returns `3` and places `[1, 2, 3]` at the start of the array. - ---- - -**Example 2**: -Input: -`arr = [1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4]` - -Output: -`arr = [1, 2, 3, 4, _, _, _, _, _, _, _]` - -Explanation: -The unique elements are `[1, 2, 3, 4]`, so the function returns `4` and places `[1, 2, 3, 4]` at the start of the array. - ---- - -## Approach -The problem can be solved using the two-pointer technique: - -1. Maintain two pointers, `i` and `j`, where `i` tracks the position of unique elements and `j` iterates over the array. -2. If the element at index `j` is different from the element at index `i`, increment `i` and set `arr[i] = arr[j]`. -3. The new length of the array will be `i + 1`. - -### Steps: -- Initialize `i = 0` to track the first unique element. -- Traverse the array from `j = 1` to the end. -- If `arr[j]` is different from `arr[i]`, update `arr[i + 1]` with `arr[j]` and increment `i`. -- After the loop, the first `i + 1` elements of the array will be unique. - ---- - -## Java Implementation - -```java -import java.util.*; - -public class Main { - public static void main(String[] args) { - int arr[] = {1, 1, 2, 2, 2, 3, 3}; - int k = removeDuplicates(arr); - System.out.println("The array after removing duplicate elements is "); - for (int i = 0; i < k; i++) { - System.out.print(arr[i] + " "); - } - } - - static int removeDuplicates(int[] arr) { - int i = 0; - for (int j = 1; j < arr.length; j++) { - if (arr[i] != arr[j]) { - i++; - arr[i] = arr[j]; - } - } - return i + 1; - } -} -``` - ---- -## Time Complexity -**Time Complexity**: `O(n)`, where n is the length of the input array. We are using a single loop to traverse the array. - -**Space Complexity**: `O(1)`, since we are modifying the array in-place without using any extra space. - ---- -## Conclusion -This solution efficiently removes duplicates from a sorted array in-place using the two-pointer technique. It has a time complexity of `O(n)` and does not require extra space, making it optimal for large inputs. \ No newline at end of file diff --git a/java/Arrays/2.Medium/Kadane's Algorithm.md b/java/Arrays/2.Medium/Kadane's Algorithm.md deleted file mode 100644 index 68d24dca3..000000000 --- a/java/Arrays/2.Medium/Kadane's Algorithm.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: kadanes-algorithm> -title: Kadane's Algorithm- Maximum Subarray Sum -sidebar_label: Maximum Subarray Sum -sidebar_position: 1 -description: Find the maximum sum of a contiguous subarray in an integer array. -tags: [Array, Dynamic Programming, Greedy, DSA] ---- - -# Kadane's Algorithm: Maximum Subarray Sum - -## Problem Statement -Given an integer array `arr`, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. - -[LeetCode Problem Link](https://leetcode.com/problems/maximum-subarray/description/) - -## Examples - -**Example 1**: -Input: -`arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4]` - -Output: -`6` - -Explanation: -The subarray `[4, -1, 2, 1]` has the largest sum = 6. - ---- - -**Example 2**: -Input: -`arr = [1]` - -Output: -`1` - -Explanation: -Array has only one element, which gives a positive sum of 1. - ---- - -## Intuition -The intuition behind **Kadane's Algorithm** is simple: a subarray with a negative sum will always reduce the sum of the total subarray, so it's better to discard such subarrays and reset the sum to 0 whenever the sum goes below 0. - -### Key Idea -- Iterate through the array and add elements to a running sum. -- If the sum becomes negative at any point, reset it to zero since no subarray with a negative sum is worth considering. -- Track the maximum sum encountered during the iteration. - -## Approach -1. Initialize two variables: `maxi` to store the maximum sum and `sum` to store the current subarray sum. -2. Iterate through the array: - - Add the current element to `sum`. - - If `sum` exceeds `maxi`, update `maxi`. - - If `sum` becomes negative, reset it to `0`. -3. Return `maxi` as the result. - -### Edge Case -In some scenarios, the question may mention that the sum of an empty subarray should be considered. In that case, compare `maxi` with `0` before returning the result, and ensure you return the larger value. - -## Java Implementation - -```java -import java.util.*; - -public class Main { - public static long maxSubarraySum(int[] arr, int n) { - long maxi = Long.MIN_VALUE; // maximum sum - long sum = 0; - - for (int i = 0; i < n; i++) { - sum += arr[i]; - if (sum > maxi) { - maxi = sum; - } - // If sum < 0: discard the sum calculated - if (sum < 0) { - sum = 0; - } - } - - return maxi; - } - - public static void main(String args[]) { - int[] arr = { -2, 1, -3, 4, -1, 2, 1, -5, 4}; - int n = arr.length; - long maxSum = maxSubarraySum(arr, n); - System.out.println("The maximum subarray sum is: " + maxSum); - } -} - -``` - ---- -## Time Complexity -The **Time complexity** of Kadane's Algorithm is `O(n)`, where n is the number of elements in the array. This is because we make a single pass through the array to calculate the maximum subarray sum. - -**Space Complexity**: `O(1)` as we are not using any extra space. - ---- -## Conclusion -Kadane's Algorithm efficiently finds the maximum subarray sum in linear time, making it a powerful technique for solving problems related to contiguous subarrays. The algorithm's simplicity and effectiveness make it a staple in competitive programming and interviews. \ No newline at end of file diff --git a/java/Arrays/2.Medium/Longest Subarray with sum K.md b/java/Arrays/2.Medium/Longest Subarray with sum K.md deleted file mode 100644 index 8f66e0f22..000000000 --- a/java/Arrays/2.Medium/Longest Subarray with sum K.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -id: longest-subarray-sum-k -title: Find Longest Subarray with Sum k -sidebar_label: Longest Subarray with Sum k -sidebar_position: 1 -description: Find the length of the longest subarray whose sum equals k. -tags: [Array, Hashing, DSA] ---- - -# Problem Statement -Given an array `a[]` and an integer `k`, find the length of the longest subarray that sums to `k`. - -[LeetCode Problem Link](https://leetcode.com/problems/subarray-sum-equals-k/) - -## Examples - -**Example 1**: -Input: -`N = 3, k = 5, array[] = {2, 3, 5}` - -Output: -`2` - -Explanation: -The longest subarray with sum `5` is `{2, 3}`. Its length is `2`. - ---- - -**Example 2**: -Input: -`N = 3, k = 1, array[] = {-1, 1, 1}` - -Output: -`3` - -Explanation: -The longest subarray with sum `1` is `{-1, 1, 1}`. Its length is `3`. - ---- - -## Intuition -To solve this problem optimally, we can use the concept of **prefix sum** combined with **hashing**. - -### Key Idea: -- Maintain a map to store the prefix sum and its corresponding index. -- As we iterate through the array, calculate the prefix sum up to each index. -- Check if the prefix sum equals `k`. If yes, update the maximum subarray length. -- Also, check if there is a prefix sum equal to `sum - k` (the remaining sum required to get `k` from the current subarray). If such a sum exists, calculate the length of the subarray and update the maximum length accordingly. -- Store the prefix sum and its earliest occurrence in the map to maximize the subarray length. - ---- - -## Approach -1. Declare a HashMap `preSumMap` to store prefix sums and their corresponding indices. -2. Initialize variables `sum = 0` (to store the running prefix sum) and `maxLen = 0` (to store the length of the longest subarray with sum `k`). -3. Iterate through the array. For each element: - - Add the current element to `sum` (prefix sum up to that index). - - If the sum is equal to `k`, update `maxLen` to `i + 1` (the length from the start). - - Check if `sum - k` exists in the map. If yes, update `maxLen` with the length of the subarray `i - preSumMap[sum - k]`. - - Add the current `sum` to the map if it doesn't already exist (to store the earliest occurrence of the prefix sum). -4. Return `maxLen`, which stores the length of the longest subarray with sum `k`. - ---- - -## Java Implementation - -```java -import java.util.*; - -public class tUf { - public static int getLongestSubarray(int[] a, int k) { - int n = a.length; // size of the array. - Map preSumMap = new HashMap<>(); - int sum = 0; - int maxLen = 0; - - for (int i = 0; i < n; i++) { - // calculate the prefix sum till index i: - sum += a[i]; - - // if the sum = k, update the maxLen: - if (sum == k) { - maxLen = Math.max(maxLen, i + 1); - } - - // calculate the sum of remaining part i.e. x-k: - int rem = sum - k; - - // calculate the length and update maxLen: - if (preSumMap.containsKey(rem)) { - int len = i - preSumMap.get(rem); - maxLen = Math.max(maxLen, len); - } - - // finally, update the map checking the conditions: - if (!preSumMap.containsKey(sum)) { - preSumMap.put(sum, i); - } - } - - return maxLen; - } - - public static void main(String[] args) { - int[] a = {-1, 1, 1}; - int k = 1; - int len = getLongestSubarray(a, k); - System.out.println("The length of the longest subarray is: " + len); - } -} - -``` - ---- -## Time Complexity -**Time Complexity**: `O(N)`, where N is the number of elements in the array. We process each element only once. - -**Space Complexity**: `O(N)`, as we are using a HashMap to store the prefix sums. - ---- -## Conclusion -Using a hash map to store prefix sums allows us to efficiently find the longest subarray with sum k in linear time. \ No newline at end of file diff --git a/java/Arrays/3.Hard/Maximum Product Subarray.md b/java/Arrays/3.Hard/Maximum Product Subarray.md deleted file mode 100644 index 92d596ccf..000000000 --- a/java/Arrays/3.Hard/Maximum Product Subarray.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -id: maximum-product-subarray -title: Maximum Product Subarray in an Array -sidebar_label: Maximum Product Subarray -sidebar_position: 1 -description: Find the maximum product of a contiguous subarray within an array containing both negative and positive integers. -tags: [Dynamic Programming, Array] ---- - -# Problem Statement -Given an array that contains both negative and positive integers, find the maximum product subarray. - -**LeetCode Problem Link**: [Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/description/) - -## Examples - -**Example 1**: -Input: -`Nums = [1, 2, 3, 4, 5, 0]` -Output: -`120` -**Explanation**: -In the given array, we can see `1 × 2 × 3 × 4 × 5` gives the maximum product value. - ---- - -**Example 2**: -Input: -`Nums = [1, 2, -3, 0, -4, -5]` -Output: -`20` -**Explanation**: -In the given array, we can see `(-4) × (-5)` gives the maximum product value. - ---- - -## Approach -The following approach is motivated by Kadane’s algorithm. The key insight is that we can obtain the maximum product from the product of two negative numbers as well. - -### Steps: -1. Initially, store the value at the 0th index in `prod1`, `prod2`, and `result`. -2. Traverse the array starting from the 1st index. -3. For each element: - - Update `prod1` to be the maximum of the current element, the product of the current element and `prod1`, and the product of the current element and `prod2`. - - Update `prod2` to be the minimum of the current element, the product of the current element and `prod1`, and the product of the current element and `prod2`. -4. Return the maximum of `result` and `prod1`. - -## Java Implementation - -```java -import java.util.*; - -public class Main { - static int maxProductSubArray(int arr[]) { - int prod1 = arr[0], prod2 = arr[0], result = arr[0]; - - for (int i = 1; i < arr.length; i++) { - int temp = Math.max(arr[i], Math.max(prod1 * arr[i], prod2 * arr[i])); - prod2 = Math.min(arr[i], Math.min(prod1 * arr[i], prod2 * arr[i])); - prod1 = temp; - - result = Math.max(result, prod1); - } - - return result; - } - - public static void main(String[] args) { - int nums[] = {1, 2, -3, 0, -4, -5}; - int answer = maxProductSubArray(nums); - System.out.print("The maximum product subarray is: " + answer); - } -} - -``` - ---- -## Time Complexity -The **Time complexity** of this algorithm is `O(n)`, where n is the number of elements in the input array. We traverse the array once to calculate the maximum product. - -The **Space complexity** is `O(1)` since we are using only a constant amount of space for variables. - ---- -## Conclusion -This approach efficiently finds the maximum product subarray by leveraging the properties of positive and negative integers. It maintains both the maximum and minimum products at each step, allowing it to handle negative values effectively. This solution is optimal in terms of both time and space complexity, making it suitable for large input sizes. \ No newline at end of file diff --git a/java/Arrays/3.Hard/Reverse pairs.md b/java/Arrays/3.Hard/Reverse pairs.md deleted file mode 100644 index 828d5c762..000000000 --- a/java/Arrays/3.Hard/Reverse pairs.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: reverse-pairs -title: Count Reverse Pairs -sidebar_label: Count Reverse Pairs -sidebar_position: 1 -description: Count the number of reverse pairs in an array where i is less than j and the element at index i is greater than twice the element at index j. -tags: [Merge Sort, Array] ---- - -# Problem Statement -Given an array of numbers, return the count of reverse pairs. Reverse Pairs are those pairs where `i < j` and `arr[i] > 2 * arr[j]`. - -**LeetCode Problem Link**: [Reverse Pairs](https://leetcode.com/problems/reverse-pairs/description/) - -## Examples - -### Example 1 -Input: -`N = 5, array[] = {1, 3, 2, 3, 1}` -Output: -`2` -**Explanation**: -The pairs are `(3, 1)` and `(3, 1)` as both satisfy the condition `arr[i] > 2 * arr[j]`. - -### Example 2 -Input: -`N = 4, array[] = {3, 2, 1, 4}` -Output: -`1` -**Explanation**: -There is only 1 pair `(3, 1)` that satisfies the condition `arr[i] > 2 * arr[j]`. - -## Approach - -The problem can be solved using a modified **Merge Sort** approach, similar to the inversion count problem but with a change in the condition. The idea is to: -1. **Merge** the sorted halves. -2. **Count pairs** where `arr[i] > 2 * arr[j]` using two pointers during the merge step. -3. Merge sort ensures that both halves are sorted, making it efficient to count valid pairs. - -### Steps -1. Implement a **modified merge sort** where: - - During the merge process, count valid pairs by iterating through the left and right halves. - - For each element in the left half, count how many elements in the right half satisfy the condition. -2. After counting the pairs, merge the two halves back into the original array. - -## Java Implementation - -```java -import java.util.*; - -public class CountReversePairs { - - // Merges two sorted halves and counts reverse pairs - private static void merge(int[] arr, int low, int mid, int high) { - ArrayList temp = new ArrayList<>(); - int left = low; - int right = mid + 1; - - // Merge two halves in sorted order - while (left <= mid && right <= high) { - if (arr[left] <= arr[right]) { - temp.add(arr[left]); - left++; - } else { - temp.add(arr[right]); - right++; - } - } - - // If there are remaining elements in the left half - while (left <= mid) { - temp.add(arr[left]); - left++; - } - - // If there are remaining elements in the right half - while (right <= high) { - temp.add(arr[right]); - right++; - } - - // Transfer all elements from temp back to arr - for (int i = low; i <= high; i++) { - arr[i] = temp.get(i - low); - } - } - - // Counts pairs where arr[i] > 2 * arr[j] in two sorted halves - public static int countPairs(int[] arr, int low, int mid, int high) { - int right = mid + 1; - int cnt = 0; - for (int i = low; i <= mid; i++) { - while (right <= high && arr[i] > 2 * arr[right]) right++; - cnt += (right - (mid + 1)); - } - return cnt; - } - - // Recursive merge sort with modification to count reverse pairs - public static int mergeSort(int[] arr, int low, int high) { - int cnt = 0; - if (low >= high) return cnt; - int mid = (low + high) / 2 ; - cnt += mergeSort(arr, low, mid); // left half - cnt += mergeSort(arr, mid + 1, high); // right half - cnt += countPairs(arr, low, mid, high); // Count reverse pairs - merge(arr, low, mid, high); // Merge sorted halves - return cnt; - } - - // Main function that triggers the merge sort - public static int reversePairs(int[] arr, int n) { - return mergeSort(arr, 0, n - 1); - } - - public static void main(String[] args) { - int[] array = {4, 1, 2, 3, 1}; - int n = 5; - int count = reversePairs(array, n); - System.out.println("The number of reverse pairs is: " + count); - } -} - -``` - ---- -## Time Complexity -The **Time complexity** is O(N log N), where N is the size of the array. - -**Merge Sort**: Recursively divides the array, which takes O(log N). -**Counting pairs**: For each split, the counting process takes O(N). - -Thus, the total time complexity is `O(N log N)`. - -**Space Complexity**: The space complexity is `O(N)` because of the temporary array used to store the merged elements. - ---- -## Conclusion -This problem is a modification of the inversion count problem, with the condition `arr[i] > 2 * arr[j].` The approach uses merge sort to efficiently count such pairs in `O(N log N)` time. This is optimal for large arrays and ensures that the problem can be solved within reasonable time limits. \ No newline at end of file diff --git a/java/LCM-GCD-Calculator.md b/java/LCM-GCD-Calculator.md deleted file mode 100644 index f0091eeaa..000000000 --- a/java/LCM-GCD-Calculator.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -id: LCM-GCD-Calculator -sidebar_position: 4 -title: LCM and GCD Calculator -sidebar_label: LCM and GCD Calculator -description: "This document details the implementation of a Java program to calculate the Least Common Multiple (LCM) and Greatest Common Divisor (GCD) of two numbers, along with explanations for the approach and implementation." -tags: [java, math, gcd, lcm, calculator] ---- -### LCM and GCD Calculator -## Description -This program calculates the Greatest Common Divisor (GCD) and Least Common Multiple (LCM) of two user-provided numbers. The GCD of two numbers is the largest number that divides both, and the LCM is the smallest number divisible by both. - -## Approach -To find the GCD, the Euclidean algorithm is used, which is efficient and based on the principle that GCD(a, b) = GCD(b, a % b). The LCM is then calculated using the relation: -LCM(a,b)= ∣a×b∣/GCD(a,b) - -## ​Steps: -1.**Input Validation**: --Ensure both numbers are valid integers. -2.**Calculate GCD using the Euclidean Algorithm**: --Use a loop to find the GCD based on repeated modulo operations until one of the numbers becomes zero. -3.**Calculate LCM**: --Use the GCD to compute the LCM using the formula above. -4.**Output**: --Display the GCD and LCM results. - -## Java Implementation -'''java -import java.util.Scanner; - -public class LCMandGCDCalculator { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - - System.out.print("Enter first number: "); - int num1 = scanner.nextInt(); - - System.out.print("Enter second number: "); - int num2 = scanner.nextInt(); - - int gcd = findGCD(num1, num2); - int lcm = (num1 * num2) / gcd; - - System.out.println("GCD: " + gcd); - System.out.println("LCM: " + lcm); - } - - public static int findGCD(int a, int b) { - while (b != 0) { - int temp = b; - b = a % b; - a = temp; - } - return a; - } -} -''' -## Complexity Analysis -**Time Complexity**: -O(log(min(a, b))) — The Euclidean algorithm is efficient, with logarithmic time complexity based on the smaller of the two numbers. - -**Space Complexity**: -O(1) — Only a few variables are used for intermediate calculations. - -## Conclusion -This document details an LCM and GCD calculator that leverages the Euclidean algorithm for GCD calculation and uses it to compute the LCM. The program is efficient with logarithmic time complexity, making it suitable for calculating GCD and LCM for moderately large integers. - - - - - - diff --git a/java/Palindrome_number.md b/java/Palindrome_number.md deleted file mode 100644 index 743f42259..000000000 --- a/java/Palindrome_number.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: Palindrome_number -sidebar_position: 1 -title:check palindrome number. -sidebar_label:palindrom number. -description: "This document explains the check is it Palindrome or not , including its description, approach, and implementation." -tags: [java, problem-solving] ---- - -# Palindrome number. - -## Description -Given a number , check is it palindrome or not , and return answer in boolean. Palindrome is when we read it from left to right and right to left it same. ex-121. - -## Approach - -rev = rev * 10 + (x % 10); - -This expression shifts the current value of rev one decimal place to the left by multiplying it by 10. -The last digit of x is extracted using x % 10 (modulus operation). -The last digit is then added to rev. -Modulo operator (%) is used to extract the last digit of the number. -division (/) is used to remove the last digit of the number. -Palindrome property: A number is a palindrome if it reads the same forward and backward. - -### Steps: - -1. **Initialize**: - - initialize the rev 0 for storing the value in reverse order. - -2. **Iterate**: - - by using % operator we get last digit and store it. - - by multiply by 10 and store last digit we get the number in reverse format. - - divide by 10 so that last digit get remove. - -3. **Return**: - - original digit is equal to rev. - -## java Implementation - - -```java - -public class Palindrome_number { - public static void main(String[] args) { - Palindrome_number obj = new Palindrome_number(); - boolean ans = obj.palindrome(121); - System.out.println(ans); - } - - public boolean palindrome(int num) { - if(num<0){ //if number is less than zero then return false; - return false; - } - int rev=0; //define a varible rev. for reveses number. - int original=num; //redefined the value of num. - while(num>0){ //while loop upto the num greater than 0 - rev=rev*10+num%10; //this is logic for reverse the number. - num=num/10; //last digit deleted. - } - return rev==original; // check - } - -} -``` - - - -** 👉🏻👉🏻👉🏻 time complexity=constant. O(1)** -👉🏻👉🏻👉🏻spacd complexity=constant. O(1); - -** 👉🏻👉🏻👉🏻 logic.-** -(rev = rev * 10 + x % 10; and x = x / 10;) -Modulo operator (%) is used to extract the last digit of the number. - division (/) is used to remove the last digit of the number. -Palindrome property: A number is a palindrome if it reads the same forward and backward. - -## Conclusion - -In this article, we learned about the Palindrome in number . Palindroem is a when you read from left to right and right to left is same that basically a palindrome. The time complexit is O(n) and the space complexity is O(1).. \ No newline at end of file diff --git a/java/Palindrome_string.md b/java/Palindrome_string.md deleted file mode 100644 index 27176d826..000000000 --- a/java/Palindrome_string.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -id: Palindrome_string -title: Palindroem string -sidebar_label: Palindrome string -description: "is a well knows problem help to buid concept." -tags: [java,dsa, algorithms,Problem solving] ---- - -# Game Theory - -**Palindrome string** -Given a String , check is it palindrome or not , and return answer in boolean. Palindrome is when we read it from left to right and right to left it same. ex-madam1. - -## Apporach - -### 1. ** Understand the Problem:** -- Identify what constitutes a palindrome. --Recognize that the string should be identical when read from left to right and right to left. - -### 2. **Two-Pointer Technique:** -- This is an efficient method to check for palindromes. The idea is to use two pointers, one starting at the beginning of the string and the other at the end. --By comparing characters at these pointers, you can determine if the string is a palindrome by progressively moving toward the center. - -- **Steps to Implement:**: - - **Initialize Pointers: -Set a pointer (left) at the start of the string (index 0). -Set another pointer (right) at the end of the string (index length - 1). - --**Iterate and Compare:** -While the left pointer is less than the right pointer: -Compare the characters at both pointers. -If the characters are not equal, return false. -If they are equal, move the left pointer one step to the right (increment) and the right pointer one step to the left (decrement). - --**Return Result:** -If the loop completes without finding any mismatches, return true, indicating the string is a palindrome. - - -## java Implementation - -```java - -public class Palindrome_string { - public static void main(String[] args) { - Palindrome_string obj = new Palindrome_string(); - boolean ans = obj.Palindrome_string("manad"); - System.out.println(ans); - } - - public boolean Palindrome_string(String str) { - int left=0; - int right =str.length()-1; // last character of string . - - while(left fruits = new ArrayList<>(); - ``` - -2. **Adding Elements:** - ```java - fruits.add("Apple"); - fruits.add("Banana"); - fruits.add("Orange"); - ``` - -3. **Accessing Elements:** - ```java - String firstFruit = fruits.get(0); - ``` - -4. **Removing Elements:** - ```java - fruits.remove(1); // Removes the element at index 1 - ``` - -5. **Iterating Over Elements:** - ```java - for (String fruit : fruits) { - System.out.println(fruit); - } - ``` - -**Common Methods:** - -* **`add(E element)`:** Adds an element to the end of the list. -* **`add(int index, E element)`:** Inserts an element at a specific index. -* **`remove(int index)`:** Removes the element at a specific index. -* **`remove(Object o)`:** Removes the first occurrence of the specified object. -* **`get(int index)`:** Returns the element at a specific index. -* **`size()`:** Returns the number of elements in the list. -* **`isEmpty()`:** Returns `true` if the list is empty. -* **`clear()`:** Removes all elements from the list. - -**Example:** - -```java -import java.util.ArrayList; - -public class ArrayListExample { - public static void main(String[] args) { - ArrayList numbers = new ArrayList<>(); - numbers.add(10); - numbers.add(20); - numbers.add(30); - - System.out.println("Size of the list: " + numbers.size()); - System.out.println("First element: " + numbers.get(0)); - - numbers.remove(1); // Remove the element at index 1 - - for (int number : numbers) { - System.out.println(number); - } - } -} -``` - -**Key Points to Remember:** - -* ArrayLists are dynamic and can grow or shrink as needed. -* They are zero-indexed, meaning the first element is at index 0. -* Consider using `ArrayList` when you need a dynamic list of objects and frequent insertion and deletion operations. -* For sequential access and faster iteration, consider using `LinkedList`. - -By understanding these concepts and methods, you can effectively utilize ArrayLists in your Java programs to manage collections of objects efficiently. diff --git a/java/fast-exponential.md b/java/fast-exponential.md deleted file mode 100644 index 3450a7fb7..000000000 --- a/java/fast-exponential.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -id: fast-exponential -sidebar_position: 1 -title: Fast Exponential -sidebar_label: fast exponential -description: Fast exponentiation is a powerful technique for handling large exponents efficiently, commonly used in various computational and mathematical applications. Its ability to work in logarithmic time makes it indispensable for performance-critical systems. -tags: [java, problem-solving] ---- - -# Fast Exponential - -## Description: - -Fast Exponentiation is an algorithm to compute powers of numbers efficiently, typically used to calculate a^b%c. The common approach is Exponentiation by Squaring, which reduces the time complexity to $O(log n)$. - -**Key Points:** - -**1. Base and Modulo:** Initialize base to be within modulo. - -**2. Loop Until Exp is Zero:** - -> *Odd Exponent:* If exp is odd (exp & 1), multiply result by base and take modulo. - -> *Update Base and Exponent:* Square the base and halve the exp. - -**3. Return Result:** Final result after computing power modulo. - -## Efficiency: - -This algorithm runs in $O(log n)$ time, making it very efficient for large exponents. - -# Code in Java: - -```java -public class FastExpo { - - public static int fastExpo(int a, int n) { - int ans = 1; - - while(n>0) { - if((n&1) != 0) { - ans = ans*a; - } - a=a*a; - n=n>>1; - } - return ans; - } - public static void main(String[] args) { - System.out.println(fastExpo(2, 4)); - } -} -``` diff --git a/java/inheritance.md b/java/inheritance.md deleted file mode 100644 index 2d1c63b2f..000000000 --- a/java/inheritance.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -id: array-list -sidebar_position: 2 -title: Inheritance -sidebar_label: inheritance -description: Inheritance is a core concept in object-oriented programming (OOP) that allows you to create new classes (subclasses or child classes) that inherit properties and behaviors from existing classes (superclasses or parent classes). This promotes code reusability and helps in creating well-structured and maintainable software systems. -tags: [java, inheritance, class] ---- - -**Inheritance in Java** - -Inheritance is a core concept in object-oriented programming (OOP) that allows you to create new classes (subclasses or child classes) that inherit properties and behaviors from existing classes (superclasses or parent classes). This promotes code reusability and helps in creating well-structured and maintainable software systems. - -**Types of Inheritance** - -1. **Single Inheritance:** A class inherits from only one parent class. - ```java - class Animal { - public void eat() { - System.out.println("Animal is eating."); - } - } - - class Dog extends Animal { - public void bark() { - System.out.println("Dog is barking."); - } - } - ``` -2. **Hierarchical Inheritance:** Multiple classes inherit from a single parent class. - ```java - class Vehicle { - public void move() { - System.out.println("Vehicle is moving."); - } - } - - class Car extends Vehicle { - public void accelerate() { - System.out.println("Car is accelerating."); - } - } - - class Bike extends Vehicle { - public void brake() { - System.out.println("Bike is braking."); - } - } - ``` -3. **Multilevel Inheritance:** A class inherits from a derived class. - ```java - class Shape { - public void draw() { - System.out.println("Shape is drawn."); - } - } - - class Rectangle extends Shape { - public void area() { - System.out.println("Rectangle area calculated."); - } - } - - class Square extends Rectangle { - public void sideLength() { - System.out.println("Square side length calculated."); - } - } - ``` - -**Key Points** - -* **`extends` keyword:** Used to establish an inheritance relationship. -* **Inheritance Hierarchy:** The chain of classes that inherit from each other. -* **Method Overriding:** Redefining a method in a subclass with the same signature as the parent class. -* **Method Overloading:** Defining multiple methods with the same name but different parameters in a class. - -**Benefits of Inheritance** - -* **Code Reusability:** Avoids redundant code by inheriting common properties and behaviors. -* **Modularity:** Encourages the creation of smaller, more focused classes. -* **Polymorphism:** Allows objects of different classes to be treated as objects of a common superclass. - -**Important Considerations** - -* **Access Modifiers:** Determine the visibility of class members. -* **Constructor Chaining:** Subclass constructors can call superclass constructors using the `super` keyword. -* **Object-Oriented Design Principles:** Follow SOLID principles for effective inheritance design. - -By understanding inheritance, you can create more efficient, flexible, and maintainable Java applications. diff --git a/java/isPowerOfTwo.md b/java/isPowerOfTwo.md deleted file mode 100644 index 7c779b26b..000000000 --- a/java/isPowerOfTwo.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -id: is-power-of-two -sidebar_position: 1 -title: check isPowerOfTwo -sidebar_label: Is power of two? -description: "In this we need to determine if a given integer is a power of two. An integer is a power of two if it can be written as 2^𝑛 where 𝑛 is a non-negative integer." -tags: [java, problem-solving] ---- - -# isPowerOfTwo -## Description: - -The isPowerOfTwo problem is a common question where we need to determine if a given integer is a power of two. An integer is a power of two if it can be written as 2^𝑛 where 𝑛 is a non-negative integer. - -## Approach - -To solve this problem, you can use bit manipulation, which is very efficient. The key observation here is that a number which is a power of two has exactly one bit set to 1 in its binary representation. - -## By Bit Manipulation -**1. Binary Check:** In binary, a power of two has a single '1' followed by zero or more '0's. -**2. Masking Trick:** For a number n, the condition n & (n - 1) will be zero if n is a power of two. - -# Code in Java - -```java -import java.util.*; - -public class isPowerOfTwo { - - public static boolean isPowerOfTwo(int n) { - return (n&(n-1)) == 0; - } - public static void main(String[] args) { - System.out.println(isPowerOfTwo(15)); - } -} -``` - -## Explanation: - -**Bitwise AND Operation:** -> n & (n - 1): This operation turns off the rightmost set bit of n. If n is a power of two, there will be exactly one set bit, so n & (n - 1) will be zero. - -**For example**, 16 in binary is 10000, and 15 is 01111. 16 & 15 = 00000. diff --git a/learn.md b/learn.md deleted file mode 100644 index 036e6ee4d..000000000 --- a/learn.md +++ /dev/null @@ -1,23 +0,0 @@ -# Learn with Algo - -Algo is a comprehensive algorithm repository designed to help developers improve their problem-solving skills. Here's how you can get started and learn from this project: - -## Topics Covered -- Sorting Algorithms -- Searching Algorithms -- Dynamic Programming -- Greedy Algorithms -- Graph Algorithms -- Data Structures - -## How to Use This Repository -1. Clone the repository to your local machine. -2. Browse through the folders to find algorithms categorized by topics. -3. Each algorithm includes: - - A detailed description of the problem - - The solution code - - Time and space complexity analysis - -## Learning Resources -- We recommend starting with **Sorting Algorithms** if you're new to algorithms. -- Each algorithm file is documented with comments and explanations to help you understand the logic and steps involved. diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 22fc8fbc2..000000000 --- a/package-lock.json +++ /dev/null @@ -1,34303 +0,0 @@ -{ - "name": "algo", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "algo", - "version": "0.0.0", - "dependencies": { - "@docusaurus/core": "^3.5.2", - "@docusaurus/plugin-content-blog": "^3.5.2", - "@docusaurus/plugin-content-docs": "^3.5.2", - "@docusaurus/plugin-debug": "^3.5.2", - "@docusaurus/preset-classic": "^3.5.2", - "@docusaurus/theme-mermaid": "^3.5.2", - "@docusaurus/theme-search-algolia": "^3.5.2", - "@fortawesome/free-brands-svg-icons": "^6.6.0", - "@fortawesome/react-fontawesome": "^0.2.2", - "@giscus/react": "^3.0.0", - "@heroicons/react": "^2.1.5", - "@mdx-js/react": "^3.0.0", - "axios": "^1.7.7", - "clsx": "^2.0.0", - "framer-motion": "^11.9.0", - "joi": "^17.13.3", - "mermaid": "^11.0.0", - "prism-react-renderer": "^2.1.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-icons": "^5.3.0", - "react-lite-youtube-embed": "^2.4.0", - "react-simple-chatbot": "^0.6.0", - "react-toastify": "^10.0.5", - "rehype-katex": "^7.0.1", - "remark-math": "^6.0.0", - "styled-components": "^4.4.1", - "swiper": "^11.1.14" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/types": "3.5.2", - "autoprefixer": "^10.4.20", - "gh-pages": "^6.1.0", - "postcss": "^8.4.47", - "tailwindcss": "^3.4.13" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", - "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", - "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", - "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/cache-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", - "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" - }, - "node_modules/@algolia/cache-in-memory": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", - "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/client-account": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", - "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-account/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-account/node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", - "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics/node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.7.0.tgz", - "integrity": "sha512-hrYlN9yNQukmNj8bBlw9PCXi9jmRQqNUXaG6MXH1aDabjO6YD1WPVqTvaELbIBgTbDJzCn0R2owms0uaxQkjUg==", - "peer": true, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", - "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-personalization/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.7.0.tgz", - "integrity": "sha512-0Frfjt4oxvVP2qsTQAjwdaG5SvJ3TbHBkBrS6M7cG5RDrgHqOrhBnBGCFT+YO3CeNK54r+d57oB1VcD2F1lHuQ==", - "peer": true, - "dependencies": { - "@algolia/client-common": "5.7.0", - "@algolia/requester-browser-xhr": "5.7.0", - "@algolia/requester-fetch": "5.7.0", - "@algolia/requester-node-http": "5.7.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/events": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" - }, - "node_modules/@algolia/logger-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", - "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" - }, - "node_modules/@algolia/logger-console": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", - "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", - "dependencies": { - "@algolia/logger-common": "4.24.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", - "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.7.0.tgz", - "integrity": "sha512-ohtIp+lyTGM3agrHyedC3w7ijfdUvSN6wmGuKqUezrNzd0nCkFoLW0OINlyv1ODrTEVnL8PAM/Zqubjafxd/Ww==", - "peer": true, - "dependencies": { - "@algolia/client-common": "5.7.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", - "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" - }, - "node_modules/@algolia/requester-fetch": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.7.0.tgz", - "integrity": "sha512-Eg8cBhNg2QNnDDldyK77aXvg3wIc5qnpCDCAJXQ2oaqZwwvvYaTgnP1ofznNG6+klri4Fk1YAaC9wyDBhByWIA==", - "peer": true, - "dependencies": { - "@algolia/client-common": "5.7.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-node-http": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.7.0.tgz", - "integrity": "sha512-8BDssYEkcp1co06KtHO9b37H+5zVM/h+5kyesJb2C2EHFO3kgzLHWl/JyXOVtYlKQBkmdObYOI0s6JaXRy2yQA==", - "peer": true, - "dependencies": { - "@algolia/client-common": "5.7.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/transporter": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", - "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", - "dependencies": { - "@algolia/cache-common": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@antfu/install-pkg": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", - "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", - "dependencies": { - "package-manager-detector": "^0.2.0", - "tinyexec": "^0.3.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@antfu/utils": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", - "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", - "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/code-frame/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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/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==" - }, - "node_modules/@babel/code-frame/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==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", - "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", - "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/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", - "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", - "dependencies": { - "@babel/types": "^7.23.4", - "@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-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", - "dependencies": { - "@babel/types": "^7.22.15" - }, - "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==", - "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-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", - "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", - "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.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==", - "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==", - "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==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", - "dependencies": { - "@babel/types": "^7.23.0" - }, - "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==", - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "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-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", - "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.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==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "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==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "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==", - "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==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", - "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.4", - "@babel/types": "^7.23.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "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/highlight/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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/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==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/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==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/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==" - }, - "node_modules/@babel/highlight/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==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", - "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", - "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", - "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-async-generator-functions": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", - "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", - "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-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", - "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-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.3.tgz", - "integrity": "sha512-FGEQmugvAEu2QtgtU0uTASXevfLMFfBeVCIIdcQhn/uBQsMTjBajdnAtanQlOcuihWh10PZ7+HWvc7NtBwP74w==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", - "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-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", - "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-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", - "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", - "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-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", - "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-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", - "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-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", - "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", - "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-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", - "dependencies": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", - "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-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", - "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-constant-elements": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.7.tgz", - "integrity": "sha512-/qXt69Em8HgsjCLu7G3zdIQn7A2QwmYND7Wa0LTp09Na+Zn8L5d0A7wSXrKi18TJRc/Q5S1i1De/SU1LzVkSvA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", - "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", - "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": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/types": "^7.23.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", - "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", - "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-runtime": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.4.tgz", - "integrity": "sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw==", - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.6", - "babel-plugin-polyfill-corejs3": "^0.8.5", - "babel-plugin-polyfill-regenerator": "^0.5.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", - "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-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", - "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-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", - "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-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", - "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-typescript": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.4.tgz", - "integrity": "sha512-39hCCOl+YUAyMOu6B9SmUTiHUU0t/CxJNUmY3qRdJujbqi+lrQcL11ysYUsAvFWPBdhihrv1z0oRG84Yr3dODQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", - "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-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.3.tgz", - "integrity": "sha512-ovzGc2uuyNfNAs/jyjIGxS8arOHS5FENZaNn4rtE7UdKMMkqHCvboHfcuhWLZNX5cB44QfcGNWjaevxMzzMf+Q==", - "dependencies": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.3", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.3", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.3", - "@babel/plugin-transform-classes": "^7.23.3", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.3", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.3", - "@babel/plugin-transform-for-of": "^7.23.3", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.3", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.3", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.3", - "@babel/plugin-transform-modules-umd": "^7.23.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.3", - "@babel/plugin-transform-numeric-separator": "^7.23.3", - "@babel/plugin-transform-object-rest-spread": "^7.23.3", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.3", - "@babel/plugin-transform-optional-chaining": "^7.23.3", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.3", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.6", - "babel-plugin-polyfill-corejs3": "^0.8.5", - "babel-plugin-polyfill-regenerator": "^0.5.3", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", - "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-transform-react-display-name": "^7.23.3", - "@babel/plugin-transform-react-jsx": "^7.22.15", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", - "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-typescript": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, - "node_modules/@babel/runtime": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", - "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.4.tgz", - "integrity": "sha512-zQyB4MJGM+rvd4pM58n26kf3xbiitw9MHzL8oLiBMKb8MCtVDfV5nDzzJWWzLMtbvKI9wN6XwJYl479qF4JluQ==", - "dependencies": { - "core-js-pure": "^3.30.2", - "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==", - "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.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", - "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", - "dependencies": { - "@babel/code-frame": "^7.23.4", - "@babel/generator": "^7.23.4", - "@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.4", - "@babel/types": "^7.23.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", - "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", - "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@blakeembrey/deque": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@blakeembrey/deque/-/deque-1.0.5.tgz", - "integrity": "sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg==" - }, - "node_modules/@braintree/sanitize-url": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", - "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" - }, - "node_modules/@chevrotain/cst-dts-gen": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", - "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", - "dependencies": { - "@chevrotain/gast": "11.0.3", - "@chevrotain/types": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "node_modules/@chevrotain/gast": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", - "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", - "dependencies": { - "@chevrotain/types": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "node_modules/@chevrotain/regexp-to-ast": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", - "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" - }, - "node_modules/@chevrotain/types": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", - "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" - }, - "node_modules/@chevrotain/utils": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", - "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.2.tgz", - "integrity": "sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw==" - }, - "node_modules/@docsearch/react": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.2.tgz", - "integrity": "sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA==", - "dependencies": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.6.2", - "algoliasearch": "^4.19.1" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 19.0.0", - "react": ">= 16.8.0 < 19.0.0", - "react-dom": ">= 16.8.0 < 19.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@docusaurus/core": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.5.2.tgz", - "integrity": "sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==", - "dependencies": { - "@babel/core": "^7.23.3", - "@babel/generator": "^7.23.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/preset-react": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "@babel/runtime": "^7.22.6", - "@babel/runtime-corejs3": "^7.22.6", - "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "autoprefixer": "^10.4.14", - "babel-loader": "^9.1.3", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.2", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.31.1", - "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^5.0.1", - "cssnano": "^6.1.2", - "del": "^6.1.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "eval": "^0.1.8", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "html-minifier-terser": "^7.2.0", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.5.3", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.7.6", - "p-map": "^4.0.0", - "postcss": "^8.4.26", - "postcss-loader": "^7.3.3", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "rtl-detect": "^1.0.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.5", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "url-loader": "^4.1.1", - "webpack": "^5.88.1", - "webpack-bundle-analyzer": "^4.9.0", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.9.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@mdx-js/react": "^3.0.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/cssnano-preset": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.5.2.tgz", - "integrity": "sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==", - "dependencies": { - "cssnano-preset-advanced": "^6.1.2", - "postcss": "^8.4.38", - "postcss-sort-media-queries": "^5.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/logger": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.5.2.tgz", - "integrity": "sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/mdx-loader": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.5.2.tgz", - "integrity": "sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==", - "dependencies": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^1.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/module-type-aliases": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.5.2.tgz", - "integrity": "sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==", - "dependencies": { - "@docusaurus/types": "3.5.2", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.5.2.tgz", - "integrity": "sha512-R7ghWnMvjSf+aeNDH0K4fjyQnt5L0KzUEnUhmf1e3jZrv3wogeytZNN6n7X8yHcMsuZHPOrctQhXWnmxu+IRRg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "cheerio": "1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "reading-time": "^1.5.0", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.5.2.tgz", - "integrity": "sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-debug": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.5.2.tgz", - "integrity": "sha512-kBK6GlN0itCkrmHuCS6aX1wmoWc5wpd5KJlqQ1FyrF0cLDnvsYSnh7+ftdwzt7G6lGBho8lrVwkkL9/iQvaSOA==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^1.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.5.2.tgz", - "integrity": "sha512-rjEkJH/tJ8OXRE9bwhV2mb/WP93V441rD6XnM6MIluu7rk8qg38iSxS43ga2V2Q/2ib53PcqbDEJDG/yWQRJhQ==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.5.2.tgz", - "integrity": "sha512-lm8XL3xLkTPHFKKjLjEEAHUrW0SZBSHBE1I+i/tmYMBsjCcUB5UJ52geS5PSiOCFVR74tbPGcPHEV/gaaxFeSA==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.5.2.tgz", - "integrity": "sha512-QkpX68PMOMu10Mvgvr5CfZAzZQFx8WLlOiUQ/Qmmcl6mjGK6H21WLT5x7xDmcpCoKA/3CegsqIqBR+nA137lQg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.5.2.tgz", - "integrity": "sha512-DnlqYyRAdQ4NHY28TfHuVk414ft2uruP4QWCH//jzpHjqvKyXjj2fmDtI8RPUBh9K8iZKFMHRnLtzJKySPWvFA==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/preset-classic": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.5.2.tgz", - "integrity": "sha512-3ihfXQ95aOHiLB5uCu+9PRy2gZCeSZoDcqpnDvf3B+sTrMvMTr8qRUzBvWkoIqc82yG5prCboRjk1SVILKx6sg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/plugin-content-blog": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/plugin-content-pages": "3.5.2", - "@docusaurus/plugin-debug": "3.5.2", - "@docusaurus/plugin-google-analytics": "3.5.2", - "@docusaurus/plugin-google-gtag": "3.5.2", - "@docusaurus/plugin-google-tag-manager": "3.5.2", - "@docusaurus/plugin-sitemap": "3.5.2", - "@docusaurus/theme-classic": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-search-algolia": "3.5.2", - "@docusaurus/types": "3.5.2" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/preset-classic/node_modules/@docusaurus/plugin-content-pages": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", - "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-classic": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.5.2.tgz", - "integrity": "sha512-XRpinSix3NBv95Rk7xeMF9k4safMkwnpSgThn0UNQNumKvmcIYjfkwfh2BhwYh/BxMXQHJ/PdmNh22TQFpIaYg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/plugin-content-blog": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/plugin-content-pages": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-translations": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.44", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.4.26", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/plugin-content-pages": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", - "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-common": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.5.2.tgz", - "integrity": "sha512-QXqlm9S6x9Ibwjs7I2yEDgsCocp708DrCrgHgKwg2n2AY0YQ6IjU0gAK35lHRLOvAoJUfCKpQAwUykB0R7+Eew==", - "dependencies": { - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.5.2.tgz", - "integrity": "sha512-7vWCnIe/KoyTN1Dc55FIyqO5hJ3YaV08Mr63Zej0L0mX1iGzt+qKSmeVUAJ9/aOalUhF0typV0RmNUSy5FAmCg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "mermaid": "^10.4.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "dependencies": { - "@types/unist": "^2" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/mermaid": { - "version": "10.9.3", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.3.tgz", - "integrity": "sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==", - "license": "MIT", - "dependencies": { - "@braintree/sanitize-url": "^6.0.1", - "@types/d3-scale": "^4.0.3", - "@types/d3-scale-chromatic": "^3.0.0", - "cytoscape": "^3.28.1", - "cytoscape-cose-bilkent": "^4.1.0", - "d3": "^7.4.0", - "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.10", - "dayjs": "^1.11.7", - "dompurify": "^3.0.5 <3.1.7", - "elkjs": "^0.9.0", - "katex": "^0.16.9", - "khroma": "^2.0.0", - "lodash-es": "^4.17.21", - "mdast-util-from-markdown": "^1.3.0", - "non-layered-tidy-tree-layout": "^2.0.2", - "stylis": "^4.1.3", - "ts-dedent": "^2.2.0", - "uuid": "^9.0.0", - "web-worker": "^1.2.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@docusaurus/theme-mermaid/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.5.2.tgz", - "integrity": "sha512-qW53kp3VzMnEqZGjakaV90sst3iN1o32PH+nawv1uepROO8aEGxptcq2R5rsv7aBShSRbZwIobdvSYKsZ5pqvA==", - "dependencies": { - "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-translations": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "algoliasearch": "^4.18.0", - "algoliasearch-helper": "^3.13.3", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-translations": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.5.2.tgz", - "integrity": "sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==", - "dependencies": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/types": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.5.2.tgz", - "integrity": "sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/utils": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.5.2.tgz", - "integrity": "sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==", - "dependencies": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@svgr/webpack": "^8.1.0", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "prompts": "^2.4.2", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/utils-common": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.5.2.tgz", - "integrity": "sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==", - "dependencies": { - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/utils-validation": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.5.2.tgz", - "integrity": "sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==", - "dependencies": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "fs-extra": "^11.2.0", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "0.7.4" - } - }, - "node_modules/@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "license": "MIT" - }, - "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", - "license": "MIT" - }, - "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==", - "license": "MIT", - "peer": 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/eslint-utils/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==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", - "license": "MIT", - "peer": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.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": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "peer": 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/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/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==", - "license": "MIT", - "peer": true - }, - "node_modules/@eslint/js": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", - "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", - "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", - "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", - "peer": true, - "dependencies": { - "@fortawesome/fontawesome-common-types": "6.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/free-brands-svg-icons": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz", - "integrity": "sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==", - "dependencies": { - "@fortawesome/fontawesome-common-types": "6.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/react-fontawesome": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", - "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", - "dependencies": { - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "@fortawesome/fontawesome-svg-core": "~1 || ~6", - "react": ">=16.3" - } - }, - "node_modules/@giscus/react": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@giscus/react/-/react-3.0.0.tgz", - "integrity": "sha512-hgCjLpg3Wgh8VbTF5p8ZLcIHI74wvDk1VIFv12+eKhenNVUDjgwNg2B1aq/3puyHOad47u/ZSyqiMtohjy/OOA==", - "dependencies": { - "giscus": "^1.5.0" - }, - "peerDependencies": { - "react": "^16 || ^17 || ^18", - "react-dom": "^16 || ^17 || ^18" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@heroicons/react": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.1.5.tgz", - "integrity": "sha512-FuzFN+BsHa+7OxbvAERtgBTNeZpUjgM/MIizfVkSCL2/edriN0Hx/DWRCR//aPYwO5QX/YlgLGXk+E3PcfZwjA==", - "peerDependencies": { - "react": ">= 16" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", - "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.5", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", - "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@humanfs/core": "^0.19.0", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.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==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@iconify/types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" - }, - "node_modules/@iconify/utils": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.1.33.tgz", - "integrity": "sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==", - "dependencies": { - "@antfu/install-pkg": "^0.4.0", - "@antfu/utils": "^0.7.10", - "@iconify/types": "^2.0.0", - "debug": "^4.3.6", - "kolorist": "^1.8.0", - "local-pkg": "^0.5.0", - "mlly": "^1.7.1" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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==", - "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==", - "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==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "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==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" - }, - "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", - "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==" - }, - "node_modules/@lit/reactive-element": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", - "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0" - } - }, - "node_modules/@mdx-js/mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.0.tgz", - "integrity": "sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-to-js": "^2.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/react": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", - "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "node_modules/@mermaid-js/parser": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", - "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==", - "dependencies": { - "langium": "3.0.0" - } - }, - "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==", - "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==", - "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==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "dependencies": { - "graceful-fs": "4.2.10" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "node_modules/@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.23", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", - "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "dependencies": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "dependencies": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/d3": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", - "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", - "dependencies": { - "@types/d3-array": "*", - "@types/d3-axis": "*", - "@types/d3-brush": "*", - "@types/d3-chord": "*", - "@types/d3-color": "*", - "@types/d3-contour": "*", - "@types/d3-delaunay": "*", - "@types/d3-dispatch": "*", - "@types/d3-drag": "*", - "@types/d3-dsv": "*", - "@types/d3-ease": "*", - "@types/d3-fetch": "*", - "@types/d3-force": "*", - "@types/d3-format": "*", - "@types/d3-geo": "*", - "@types/d3-hierarchy": "*", - "@types/d3-interpolate": "*", - "@types/d3-path": "*", - "@types/d3-polygon": "*", - "@types/d3-quadtree": "*", - "@types/d3-random": "*", - "@types/d3-scale": "*", - "@types/d3-scale-chromatic": "*", - "@types/d3-selection": "*", - "@types/d3-shape": "*", - "@types/d3-time": "*", - "@types/d3-time-format": "*", - "@types/d3-timer": "*", - "@types/d3-transition": "*", - "@types/d3-zoom": "*" - } - }, - "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" - }, - "node_modules/@types/d3-axis": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", - "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-brush": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", - "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-chord": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" - }, - "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" - }, - "node_modules/@types/d3-contour": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", - "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", - "dependencies": { - "@types/d3-array": "*", - "@types/geojson": "*" - } - }, - "node_modules/@types/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" - }, - "node_modules/@types/d3-dispatch": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", - "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" - }, - "node_modules/@types/d3-drag": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", - "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-dsv": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" - }, - "node_modules/@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" - }, - "node_modules/@types/d3-fetch": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", - "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", - "dependencies": { - "@types/d3-dsv": "*" - } - }, - "node_modules/@types/d3-force": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==" - }, - "node_modules/@types/d3-format": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" - }, - "node_modules/@types/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", - "dependencies": { - "@types/geojson": "*" - } - }, - "node_modules/@types/d3-hierarchy": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" - }, - "node_modules/@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@types/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" - }, - "node_modules/@types/d3-polygon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" - }, - "node_modules/@types/d3-quadtree": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" - }, - "node_modules/@types/d3-random": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" - }, - "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@types/d3-scale-chromatic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" - }, - "node_modules/@types/d3-selection": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", - "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==" - }, - "node_modules/@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", - "dependencies": { - "@types/d3-path": "*" - } - }, - "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" - }, - "node_modules/@types/d3-time-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" - }, - "node_modules/@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" - }, - "node_modules/@types/d3-transition": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", - "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-zoom": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", - "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", - "dependencies": { - "@types/d3-interpolate": "*", - "@types/d3-selection": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/dompurify": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", - "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", - "dependencies": { - "@types/trusted-types": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", - "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/geojson": { - "version": "7946.0.14", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" - }, - "node_modules/@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" - }, - "node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "node_modules/@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" - }, - "node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdx": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", - "integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" - }, - "node_modules/@types/node": { - "version": "20.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", - "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.10", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", - "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/prismjs": { - "version": "1.26.3", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", - "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.11", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" - }, - "node_modules/@types/qs": { - "version": "6.9.10", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "node_modules/@types/react": { - "version": "18.2.39", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", - "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-config": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.10.tgz", - "integrity": "sha512-Wn6c/tXdEgi9adCMtDwx8Q2vGty6TsPTc/wCQQ9kAlye8UqFxj0vGFWWuhywNfkwqth+SOgJxQTLTZukrqDQmQ==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" - }, - "node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/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/accepts/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/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, - "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==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", - "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/algoliasearch": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", - "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-account": "4.24.0", - "@algolia/client-analytics": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-personalization": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/recommend": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/algoliasearch-helper": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.5.tgz", - "integrity": "sha512-lWvhdnc+aKOKx8jyA3bsdEgHzm/sglC4cYdMG4xSQyRiPLJVJtH/IVYZG3Hp6PkTEhQqhyVYkeP9z2IlcHJsWw==", - "dependencies": { - "@algolia/events": "^4.0.1" - }, - "peerDependencies": { - "algoliasearch": ">= 3.1 < 6" - } - }, - "node_modules/algoliasearch/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/algoliasearch/node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/algoliasearch/node_modules/@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/algoliasearch/node_modules/@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "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==" - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true - }, - "node_modules/async-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", - "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", - "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.3", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", - "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3", - "core-js-compat": "^3.33.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", - "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-styled-components": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", - "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "lodash": "^4.17.21", - "picomatch": "^2.3.1" - }, - "peerDependencies": { - "styled-components": ">= 2" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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==" - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/bonjour-service": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", - "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", - "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/boxen": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^6.2.0", - "chalk": "^4.1.2", - "cli-boxes": "^3.0.0", - "string-width": "^5.0.1", - "type-fest": "^2.5.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", - "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.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request/node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "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==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/camelize": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001664", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz", - "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==", - "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/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chevrotain": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", - "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", - "dependencies": { - "@chevrotain/cst-dts-gen": "11.0.3", - "@chevrotain/gast": "11.0.3", - "@chevrotain/regexp-to-ast": "11.0.3", - "@chevrotain/types": "11.0.3", - "@chevrotain/utils": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "node_modules/chevrotain-allstar": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", - "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", - "dependencies": { - "lodash-es": "^4.17.21" - }, - "peerDependencies": { - "chevrotain": "^11.0.0" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-css": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", - "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "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==" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "node_modules/combine-promises": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", - "engines": { - "node": ">=10" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compressible/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/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "dependencies": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/yeoman/configstore?sponsor=1" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" - }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "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==" - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/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==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/core-js": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", - "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", - "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", - "dependencies": { - "browserslist": "^4.22.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.3.tgz", - "integrity": "sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/cose-base": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", - "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", - "dependencies": { - "layout-base": "^1.0.0" - } - }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": 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==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "dependencies": { - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", - "license": "ISC", - "engines": { - "node": ">=4" - } - }, - "node_modules/css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-loader": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", - "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.21", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.3", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "cssnano": "^6.0.1", - "jest-worker": "^29.4.3", - "postcss": "^8.4.24", - "schema-utils": "^4.0.1", - "serialize-javascript": "^6.0.1" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "lightningcss": { - "optional": true - } - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-to-react-native": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", - "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", - "license": "MIT", - "dependencies": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^3.3.0" - } - }, - "node_modules/css-to-react-native/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "license": "MIT" - }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", - "dependencies": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "dependencies": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "dependencies": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" - }, - "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/cytoscape": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz", - "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/cytoscape-cose-bilkent": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", - "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", - "dependencies": { - "cose-base": "^1.0.0" - }, - "peerDependencies": { - "cytoscape": "^3.2.0" - } - }, - "node_modules/cytoscape-fcose": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", - "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", - "dependencies": { - "cose-base": "^2.2.0" - }, - "peerDependencies": { - "cytoscape": "^3.2.0" - } - }, - "node_modules/cytoscape-fcose/node_modules/cose-base": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", - "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", - "dependencies": { - "layout-base": "^2.0.0" - } - }, - "node_modules/cytoscape-fcose/node_modules/layout-base": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", - "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" - }, - "node_modules/d3": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", - "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", - "dependencies": { - "d3-array": "3", - "d3-axis": "3", - "d3-brush": "3", - "d3-chord": "3", - "d3-color": "3", - "d3-contour": "4", - "d3-delaunay": "6", - "d3-dispatch": "3", - "d3-drag": "3", - "d3-dsv": "3", - "d3-ease": "3", - "d3-fetch": "3", - "d3-force": "3", - "d3-format": "3", - "d3-geo": "3", - "d3-hierarchy": "3", - "d3-interpolate": "3", - "d3-path": "3", - "d3-polygon": "3", - "d3-quadtree": "3", - "d3-random": "3", - "d3-scale": "4", - "d3-scale-chromatic": "3", - "d3-selection": "3", - "d3-shape": "3", - "d3-time": "3", - "d3-time-format": "4", - "d3-timer": "3", - "d3-transition": "3", - "d3-zoom": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "dependencies": { - "internmap": "1 - 2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-axis": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-brush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "3", - "d3-transition": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-chord": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", - "dependencies": { - "d3-path": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-contour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", - "dependencies": { - "d3-array": "^3.2.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "dependencies": { - "delaunator": "5" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "dependencies": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" - }, - "bin": { - "csv2json": "bin/dsv2json.js", - "csv2tsv": "bin/dsv2dsv.js", - "dsv2dsv": "bin/dsv2dsv.js", - "dsv2json": "bin/dsv2json.js", - "json2csv": "bin/json2dsv.js", - "json2dsv": "bin/json2dsv.js", - "json2tsv": "bin/json2dsv.js", - "tsv2csv": "bin/dsv2dsv.js", - "tsv2json": "bin/dsv2json.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dsv/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/d3-dsv/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", - "dependencies": { - "d3-dsv": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", - "dependencies": { - "d3-array": "2.5.0 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-polygon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-sankey": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", - "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", - "dependencies": { - "d3-array": "1 - 2", - "d3-shape": "^1.2.0" - } - }, - "node_modules/d3-sankey/node_modules/d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "dependencies": { - "internmap": "^1.0.0" - } - }, - "node_modules/d3-sankey/node_modules/d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" - }, - "node_modules/d3-sankey/node_modules/d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "dependencies": { - "d3-path": "1" - } - }, - "node_modules/d3-sankey/node_modules/internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" - }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-scale-chromatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", - "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", - "dependencies": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-selection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "dependencies": { - "d3-array": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "dependencies": { - "d3-time": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-transition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "dependencies": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "d3-selection": "2 - 3" - } - }, - "node_modules/d3-zoom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/dagre-d3-es": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", - "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", - "dependencies": { - "d3": "^7.8.2", - "lodash-es": "^4.17.21" - } - }, - "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" - }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "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==", - "license": "MIT", - "peer": true - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "engines": { - "node": ">=8" - } - }, - "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==", - "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/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/delaunator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", - "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", - "dependencies": { - "robust-predicates": "^3.0.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port-alt/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port-alt/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true - }, - "node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true - }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/dompurify": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", - "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==" - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.30", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.30.tgz", - "integrity": "sha512-sXI35EBN4lYxzc/pIGorlymYNzDBOqkSlVRe6MkgBsW/hW1tpC/HDJ2fjG7XnjakzfLEuvdmux0Mjs6jHq4UOA==" - }, - "node_modules/elkjs": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", - "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" - }, - "node_modules/email-addresses": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", - "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/emoticon": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", - "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", - "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.12.0", - "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-config-prettier": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz", - "integrity": "sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA==", - "dependencies": { - "get-stdin": "^6.0.0" - }, - "bin": { - "eslint-config-prettier-check": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=3.14.1" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "peer": 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/eslint/node_modules/eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/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==", - "license": "MIT", - "peer": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "license": "ISC", - "peer": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/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==", - "license": "MIT", - "peer": true - }, - "node_modules/eslint/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==", - "license": "MIT", - "peer": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "license": "MIT", - "peer": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "license": "MIT", - "peer": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/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==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "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==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-value-to-estree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", - "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", - "dependencies": { - "@types/estree": "^1.0.0", - "is-plain-obj": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "url": "https://github.com/eta-dev/eta?sponsor=1" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "dependencies": { - "@types/node": "*", - "require-like": ">= 0.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/express/node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "license": "MIT" - }, - "node_modules/express/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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==" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "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==" - }, - "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==", - "license": "MIT", - "peer": 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==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/feed": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "dependencies": { - "xml-js": "^1.6.11" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/file-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/file-loader/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==" - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "dev": true, - "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "license": "MIT", - "peer": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flat-cache/node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "license": "ISC", - "peer": true - }, - "node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/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==" - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "engines": { - "node": ">= 14.17" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/framer-motion": { - "version": "11.11.11", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.11.tgz", - "integrity": "sha512-tuDH23ptJAKUHGydJQII9PhABNJBpB+z0P1bmgKK9QFIssHGlfPd6kxMq00LSKwE27WFsb2z0ovY0bpUyMvfRw==", - "dependencies": { - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" - }, - "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==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "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==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "node_modules/get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gh-pages": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.2.0.tgz", - "integrity": "sha512-HMXJ8th9u5wRXaZCnLcs/d3oVvCHiZkaP5KQExQljYGwJjQbSPyTdHe/Gc1IvYUR/rWiZLxNobIqfoMHKTKjHQ==", - "dev": true, - "dependencies": { - "async": "^3.2.4", - "commander": "^11.0.0", - "email-addresses": "^5.0.0", - "filenamify": "^4.3.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^11.1.1", - "globby": "^11.1.0" - }, - "bin": { - "gh-pages": "bin/gh-pages.js", - "gh-pages-clean": "bin/gh-pages-clean.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gh-pages/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/gh-pages/node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/gh-pages/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gh-pages/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gh-pages/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gh-pages/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gh-pages/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/gh-pages/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/giscus": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/giscus/-/giscus-1.5.0.tgz", - "integrity": "sha512-t3LL0qbSO3JXq3uyQeKpF5CegstGfKX/0gI6eDe1cmnI7D56R7j52yLdzw4pdKrg3VnufwCgCM3FDz7G1Qr6lg==", - "dependencies": { - "lit": "^3.1.2" - } - }, - "node_modules/github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "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": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" - }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hachure-fill": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", - "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==" - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "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==", - "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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-from-dom": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", - "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", - "dependencies": { - "@types/hast": "^3.0.0", - "hastscript": "^8.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", - "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.1.0", - "hast-util-from-parse5": "^8.0.0", - "parse5": "^7.0.0", - "vfile": "^6.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html-isomorphic": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", - "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-from-dom": "^5.0.0", - "hast-util-from-html": "^2.0.0", - "unist-util-remove-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", - "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.2.0.tgz", - "integrity": "sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-text": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", - "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "engines": { - "node": ">=14" - } - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", - "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "webpack": "^5.20.0" - } - }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", - "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", - "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-size": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", - "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", - "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "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==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/infima": { - "version": "0.2.0-alpha.44", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.44.tgz", - "integrity": "sha512-tuRkUSO/lB3rEhLJk25atwAjgLuzq070+pOW8XcvpHky/YbENnRRdPd85IBkyeTgttmOy5ah+yHYsK1HhUd4lQ==", - "engines": { - "node": ">=12" - } - }, - "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==", - "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==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "engines": { - "node": ">= 0.10" - } - }, - "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/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "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==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "engines": { - "node": ">=6" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", - "license": "MIT" - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "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==", - "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==", - "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==" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "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==", - "license": "MIT", - "peer": 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==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/katex": { - "version": "0.16.11", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", - "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, - "node_modules/katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/khroma": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", - "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" - }, - "node_modules/langium": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", - "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", - "dependencies": { - "chevrotain": "~11.0.3", - "chevrotain-allstar": "~0.3.0", - "vscode-languageserver": "~9.0.1", - "vscode-languageserver-textdocument": "~1.0.11", - "vscode-uri": "~3.0.8" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "dependencies": { - "package-json": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/layout-base": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", - "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "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==", - "license": "MIT", - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/lit": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.0.tgz", - "integrity": "sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw==", - "dependencies": { - "@lit/reactive-element": "^2.0.4", - "lit-element": "^4.1.0", - "lit-html": "^3.2.0" - } - }, - "node_modules/lit-element": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.0.tgz", - "integrity": "sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0", - "@lit/reactive-element": "^2.0.4", - "lit-html": "^3.2.0" - } - }, - "node_modules/lit-html": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.0.tgz", - "integrity": "sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA==", - "dependencies": { - "@types/trusted-types": "^2.0.2" - } - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "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==", - "license": "MIT", - "peer": true - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/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/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/marked": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", - "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", - "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-math": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", - "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "longest-streak": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.1.0", - "unist-util-remove-position": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", - "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", - "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", - "license": "MIT" - }, - "node_modules/merge-anything": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz", - "integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==", - "license": "MIT", - "dependencies": { - "is-what": "^3.3.1" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/mermaid": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.0.tgz", - "integrity": "sha512-mxCfEYvADJqOiHfGpJXLs4/fAjHz448rH0pfY5fAoxiz70rQiDSzUUy4dNET2T08i46IVpjohPd6WWbzmRHiPA==", - "dependencies": { - "@braintree/sanitize-url": "^7.0.1", - "@iconify/utils": "^2.1.32", - "@mermaid-js/parser": "^0.3.0", - "@types/d3": "^7.4.3", - "@types/dompurify": "^3.0.5", - "cytoscape": "^3.29.2", - "cytoscape-cose-bilkent": "^4.1.0", - "cytoscape-fcose": "^2.2.0", - "d3": "^7.9.0", - "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.11", - "dayjs": "^1.11.10", - "dompurify": "^3.0.11 <3.1.7", - "katex": "^0.16.9", - "khroma": "^2.1.0", - "lodash-es": "^4.17.21", - "marked": "^13.0.2", - "roughjs": "^4.6.6", - "stylis": "^4.3.1", - "ts-dedent": "^2.2.0", - "uuid": "^9.0.1" - } - }, - "node_modules/mermaid/node_modules/@braintree/sanitize-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz", - "integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==" - }, - "node_modules/mermaid/node_modules/dagre-d3-es": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", - "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", - "dependencies": { - "d3": "^7.9.0", - "lodash-es": "^4.17.21" - } - }, - "node_modules/mermaid/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", - "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-math": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", - "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", - "dependencies": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-math/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", - "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-factory-space/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-character/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", - "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", - "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.7.6", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", - "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", - "dependencies": { - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mlly": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", - "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.1", - "ufo": "^1.5.3" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/mrmime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", - "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nan": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", - "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", - "optional": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "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/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT", - "peer": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" - }, - "node_modules/non-layered-tidy-tree-layout": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", - "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "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-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "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==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "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.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "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==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onchange": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/onchange/-/onchange-5.2.0.tgz", - "integrity": "sha512-kBNMF4KU1m0GkZCANckQZs3N41esf950T/gv7JIjNS6qWS8R34+iCKk/wmVRPEdaYCA+yi2aK2vNXS0RaB/V2A==", - "dependencies": { - "@blakeembrey/deque": "^1.0.3", - "arrify": "^1.0.1", - "chokidar": "^2.0.0", - "cross-spawn": "^6.0.0", - "minimist": "^1.2.0", - "supports-color": "^5.5.0", - "tree-kill": "^1.2.0" - }, - "bin": { - "onchange": "cli.js" - } - }, - "node_modules/onchange/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/onchange/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/onchange/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/onchange/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/onchange/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/onchange/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/onchange/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/onchange/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/onchange/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/onchange/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/onchange/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/onchange/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/onchange/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/onchange/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/onchange/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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/onchange/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/onchange/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "peer": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "dependencies": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true - }, - "node_modules/package-manager-detector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.0.tgz", - "integrity": "sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==" - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "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==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-numeric-range": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-data-parser": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", - "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==" - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==" - }, - "node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" - }, - "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==", - "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==" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz", - "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==", - "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.7.1", - "pathe": "^1.1.2" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/points-on-curve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", - "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==" - }, - "node_modules/points-on-path": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", - "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", - "dependencies": { - "path-data-parser": "0.1.0", - "points-on-curve": "0.2.0" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "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.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "colord": "^2.9.3", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-convert-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-comments": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-empty": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/postcss-load-config/node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "dev": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/postcss-loader": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.3.tgz", - "integrity": "sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA==", - "dependencies": { - "cosmiconfig": "^8.2.0", - "jiti": "^1.18.2", - "semver": "^7.3.8" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-merge-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-rules": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", - "dependencies": { - "colord": "^2.9.3", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-params": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", - "dependencies": { - "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", - "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-string": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-ordered-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-sort-media-queries": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", - "dependencies": { - "sort-css-media-queries": "2.2.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.4.23" - } - }, - "node_modules/postcss-svgo": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - }, - "engines": { - "node": "^14 || ^16 || >= 18" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "node_modules/postcss-zindex": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "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==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/prism-react-renderer": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.0.tgz", - "integrity": "sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw==", - "dependencies": { - "@types/prismjs": "^1.26.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.0.0" - } - }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "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/property-information": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", - "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", - "dependencies": { - "escape-goat": "^4.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dependencies": { - "inherits": "~2.0.3" - } - }, - "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==", - "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/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/random-id": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/random-id/-/random-id-0.0.2.tgz", - "integrity": "sha512-e1E0fCzmRQcSxeAFnCybHkVi4filc7c07INtA1BAjKFRfKyO+upZ3q0OhxMnyJ2PRwTSpy/jiMN0ZXwLtyQaBw==", - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" - }, - "node_modules/react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-icons": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", - "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", - "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-json-view-lite": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", - "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-lite-youtube-embed": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/react-lite-youtube-embed/-/react-lite-youtube-embed-2.4.0.tgz", - "integrity": "sha512-Xo6cM1zPlROvvM97JkqQIoXstlQDaC4+DawmM7BB7Hh1cXrkBHEGq1iJlQxBTUWAUklmpcC7ph7qg7CztXtABQ==", - "peerDependencies": { - "react": ">=18.2.0", - "react-dom": ">=18.2.0" - } - }, - "node_modules/react-loadable": { - "name": "@docusaurus/react-loadable", - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", - "dependencies": { - "@types/react": "*" - }, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "dependencies": { - "@babel/runtime": "^7.10.3" - }, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "react-loadable": "*", - "webpack": ">=4.41.1 || 5.x" - } - }, - "node_modules/react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router-config": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "dependencies": { - "@babel/runtime": "^7.1.2" - }, - "peerDependencies": { - "react": ">=15", - "react-router": ">=5" - } - }, - "node_modules/react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-simple-chatbot": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/react-simple-chatbot/-/react-simple-chatbot-0.6.1.tgz", - "integrity": "sha512-q9y5GXwBvD+YvLgDVyDuZHYMkrcgIirm1FVV9RkR7XojPmbiX1lCzT6ib8U1M5zh42kTUBRnszXzkAGm9e0K8w==", - "dependencies": { - "eslint-config-prettier": "^4.1.0", - "eslint-plugin-prettier": "^3.0.1", - "flatted": "^2.0.0", - "onchange": "^5.2.0", - "prettier": "^1.16.4", - "prop-types": "^15.6.0", - "random-id": "0.0.2", - "react": "^16.4.1", - "react-dom": "^16.4.1" - }, - "peerDependencies": { - "react": "^16.3.0", - "react-dom": "^16.3.0", - "styled-components": "^4.0.0" - } - }, - "node_modules/react-simple-chatbot/node_modules/react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-simple-chatbot/node_modules/react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - }, - "peerDependencies": { - "react": "^16.14.0" - } - }, - "node_modules/react-simple-chatbot/node_modules/scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "node_modules/react-toastify": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.6.tgz", - "integrity": "sha512-yYjp+omCDf9lhZcrZHKbSq7YMuK0zcYkDFTzfRFgTXkTFHZ1ToxwAonzA4JI5CxA91JpjFLmwEsZEgfYfOqI1A==", - "dependencies": { - "clsx": "^2.1.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reading-time": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "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/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "dependencies": { - "rc": "1.2.8" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/rehype-katex": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", - "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/katex": "^0.16.0", - "hast-util-from-html-isomorphic": "^2.0.0", - "hast-util-to-text": "^4.0.0", - "katex": "^0.16.0", - "unist-util-visit-parents": "^6.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remark-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", - "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-emoji": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", - "dependencies": { - "@types/mdast": "^4.0.2", - "emoticon": "^4.0.1", - "mdast-util-find-and-replace": "^3.0.1", - "node-emoji": "^2.1.0", - "unified": "^11.0.4" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-math": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", - "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-math": "^3.0.0", - "micromark-extension-math": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", - "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz", - "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/renderkid/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/renderkid/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", - "engines": { - "node": "*" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.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-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated" - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "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==", - "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==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" - }, - "node_modules/roughjs": { - "version": "4.6.6", - "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", - "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", - "dependencies": { - "hachure-fill": "^0.5.2", - "path-data-parser": "^0.1.0", - "points-on-curve": "^0.2.0", - "points-on-path": "^0.2.1" - } - }, - "node_modules/rtl-detect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", - "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" - }, - "node_modules/rtlcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", - "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0", - "postcss": "^8.4.21", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "rtlcss": "bin/rtlcss.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "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==", - "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/rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" - }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/search-insights": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", - "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", - "peer": true - }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-handler": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", - "license": "MIT", - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "3.3.0", - "range-parser": "1.2.0" - } - }, - "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", - "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", - "license": "MIT" - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "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==", - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/sirv": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", - "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", - "dependencies": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/sitemap": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", - "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "bin": { - "sitemap": "dist/cli.js" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=5.6.0" - } - }, - "node_modules/sitemap/node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "node_modules/skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sort-css-media-queries": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", - "engines": { - "node": ">= 6.3.0" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated" - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/std-env": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.5.0.tgz", - "integrity": "sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA==" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "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-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "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==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer/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/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/styled-components": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz", - "integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@emotion/is-prop-valid": "^0.8.1", - "@emotion/unitless": "^0.7.0", - "babel-plugin-styled-components": ">= 1", - "css-to-react-native": "^2.2.2", - "memoize-one": "^5.0.0", - "merge-anything": "^2.2.4", - "prop-types": "^15.5.4", - "react-is": "^16.6.0", - "stylis": "^3.5.0", - "stylis-rule-sheet": "^0.0.10", - "supports-color": "^5.5.0" - }, - "peerDependencies": { - "react": ">= 16.3.0", - "react-dom": ">= 16.3.0" - } - }, - "node_modules/styled-components/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==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/styled-components/node_modules/stylis": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", - "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==", - "license": "MIT" - }, - "node_modules/styled-components/node_modules/stylis-rule-sheet": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", - "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==", - "license": "MIT", - "peerDependencies": { - "stylis": "^3.5.0" - } - }, - "node_modules/styled-components/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==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylehacks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/stylis": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", - "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/sucrase/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sucrase/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sucrase/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/swiper": { - "version": "11.1.14", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.1.14.tgz", - "integrity": "sha512-VbQLQXC04io6AoAjIUWuZwW4MSYozkcP9KjLdrsG/00Q/yiwvhz9RQyt0nHXV10hi9NVnDNy1/wv7Dzq1lkOCQ==", - "funding": [ - { - "type": "patreon", - "url": "https://www.patreon.com/swiperjs" - }, - { - "type": "open_collective", - "url": "http://opencollective.com/swiper" - } - ], - "engines": { - "node": ">= 4.7.0" - } - }, - "node_modules/tailwindcss": { - "version": "3.4.14", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", - "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", - "dev": true, - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/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/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.35.0.tgz", - "integrity": "sha512-TmYbQnzVfrx3RQsPoItoPplymixIAtp2R2xlpyVBYmFmvI34IzLhCLj8SimRb/kZXlq4t1gA+vbcTqLQ3+5Q5g==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/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==" - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "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==" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "node_modules/tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "node_modules/tinyexec": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", - "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==" - }, - "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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/trim-repeated/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/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", - "engines": { - "node": ">=6.10" - } - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true - }, - "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==", - "license": "MIT", - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/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==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/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==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", - "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", - "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==" - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "dependencies": { - "crypto-random-string": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "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.2.0", - "picocolors": "^1.1.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/update-notifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", - "dependencies": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", - "configstore": "^6.0.0", - "has-yarn": "^3.0.0", - "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", - "is-installed-globally": "^0.4.0", - "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", - "latest-version": "^7.0.0", - "pupa": "^3.1.0", - "semver": "^7.3.7", - "semver-diff": "^4.0.0", - "xdg-basedir": "^5.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated" - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/url-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/url-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/url-loader/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==" - }, - "node_modules/url-loader/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/url-loader/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/url-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "node_modules/utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/uvu": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", - "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", - "dependencies": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - }, - "bin": { - "uvu": "bin.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/uvu/node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vscode-jsonrpc": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", - "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/vscode-languageserver": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", - "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", - "dependencies": { - "vscode-languageserver-protocol": "3.17.5" - }, - "bin": { - "installServerIntoExtension": "bin/installServerIntoExtension" - } - }, - "node_modules/vscode-languageserver-protocol": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", - "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", - "dependencies": { - "vscode-jsonrpc": "8.2.0", - "vscode-languageserver-types": "3.17.5" - } - }, - "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", - "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" - }, - "node_modules/vscode-languageserver-types": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" - }, - "node_modules/vscode-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" - }, - "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - }, - "node_modules/webpack": { - "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", - "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "is-plain-object": "^5.0.0", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/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/webpack-dev-middleware/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/webpack-dev-middleware/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/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==" - }, - "node_modules/webpack/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/webpack/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/webpack/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpackbar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", - "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.3", - "pretty-time": "^1.1.0", - "std-env": "^3.0.1" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "webpack": "3 || 4 || 5" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "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==" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xml-js": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "dependencies": { - "sax": "^1.2.4" - }, - "bin": { - "xml-js": "bin/cli.js" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - }, - "dependencies": { - "@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", - "requires": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", - "requires": { - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", - "requires": { - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", - "requires": {} - }, - "@algolia/cache-browser-local-storage": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", - "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", - "requires": { - "@algolia/cache-common": "4.24.0" - } - }, - "@algolia/cache-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", - "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" - }, - "@algolia/cache-in-memory": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", - "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", - "requires": { - "@algolia/cache-common": "4.24.0" - } - }, - "@algolia/client-account": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", - "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/transporter": "4.24.0" - }, - "dependencies": { - "@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "requires": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - } - } - }, - "@algolia/client-analytics": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", - "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - }, - "dependencies": { - "@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "requires": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - } - } - }, - "@algolia/client-common": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.7.0.tgz", - "integrity": "sha512-hrYlN9yNQukmNj8bBlw9PCXi9jmRQqNUXaG6MXH1aDabjO6YD1WPVqTvaELbIBgTbDJzCn0R2owms0uaxQkjUg==", - "peer": true - }, - "@algolia/client-personalization": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", - "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - }, - "dependencies": { - "@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "requires": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - } - } - }, - "@algolia/client-search": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.7.0.tgz", - "integrity": "sha512-0Frfjt4oxvVP2qsTQAjwdaG5SvJ3TbHBkBrS6M7cG5RDrgHqOrhBnBGCFT+YO3CeNK54r+d57oB1VcD2F1lHuQ==", - "peer": true, - "requires": { - "@algolia/client-common": "5.7.0", - "@algolia/requester-browser-xhr": "5.7.0", - "@algolia/requester-fetch": "5.7.0", - "@algolia/requester-node-http": "5.7.0" - } - }, - "@algolia/events": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" - }, - "@algolia/logger-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", - "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" - }, - "@algolia/logger-console": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", - "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", - "requires": { - "@algolia/logger-common": "4.24.0" - } - }, - "@algolia/recommend": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", - "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", - "requires": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - }, - "dependencies": { - "@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "requires": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "requires": { - "@algolia/requester-common": "4.24.0" - } - }, - "@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "requires": { - "@algolia/requester-common": "4.24.0" - } - } - } - }, - "@algolia/requester-browser-xhr": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.7.0.tgz", - "integrity": "sha512-ohtIp+lyTGM3agrHyedC3w7ijfdUvSN6wmGuKqUezrNzd0nCkFoLW0OINlyv1ODrTEVnL8PAM/Zqubjafxd/Ww==", - "peer": true, - "requires": { - "@algolia/client-common": "5.7.0" - } - }, - "@algolia/requester-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", - "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" - }, - "@algolia/requester-fetch": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.7.0.tgz", - "integrity": "sha512-Eg8cBhNg2QNnDDldyK77aXvg3wIc5qnpCDCAJXQ2oaqZwwvvYaTgnP1ofznNG6+klri4Fk1YAaC9wyDBhByWIA==", - "peer": true, - "requires": { - "@algolia/client-common": "5.7.0" - } - }, - "@algolia/requester-node-http": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.7.0.tgz", - "integrity": "sha512-8BDssYEkcp1co06KtHO9b37H+5zVM/h+5kyesJb2C2EHFO3kgzLHWl/JyXOVtYlKQBkmdObYOI0s6JaXRy2yQA==", - "peer": true, - "requires": { - "@algolia/client-common": "5.7.0" - } - }, - "@algolia/transporter": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", - "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", - "requires": { - "@algolia/cache-common": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/requester-common": "4.24.0" - } - }, - "@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true - }, - "@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@antfu/install-pkg": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", - "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", - "requires": { - "package-manager-detector": "^0.2.0", - "tinyexec": "^0.3.0" - } - }, - "@antfu/utils": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", - "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==" - }, - "@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", - "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "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==" - }, - "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==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/compat-data": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", - "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==" - }, - "@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/generator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", - "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", - "requires": { - "@babel/types": "^7.23.4", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", - "requires": { - "@babel/types": "^7.22.15" - } - }, - "@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==", - "requires": { - "@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" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", - "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", - "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", - "requires": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - } - }, - "@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==" - }, - "@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==", - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", - "requires": { - "@babel/types": "^7.23.0" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.22.15" - } - }, - "@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "requires": { - "@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" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", - "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" - } - }, - "@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", - "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" - }, - "@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==" - }, - "@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==" - }, - "@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", - "requires": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" - } - }, - "@babel/helpers": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", - "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", - "requires": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.4", - "@babel/types": "^7.23.4" - } - }, - "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "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==" - }, - "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==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", - "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==" - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" - } - }, - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", - "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", - "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "requires": {} - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-async-generator-functions": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", - "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", - "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", - "requires": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.3.tgz", - "integrity": "sha512-FGEQmugvAEu2QtgtU0uTASXevfLMFfBeVCIIdcQhn/uBQsMTjBajdnAtanQlOcuihWh10PZ7+HWvc7NtBwP74w==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", - "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", - "requires": { - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", - "requires": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", - "requires": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", - "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", - "requires": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", - "requires": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", - "requires": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" - } - }, - "@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-react-constant-elements": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.7.tgz", - "integrity": "sha512-/qXt69Em8HgsjCLu7G3zdIQn7A2QwmYND7Wa0LTp09Na+Zn8L5d0A7wSXrKi18TJRc/Q5S1i1De/SU1LzVkSvA==", - "requires": { - "@babel/helper-plugin-utils": "^7.25.7" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", - "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/types": "^7.23.4" - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", - "requires": { - "@babel/plugin-transform-react-jsx": "^7.22.5" - } - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", - "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.4.tgz", - "integrity": "sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw==", - "requires": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.6", - "babel-plugin-polyfill-corejs3": "^0.8.5", - "babel-plugin-polyfill-regenerator": "^0.5.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.4.tgz", - "integrity": "sha512-39hCCOl+YUAyMOu6B9SmUTiHUU0t/CxJNUmY3qRdJujbqi+lrQcL11ysYUsAvFWPBdhihrv1z0oRG84Yr3dODQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.23.3" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/preset-env": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.3.tgz", - "integrity": "sha512-ovzGc2uuyNfNAs/jyjIGxS8arOHS5FENZaNn4rtE7UdKMMkqHCvboHfcuhWLZNX5cB44QfcGNWjaevxMzzMf+Q==", - "requires": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.3", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.3", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.3", - "@babel/plugin-transform-classes": "^7.23.3", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.3", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.3", - "@babel/plugin-transform-for-of": "^7.23.3", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.3", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.3", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.3", - "@babel/plugin-transform-modules-umd": "^7.23.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.3", - "@babel/plugin-transform-numeric-separator": "^7.23.3", - "@babel/plugin-transform-object-rest-spread": "^7.23.3", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.3", - "@babel/plugin-transform-optional-chaining": "^7.23.3", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.3", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.6", - "babel-plugin-polyfill-corejs3": "^0.8.5", - "babel-plugin-polyfill-regenerator": "^0.5.3", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-react": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", - "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-transform-react-display-name": "^7.23.3", - "@babel/plugin-transform-react-jsx": "^7.22.15", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.23.3" - } - }, - "@babel/preset-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", - "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-typescript": "^7.23.3" - } - }, - "@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, - "@babel/runtime": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", - "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", - "requires": { - "regenerator-runtime": "^0.14.0" - } - }, - "@babel/runtime-corejs3": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.4.tgz", - "integrity": "sha512-zQyB4MJGM+rvd4pM58n26kf3xbiitw9MHzL8oLiBMKb8MCtVDfV5nDzzJWWzLMtbvKI9wN6XwJYl479qF4JluQ==", - "requires": { - "core-js-pure": "^3.30.2", - "regenerator-runtime": "^0.14.0" - } - }, - "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/traverse": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", - "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", - "requires": { - "@babel/code-frame": "^7.23.4", - "@babel/generator": "^7.23.4", - "@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.4", - "@babel/types": "^7.23.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", - "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@blakeembrey/deque": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@blakeembrey/deque/-/deque-1.0.5.tgz", - "integrity": "sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg==" - }, - "@braintree/sanitize-url": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", - "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" - }, - "@chevrotain/cst-dts-gen": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", - "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", - "requires": { - "@chevrotain/gast": "11.0.3", - "@chevrotain/types": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "@chevrotain/gast": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", - "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", - "requires": { - "@chevrotain/types": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "@chevrotain/regexp-to-ast": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", - "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" - }, - "@chevrotain/types": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", - "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" - }, - "@chevrotain/utils": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", - "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" - }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "optional": true - }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" - }, - "@docsearch/css": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.2.tgz", - "integrity": "sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw==" - }, - "@docsearch/react": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.2.tgz", - "integrity": "sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA==", - "requires": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.6.2", - "algoliasearch": "^4.19.1" - } - }, - "@docusaurus/core": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.5.2.tgz", - "integrity": "sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==", - "requires": { - "@babel/core": "^7.23.3", - "@babel/generator": "^7.23.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/preset-react": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "@babel/runtime": "^7.22.6", - "@babel/runtime-corejs3": "^7.22.6", - "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "autoprefixer": "^10.4.14", - "babel-loader": "^9.1.3", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.2", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.31.1", - "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^5.0.1", - "cssnano": "^6.1.2", - "del": "^6.1.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "eval": "^0.1.8", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "html-minifier-terser": "^7.2.0", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.5.3", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.7.6", - "p-map": "^4.0.0", - "postcss": "^8.4.26", - "postcss-loader": "^7.3.3", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "rtl-detect": "^1.0.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.5", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "url-loader": "^4.1.1", - "webpack": "^5.88.1", - "webpack-bundle-analyzer": "^4.9.0", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.9.0", - "webpackbar": "^5.0.2" - } - }, - "@docusaurus/cssnano-preset": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.5.2.tgz", - "integrity": "sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==", - "requires": { - "cssnano-preset-advanced": "^6.1.2", - "postcss": "^8.4.38", - "postcss-sort-media-queries": "^5.2.0", - "tslib": "^2.6.0" - } - }, - "@docusaurus/logger": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.5.2.tgz", - "integrity": "sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==", - "requires": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - } - }, - "@docusaurus/mdx-loader": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.5.2.tgz", - "integrity": "sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==", - "requires": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^1.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - } - }, - "@docusaurus/module-type-aliases": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.5.2.tgz", - "integrity": "sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==", - "requires": { - "@docusaurus/types": "3.5.2", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - } - }, - "@docusaurus/plugin-content-blog": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.5.2.tgz", - "integrity": "sha512-R7ghWnMvjSf+aeNDH0K4fjyQnt5L0KzUEnUhmf1e3jZrv3wogeytZNN6n7X8yHcMsuZHPOrctQhXWnmxu+IRRg==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "cheerio": "1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "reading-time": "^1.5.0", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - } - }, - "@docusaurus/plugin-content-docs": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.5.2.tgz", - "integrity": "sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - } - }, - "@docusaurus/plugin-debug": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.5.2.tgz", - "integrity": "sha512-kBK6GlN0itCkrmHuCS6aX1wmoWc5wpd5KJlqQ1FyrF0cLDnvsYSnh7+ftdwzt7G6lGBho8lrVwkkL9/iQvaSOA==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^1.2.0", - "tslib": "^2.6.0" - } - }, - "@docusaurus/plugin-google-analytics": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.5.2.tgz", - "integrity": "sha512-rjEkJH/tJ8OXRE9bwhV2mb/WP93V441rD6XnM6MIluu7rk8qg38iSxS43ga2V2Q/2ib53PcqbDEJDG/yWQRJhQ==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "tslib": "^2.6.0" - } - }, - "@docusaurus/plugin-google-gtag": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.5.2.tgz", - "integrity": "sha512-lm8XL3xLkTPHFKKjLjEEAHUrW0SZBSHBE1I+i/tmYMBsjCcUB5UJ52geS5PSiOCFVR74tbPGcPHEV/gaaxFeSA==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" - } - }, - "@docusaurus/plugin-google-tag-manager": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.5.2.tgz", - "integrity": "sha512-QkpX68PMOMu10Mvgvr5CfZAzZQFx8WLlOiUQ/Qmmcl6mjGK6H21WLT5x7xDmcpCoKA/3CegsqIqBR+nA137lQg==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "tslib": "^2.6.0" - } - }, - "@docusaurus/plugin-sitemap": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.5.2.tgz", - "integrity": "sha512-DnlqYyRAdQ4NHY28TfHuVk414ft2uruP4QWCH//jzpHjqvKyXjj2fmDtI8RPUBh9K8iZKFMHRnLtzJKySPWvFA==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" - } - }, - "@docusaurus/preset-classic": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.5.2.tgz", - "integrity": "sha512-3ihfXQ95aOHiLB5uCu+9PRy2gZCeSZoDcqpnDvf3B+sTrMvMTr8qRUzBvWkoIqc82yG5prCboRjk1SVILKx6sg==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/plugin-content-blog": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/plugin-content-pages": "3.5.2", - "@docusaurus/plugin-debug": "3.5.2", - "@docusaurus/plugin-google-analytics": "3.5.2", - "@docusaurus/plugin-google-gtag": "3.5.2", - "@docusaurus/plugin-google-tag-manager": "3.5.2", - "@docusaurus/plugin-sitemap": "3.5.2", - "@docusaurus/theme-classic": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-search-algolia": "3.5.2", - "@docusaurus/types": "3.5.2" - }, - "dependencies": { - "@docusaurus/plugin-content-pages": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", - "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - } - } - } - }, - "@docusaurus/theme-classic": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.5.2.tgz", - "integrity": "sha512-XRpinSix3NBv95Rk7xeMF9k4safMkwnpSgThn0UNQNumKvmcIYjfkwfh2BhwYh/BxMXQHJ/PdmNh22TQFpIaYg==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/plugin-content-blog": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/plugin-content-pages": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-translations": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.44", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.4.26", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "dependencies": { - "@docusaurus/plugin-content-pages": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", - "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - } - } - } - }, - "@docusaurus/theme-common": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.5.2.tgz", - "integrity": "sha512-QXqlm9S6x9Ibwjs7I2yEDgsCocp708DrCrgHgKwg2n2AY0YQ6IjU0gAK35lHRLOvAoJUfCKpQAwUykB0R7+Eew==", - "requires": { - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - } - }, - "@docusaurus/theme-mermaid": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.5.2.tgz", - "integrity": "sha512-7vWCnIe/KoyTN1Dc55FIyqO5hJ3YaV08Mr63Zej0L0mX1iGzt+qKSmeVUAJ9/aOalUhF0typV0RmNUSy5FAmCg==", - "requires": { - "@docusaurus/core": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "mermaid": "^10.4.0", - "tslib": "^2.6.0" - }, - "dependencies": { - "@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" - }, - "mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - } - }, - "mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "requires": { - "@types/mdast": "^3.0.0" - } - }, - "mermaid": { - "version": "10.9.3", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.3.tgz", - "integrity": "sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==", - "requires": { - "@braintree/sanitize-url": "^6.0.1", - "@types/d3-scale": "^4.0.3", - "@types/d3-scale-chromatic": "^3.0.0", - "cytoscape": "^3.28.1", - "cytoscape-cose-bilkent": "^4.1.0", - "d3": "^7.4.0", - "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.10", - "dayjs": "^1.11.7", - "dompurify": "^3.0.5 <3.1.7", - "elkjs": "^0.9.0", - "katex": "^0.16.9", - "khroma": "^2.0.0", - "lodash-es": "^4.17.21", - "mdast-util-from-markdown": "^1.3.0", - "non-layered-tidy-tree-layout": "^2.0.2", - "stylis": "^4.1.3", - "ts-dedent": "^2.2.0", - "uuid": "^9.0.0", - "web-worker": "^1.2.0" - } - }, - "micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "requires": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==" - }, - "micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==" - }, - "micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "requires": { - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "requires": { - "micromark-util-types": "^1.0.0" - } - }, - "micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" - } - }, - "micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" - }, - "unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "requires": { - "@types/unist": "^2.0.0" - } - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" - } - } - }, - "@docusaurus/theme-search-algolia": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.5.2.tgz", - "integrity": "sha512-qW53kp3VzMnEqZGjakaV90sst3iN1o32PH+nawv1uepROO8aEGxptcq2R5rsv7aBShSRbZwIobdvSYKsZ5pqvA==", - "requires": { - "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-translations": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "algoliasearch": "^4.18.0", - "algoliasearch-helper": "^3.13.3", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - } - }, - "@docusaurus/theme-translations": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.5.2.tgz", - "integrity": "sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==", - "requires": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - } - }, - "@docusaurus/types": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.5.2.tgz", - "integrity": "sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==", - "requires": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - } - }, - "@docusaurus/utils": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.5.2.tgz", - "integrity": "sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==", - "requires": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@svgr/webpack": "^8.1.0", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "prompts": "^2.4.2", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - } - }, - "@docusaurus/utils-common": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.5.2.tgz", - "integrity": "sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==", - "requires": { - "tslib": "^2.6.0" - } - }, - "@docusaurus/utils-validation": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.5.2.tgz", - "integrity": "sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==", - "requires": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "fs-extra": "^11.2.0", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - } - }, - "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "requires": { - "@emotion/memoize": "0.7.4" - } - }, - "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" - }, - "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "@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==", - "peer": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "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==", - "peer": true - } - } - }, - "@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", - "peer": true - }, - "@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", - "peer": true, - "requires": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - } - }, - "@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", - "peer": true - }, - "@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "peer": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.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" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "peer": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "peer": true - }, - "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==", - "peer": true - } - } - }, - "@eslint/js": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", - "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", - "peer": true - }, - "@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "peer": true - }, - "@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", - "peer": true, - "requires": { - "levn": "^0.4.1" - } - }, - "@fortawesome/fontawesome-common-types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", - "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==" - }, - "@fortawesome/fontawesome-svg-core": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", - "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", - "peer": true, - "requires": { - "@fortawesome/fontawesome-common-types": "6.6.0" - } - }, - "@fortawesome/free-brands-svg-icons": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz", - "integrity": "sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==", - "requires": { - "@fortawesome/fontawesome-common-types": "6.6.0" - } - }, - "@fortawesome/react-fontawesome": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", - "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", - "requires": { - "prop-types": "^15.8.1" - } - }, - "@giscus/react": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@giscus/react/-/react-3.0.0.tgz", - "integrity": "sha512-hgCjLpg3Wgh8VbTF5p8ZLcIHI74wvDk1VIFv12+eKhenNVUDjgwNg2B1aq/3puyHOad47u/ZSyqiMtohjy/OOA==", - "requires": { - "giscus": "^1.5.0" - } - }, - "@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" - }, - "@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@heroicons/react": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.1.5.tgz", - "integrity": "sha512-FuzFN+BsHa+7OxbvAERtgBTNeZpUjgM/MIizfVkSCL2/edriN0Hx/DWRCR//aPYwO5QX/YlgLGXk+E3PcfZwjA==", - "requires": {} - }, - "@humanfs/core": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", - "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", - "peer": true - }, - "@humanfs/node": { - "version": "0.16.5", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", - "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", - "peer": true, - "requires": { - "@humanfs/core": "^0.19.0", - "@humanwhocodes/retry": "^0.3.0" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "peer": true - }, - "@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "peer": true - }, - "@iconify/types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" - }, - "@iconify/utils": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.1.33.tgz", - "integrity": "sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==", - "requires": { - "@antfu/install-pkg": "^0.4.0", - "@antfu/utils": "^0.7.10", - "@iconify/types": "^2.0.0", - "debug": "^4.3.6", - "kolorist": "^1.8.0", - "local-pkg": "^0.5.0", - "mlly": "^1.7.1" - } - }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "requires": { - "@sinclair/typebox": "^0.27.8" - } - }, - "@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "requires": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@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==", - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@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==" - }, - "@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==" - }, - "@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@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==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" - }, - "@lit-labs/ssr-dom-shim": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", - "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==" - }, - "@lit/reactive-element": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", - "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", - "requires": { - "@lit-labs/ssr-dom-shim": "^1.2.0" - } - }, - "@mdx-js/mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.0.tgz", - "integrity": "sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==", - "requires": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-to-js": "^2.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - } - }, - "@mdx-js/react": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", - "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", - "requires": { - "@types/mdx": "^2.0.0" - } - }, - "@mermaid-js/parser": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", - "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==", - "requires": { - "langium": "3.0.0" - } - }, - "@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==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@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==" - }, - "@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==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true - }, - "@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==" - }, - "@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "requires": { - "graceful-fs": "4.2.10" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - } - } - }, - "@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "requires": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - } - }, - "@polka/url": { - "version": "1.0.0-next.23", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", - "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==" - }, - "@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" - }, - "@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" - }, - "@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" - }, - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" - }, - "@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "requires": {} - }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "requires": {} - }, - "@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "requires": {} - }, - "@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "requires": {} - }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "requires": {} - }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "requires": {} - }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "requires": {} - }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "requires": {} - }, - "@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - } - }, - "@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "requires": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - } - }, - "@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "requires": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - } - }, - "@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "requires": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - } - }, - "@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "requires": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - } - }, - "@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "requires": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - } - }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "requires": { - "defer-to-connect": "^2.0.1" - } - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" - }, - "@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "requires": { - "@types/estree": "*" - } - }, - "@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "@types/d3": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", - "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", - "requires": { - "@types/d3-array": "*", - "@types/d3-axis": "*", - "@types/d3-brush": "*", - "@types/d3-chord": "*", - "@types/d3-color": "*", - "@types/d3-contour": "*", - "@types/d3-delaunay": "*", - "@types/d3-dispatch": "*", - "@types/d3-drag": "*", - "@types/d3-dsv": "*", - "@types/d3-ease": "*", - "@types/d3-fetch": "*", - "@types/d3-force": "*", - "@types/d3-format": "*", - "@types/d3-geo": "*", - "@types/d3-hierarchy": "*", - "@types/d3-interpolate": "*", - "@types/d3-path": "*", - "@types/d3-polygon": "*", - "@types/d3-quadtree": "*", - "@types/d3-random": "*", - "@types/d3-scale": "*", - "@types/d3-scale-chromatic": "*", - "@types/d3-selection": "*", - "@types/d3-shape": "*", - "@types/d3-time": "*", - "@types/d3-time-format": "*", - "@types/d3-timer": "*", - "@types/d3-transition": "*", - "@types/d3-zoom": "*" - } - }, - "@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" - }, - "@types/d3-axis": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", - "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-brush": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", - "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-chord": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" - }, - "@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" - }, - "@types/d3-contour": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", - "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", - "requires": { - "@types/d3-array": "*", - "@types/geojson": "*" - } - }, - "@types/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" - }, - "@types/d3-dispatch": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", - "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" - }, - "@types/d3-drag": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", - "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-dsv": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" - }, - "@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" - }, - "@types/d3-fetch": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", - "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", - "requires": { - "@types/d3-dsv": "*" - } - }, - "@types/d3-force": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==" - }, - "@types/d3-format": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" - }, - "@types/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", - "requires": { - "@types/geojson": "*" - } - }, - "@types/d3-hierarchy": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" - }, - "@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", - "requires": { - "@types/d3-color": "*" - } - }, - "@types/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" - }, - "@types/d3-polygon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" - }, - "@types/d3-quadtree": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" - }, - "@types/d3-random": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" - }, - "@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "requires": { - "@types/d3-time": "*" - } - }, - "@types/d3-scale-chromatic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", - "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" - }, - "@types/d3-selection": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", - "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==" - }, - "@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", - "requires": { - "@types/d3-path": "*" - } - }, - "@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" - }, - "@types/d3-time-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" - }, - "@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" - }, - "@types/d3-transition": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", - "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", - "requires": { - "@types/d3-selection": "*" - } - }, - "@types/d3-zoom": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", - "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", - "requires": { - "@types/d3-interpolate": "*", - "@types/d3-selection": "*" - } - }, - "@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "requires": { - "@types/ms": "*" - } - }, - "@types/dompurify": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", - "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", - "requires": { - "@types/trusted-types": "*" - } - }, - "@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" - }, - "@types/estree-jsx": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", - "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", - "requires": { - "@types/estree": "*" - } - }, - "@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "@types/geojson": { - "version": "7946.0.14", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" - }, - "@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" - }, - "@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", - "requires": { - "@types/unist": "*" - } - }, - "@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" - }, - "@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" - }, - "@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" - }, - "@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" - }, - "@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", - "requires": { - "@types/unist": "*" - } - }, - "@types/mdx": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", - "integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==" - }, - "@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" - }, - "@types/node": { - "version": "20.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", - "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/node-forge": { - "version": "1.3.10", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", - "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", - "requires": { - "@types/node": "*" - } - }, - "@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "@types/prismjs": { - "version": "1.26.3", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", - "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" - }, - "@types/prop-types": { - "version": "15.7.11", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" - }, - "@types/qs": { - "version": "6.9.10", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" - }, - "@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "@types/react": { - "version": "18.2.39", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", - "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "requires": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "@types/react-router-config": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.10.tgz", - "integrity": "sha512-Wn6c/tXdEgi9adCMtDwx8Q2vGty6TsPTc/wCQQ9kAlye8UqFxj0vGFWWuhywNfkwqth+SOgJxQTLTZukrqDQmQ==", - "requires": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" - } - }, - "@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "requires": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "requires": { - "@types/node": "*" - } - }, - "@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" - }, - "@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "requires": { - "@types/express": "*" - } - }, - "@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "requires": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "requires": { - "@types/node": "*" - } - }, - "@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" - }, - "@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" - }, - "@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "requires": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "dependencies": { - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "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==", - "requires": { - "mime-db": "1.52.0" - } - } - } - }, - "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" - }, - "acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "requires": {} - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} - }, - "acorn-walk": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", - "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==" - }, - "address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==" - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "requires": { - "ajv": "^8.0.0" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "algoliasearch": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", - "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", - "requires": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-account": "4.24.0", - "@algolia/client-analytics": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-personalization": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/recommend": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - }, - "dependencies": { - "@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "requires": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "requires": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "requires": { - "@algolia/requester-common": "4.24.0" - } - }, - "@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "requires": { - "@algolia/requester-common": "4.24.0" - } - } - } - }, - "algoliasearch-helper": { - "version": "3.22.5", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.5.tgz", - "integrity": "sha512-lWvhdnc+aKOKx8jyA3bsdEgHzm/sglC4cYdMG4xSQyRiPLJVJtH/IVYZG3Hp6PkTEhQqhyVYkeP9z2IlcHJsWw==", - "requires": { - "@algolia/events": "^4.0.1" - } - }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "requires": { - "string-width": "^4.1.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==" - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==" - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==" - }, - "astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==" - }, - "async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true - }, - "async-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", - "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "requires": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", - "postcss-value-parser": "^4.2.0" - } - }, - "axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "requires": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", - "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", - "requires": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", - "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.4.3", - "core-js-compat": "^3.33.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", - "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.4.3" - } - }, - "babel-plugin-styled-components": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", - "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "lodash": "^4.17.21", - "picomatch": "^2.3.1" - } - }, - "bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - } - } - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "bonjour-service": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", - "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", - "requires": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "boxen": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "requires": { - "ansi-align": "^3.0.1", - "camelcase": "^6.2.0", - "chalk": "^4.1.2", - "cli-boxes": "^3.0.0", - "string-width": "^5.0.1", - "type-fest": "^2.5.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "requires": { - "fill-range": "^7.1.1" - } - }, - "browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", - "requires": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==" - }, - "cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "requires": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "dependencies": { - "normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==" - } - } - }, - "call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" - }, - "camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true - }, - "camelize": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001664", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz", - "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==" - }, - "ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==" - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" - }, - "character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" - }, - "character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==" - }, - "character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==" - }, - "character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==" - }, - "cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "requires": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - } - }, - "cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "requires": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - } - }, - "chevrotain": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", - "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", - "requires": { - "@chevrotain/cst-dts-gen": "11.0.3", - "@chevrotain/gast": "11.0.3", - "@chevrotain/regexp-to-ast": "11.0.3", - "@chevrotain/types": "11.0.3", - "@chevrotain/utils": "11.0.3", - "lodash-es": "4.17.21" - } - }, - "chevrotain-allstar": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", - "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", - "requires": { - "lodash-es": "^4.17.21" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==" - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - } - }, - "clean-css": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", - "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==" - }, - "cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", - "requires": { - "@colors/colors": "1.5.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" - }, - "collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "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==", - "requires": { - "color-name": "~1.1.4" - } - }, - "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==" - }, - "colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "combine-promises": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==" - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" - }, - "common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==" - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "requires": { - "mime-db": ">= 1.43.0 < 2" - }, - "dependencies": { - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - } - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "confbox": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", - "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==" - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "requires": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - } - }, - "connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" - }, - "consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==" - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "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==" - }, - "cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==" - }, - "copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==" - }, - "copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "requires": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "dependencies": { - "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==", - "requires": { - "is-glob": "^4.0.3" - } - }, - "globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "requires": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - } - }, - "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" - } - } - }, - "core-js": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", - "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==" - }, - "core-js-compat": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", - "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", - "requires": { - "browserslist": "^4.22.1" - } - }, - "core-js-pure": { - "version": "3.33.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.3.tgz", - "integrity": "sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ==" - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "cose-base": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", - "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", - "requires": { - "layout-base": "^1.0.0" - } - }, - "cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "requires": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "requires": { - "type-fest": "^1.0.1" - }, - "dependencies": { - "type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==" - } - } - }, - "css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" - }, - "css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", - "requires": {} - }, - "css-loader": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", - "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", - "requires": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.21", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.3", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" - } - }, - "css-minimizer-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.18", - "cssnano": "^6.0.1", - "jest-worker": "^29.4.3", - "postcss": "^8.4.24", - "schema-utils": "^4.0.1", - "serialize-javascript": "^6.0.1" - } - }, - "css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - } - }, - "css-to-react-native": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", - "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", - "requires": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^3.3.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } - } - }, - "css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "requires": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", - "requires": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" - }, - "dependencies": { - "lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==" - } - } - }, - "cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "requires": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" - } - }, - "cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "requires": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" - } - }, - "cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "requires": {} - }, - "csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "requires": { - "css-tree": "~2.2.0" - }, - "dependencies": { - "css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "requires": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - } - }, - "mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" - } - } - }, - "csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" - }, - "cytoscape": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz", - "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==" - }, - "cytoscape-cose-bilkent": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", - "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", - "requires": { - "cose-base": "^1.0.0" - } - }, - "cytoscape-fcose": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", - "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", - "requires": { - "cose-base": "^2.2.0" - }, - "dependencies": { - "cose-base": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", - "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", - "requires": { - "layout-base": "^2.0.0" - } - }, - "layout-base": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", - "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" - } - } - }, - "d3": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", - "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", - "requires": { - "d3-array": "3", - "d3-axis": "3", - "d3-brush": "3", - "d3-chord": "3", - "d3-color": "3", - "d3-contour": "4", - "d3-delaunay": "6", - "d3-dispatch": "3", - "d3-drag": "3", - "d3-dsv": "3", - "d3-ease": "3", - "d3-fetch": "3", - "d3-force": "3", - "d3-format": "3", - "d3-geo": "3", - "d3-hierarchy": "3", - "d3-interpolate": "3", - "d3-path": "3", - "d3-polygon": "3", - "d3-quadtree": "3", - "d3-random": "3", - "d3-scale": "4", - "d3-scale-chromatic": "3", - "d3-selection": "3", - "d3-shape": "3", - "d3-time": "3", - "d3-time-format": "4", - "d3-timer": "3", - "d3-transition": "3", - "d3-zoom": "3" - } - }, - "d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "requires": { - "internmap": "1 - 2" - } - }, - "d3-axis": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==" - }, - "d3-brush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "3", - "d3-transition": "3" - } - }, - "d3-chord": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", - "requires": { - "d3-path": "1 - 3" - } - }, - "d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" - }, - "d3-contour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", - "requires": { - "d3-array": "^3.2.0" - } - }, - "d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "requires": { - "delaunator": "5" - } - }, - "d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==" - }, - "d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" - } - }, - "d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "requires": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" - }, - "d3-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", - "requires": { - "d3-dsv": "1 - 3" - } - }, - "d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" - } - }, - "d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==" - }, - "d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", - "requires": { - "d3-array": "2.5.0 - 3" - } - }, - "d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==" - }, - "d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "requires": { - "d3-color": "1 - 3" - } - }, - "d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==" - }, - "d3-polygon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==" - }, - "d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==" - }, - "d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==" - }, - "d3-sankey": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", - "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", - "requires": { - "d3-array": "1 - 2", - "d3-shape": "^1.2.0" - }, - "dependencies": { - "d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "requires": { - "internmap": "^1.0.0" - } - }, - "d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" - }, - "d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "requires": { - "d3-path": "1" - } - }, - "internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" - } - } - }, - "d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "requires": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - } - }, - "d3-scale-chromatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", - "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", - "requires": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" - } - }, - "d3-selection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==" - }, - "d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "requires": { - "d3-path": "^3.1.0" - } - }, - "d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "requires": { - "d3-array": "2 - 3" - } - }, - "d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "requires": { - "d3-time": "1 - 3" - } - }, - "d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==" - }, - "d3-transition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "requires": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - } - }, - "d3-zoom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "requires": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" - } - }, - "dagre-d3-es": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", - "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", - "requires": { - "d3": "^7.8.2", - "lodash-es": "^4.17.21" - } - }, - "dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" - }, - "debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" - }, - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "requires": { - "character-entities": "^2.0.0" - } - }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" - } - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "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==", - "peer": true - }, - "deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" - }, - "default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "requires": { - "execa": "^5.0.0" - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" - }, - "define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - } - }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" - }, - "define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "requires": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - } - }, - "delaunator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", - "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", - "requires": { - "robust-predicates": "^3.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "requires": { - "address": "^1.0.1", - "debug": "4" - } - }, - "detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "requires": { - "dequal": "^2.0.0" - } - }, - "didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true - }, - "diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==" - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "requires": { - "path-type": "^4.0.0" - } - }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" - }, - "dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - } - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" - }, - "domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "requires": { - "domelementtype": "^2.3.0" - } - }, - "dompurify": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", - "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==" - }, - "domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "requires": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "requires": { - "is-obj": "^2.0.0" - }, - "dependencies": { - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - } - } - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "electron-to-chromium": { - "version": "1.5.30", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.30.tgz", - "integrity": "sha512-sXI35EBN4lYxzc/pIGorlymYNzDBOqkSlVRe6MkgBsW/hW1tpC/HDJ2fjG7XnjakzfLEuvdmux0Mjs6jHq4UOA==" - }, - "elkjs": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", - "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" - }, - "email-addresses": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", - "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "emoticon": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", - "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==" - }, - "encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" - }, - "enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "requires": { - "get-intrinsic": "^1.2.4" - } - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" - }, - "es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" - }, - "escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" - }, - "escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "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==" - }, - "eslint": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", - "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", - "peer": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.12.0", - "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "peer": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", - "peer": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "peer": true - }, - "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==", - "peer": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "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==", - "peer": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "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==", - "peer": true - }, - "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==", - "peer": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "peer": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "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==", - "peer": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "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==", - "peer": true - }, - "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==", - "peer": true - } - } - }, - "eslint-config-prettier": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz", - "integrity": "sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA==", - "requires": { - "get-stdin": "^6.0.0" - } - }, - "eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", - "peer": true - }, - "espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", - "peer": true, - "requires": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "peer": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "peer": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "requires": { - "@types/estree": "^1.0.0" - } - }, - "estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - } - }, - "estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==" - }, - "estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - } - }, - "estree-util-value-to-estree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", - "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", - "requires": { - "@types/estree": "^1.0.0", - "is-plain-obj": "^4.0.0" - } - }, - "estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - } - }, - "estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "requires": { - "@types/estree": "^1.0.0" - } - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "requires": { - "@types/node": "*", - "require-like": ">= 0.1.1" - } - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - } - } - }, - "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==" - }, - "fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "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==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "peer": true - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "requires": { - "reusify": "^1.0.4" - } - }, - "fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "requires": { - "format": "^0.2.0" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "feed": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "requires": { - "xml-js": "^1.6.11" - } - }, - "file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "peer": true, - "requires": { - "flat-cache": "^4.0.0" - } - }, - "file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "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==" - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "dev": true - }, - "filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "dev": true, - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - } - }, - "filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "requires": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - } - }, - "find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "requires": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" - }, - "flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "peer": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "dependencies": { - "flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "peer": true - } - } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" - }, - "follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==" - }, - "foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "dependencies": { - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - } - } - }, - "fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "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==" - }, - "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - } - } - }, - "form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==" - }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==" - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "requires": { - "map-cache": "^0.2.2" - } - }, - "framer-motion": { - "version": "11.11.11", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.11.tgz", - "integrity": "sha512-tuDH23ptJAKUHGydJQII9PhABNJBpB+z0P1bmgKK9QFIssHGlfPd6kxMq00LSKwE27WFsb2z0ovY0bpUyMvfRw==", - "requires": { - "tslib": "^2.4.0" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "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==" - }, - "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==" - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==" - }, - "gh-pages": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.2.0.tgz", - "integrity": "sha512-HMXJ8th9u5wRXaZCnLcs/d3oVvCHiZkaP5KQExQljYGwJjQbSPyTdHe/Gc1IvYUR/rWiZLxNobIqfoMHKTKjHQ==", - "dev": true, - "requires": { - "async": "^3.2.4", - "commander": "^11.0.0", - "email-addresses": "^5.0.0", - "filenamify": "^4.3.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^11.1.1", - "globby": "^11.1.0" - }, - "dependencies": { - "commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true - }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "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 - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } - } - }, - "giscus": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/giscus/-/giscus-1.5.0.tgz", - "integrity": "sha512-t3LL0qbSO3JXq3uyQeKpF5CegstGfKX/0gI6eDe1cmnI7D56R7j52yLdzw4pdKrg3VnufwCgCM3FDz7G1Qr6lg==", - "requires": { - "lit": "^3.1.2" - } - }, - "github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "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" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "requires": { - "ini": "2.0.0" - }, - "dependencies": { - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" - } - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "requires": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==" - } - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "requires": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, - "gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "requires": { - "duplexer": "^0.1.2" - } - }, - "hachure-fill": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", - "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==" - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "requires": { - "es-define-property": "^1.0.0" - } - }, - "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==" - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==" - }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "hast-util-from-dom": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", - "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", - "requires": { - "@types/hast": "^3.0.0", - "hastscript": "^8.0.0", - "web-namespaces": "^2.0.0" - } - }, - "hast-util-from-html": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", - "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", - "requires": { - "@types/hast": "^3.0.0", - "devlop": "^1.1.0", - "hast-util-from-parse5": "^8.0.0", - "parse5": "^7.0.0", - "vfile": "^6.0.0", - "vfile-message": "^4.0.0" - } - }, - "hast-util-from-html-isomorphic": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", - "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", - "requires": { - "@types/hast": "^3.0.0", - "hast-util-from-dom": "^5.0.0", - "hast-util-from-html": "^2.0.0", - "unist-util-remove-position": "^5.0.0" - } - }, - "hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "requires": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - } - }, - "hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "hast-util-raw": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", - "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", - "requires": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - } - }, - "hast-util-to-estree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", - "requires": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - } - }, - "hast-util-to-jsx-runtime": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.2.0.tgz", - "integrity": "sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==", - "requires": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - } - }, - "hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "requires": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - } - }, - "hast-util-to-text": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", - "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", - "requires": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - } - }, - "hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "requires": { - "@types/hast": "^3.0.0" - } - }, - "hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "requires": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", - "requires": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "dependencies": { - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" - } - } - }, - "html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==" - }, - "html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==" - }, - "html-webpack-plugin": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", - "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", - "requires": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" - }, - "html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "requires": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - } - } - } - }, - "htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", - "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" - } - } - }, - "http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "requires": {} - }, - "ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==" - }, - "image-size": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", - "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", - "requires": { - "queue": "6.0.2" - } - }, - "immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==" - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "infima": { - "version": "0.2.0-alpha.44", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.44.tgz", - "integrity": "sha512-tuRkUSO/lB3rEhLJk25atwAjgLuzq070+pOW8XcvpHky/YbENnRRdPd85IBkyeTgttmOy5ah+yHYsK1HhUd4lQ==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==" - }, - "is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", - "requires": { - "hasown": "^2.0.0" - } - }, - "is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==" - }, - "is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "requires": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "requires": { - "ci-info": "^3.2.0" - } - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "requires": { - "hasown": "^2.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", - "requires": { - "hasown": "^2.0.0" - } - }, - "is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==" - }, - "is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==" - }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, - "is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" - }, - "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==" - }, - "is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - }, - "is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "requires": { - "@types/estree": "*" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" - }, - "is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "requires": { - "is-docker": "^2.0.0" - } - }, - "is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" - }, - "jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "requires": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==" - }, - "joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "requires": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "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==" - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "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==", - "peer": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "katex": { - "version": "0.16.11", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", - "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", - "requires": { - "commander": "^8.3.0" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" - } - } - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "requires": { - "json-buffer": "3.0.1" - } - }, - "khroma": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", - "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" - }, - "kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" - }, - "langium": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", - "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", - "requires": { - "chevrotain": "~11.0.3", - "chevrotain-allstar": "~0.3.0", - "vscode-languageserver": "~9.0.1", - "vscode-languageserver-textdocument": "~1.0.11", - "vscode-uri": "~3.0.8" - } - }, - "latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "requires": { - "package-json": "^8.1.0" - } - }, - "launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", - "requires": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "layout-base": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", - "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "peer": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "lit": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.0.tgz", - "integrity": "sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw==", - "requires": { - "@lit/reactive-element": "^2.0.4", - "lit-element": "^4.1.0", - "lit-html": "^3.2.0" - } - }, - "lit-element": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.0.tgz", - "integrity": "sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww==", - "requires": { - "@lit-labs/ssr-dom-shim": "^1.2.0", - "@lit/reactive-element": "^2.0.4", - "lit-html": "^3.2.0" - } - }, - "lit-html": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.0.tgz", - "integrity": "sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA==", - "requires": { - "@types/trusted-types": "^2.0.2" - } - }, - "loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" - }, - "loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "requires": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - } - }, - "locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "requires": { - "p-locate": "^6.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "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==", - "peer": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==" - }, - "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==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "requires": { - "tslib": "^2.0.3" - } - }, - "lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==" - }, - "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==", - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==" - }, - "markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==" - }, - "marked": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", - "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==" - }, - "mdast-util-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", - "requires": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - } - }, - "mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", - "requires": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" - } - } - }, - "mdast-util-from-markdown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", - "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", - "requires": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "requires": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" - } - } - }, - "mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", - "requires": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", - "requires": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", - "requires": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - } - }, - "mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "requires": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "requires": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-math": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", - "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", - "requires": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "longest-streak": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.1.0", - "unist-util-remove-position": "^5.0.0" - } - }, - "mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "requires": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - } - }, - "mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - } - }, - "mdast-util-phrasing": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", - "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", - "requires": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - } - }, - "mdast-util-to-hast": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", - "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", - "requires": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0" - } - }, - "mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "requires": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - } - }, - "mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "requires": { - "@types/mdast": "^4.0.0" - } - }, - "mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "requires": { - "fs-monkey": "^1.0.4" - } - }, - "memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - }, - "merge-anything": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz", - "integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==", - "requires": { - "is-what": "^3.3.1" - } - }, - "merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "mermaid": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.0.tgz", - "integrity": "sha512-mxCfEYvADJqOiHfGpJXLs4/fAjHz448rH0pfY5fAoxiz70rQiDSzUUy4dNET2T08i46IVpjohPd6WWbzmRHiPA==", - "requires": { - "@braintree/sanitize-url": "^7.0.1", - "@iconify/utils": "^2.1.32", - "@mermaid-js/parser": "^0.3.0", - "@types/d3": "^7.4.3", - "@types/dompurify": "^3.0.5", - "cytoscape": "^3.29.2", - "cytoscape-cose-bilkent": "^4.1.0", - "cytoscape-fcose": "^2.2.0", - "d3": "^7.9.0", - "d3-sankey": "^0.12.3", - "dagre-d3-es": "7.0.11", - "dayjs": "^1.11.10", - "dompurify": "^3.0.11 <3.1.7", - "katex": "^0.16.9", - "khroma": "^2.1.0", - "lodash-es": "^4.17.21", - "marked": "^13.0.2", - "roughjs": "^4.6.6", - "stylis": "^4.3.1", - "ts-dedent": "^2.2.0", - "uuid": "^9.0.1" - }, - "dependencies": { - "@braintree/sanitize-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz", - "integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==" - }, - "dagre-d3-es": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", - "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", - "requires": { - "d3": "^7.9.0", - "lodash-es": "^4.17.21" - } - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "requires": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-core-commonmark": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", - "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", - "requires": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "requires": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "requires": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-extension-gfm-autolink-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", - "requires": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", - "requires": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", - "requires": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "requires": { - "micromark-util-types": "^2.0.0" - } - }, - "micromark-extension-gfm-task-list-item": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", - "requires": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-math": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", - "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", - "requires": { - "@types/katex": "^0.16.0", - "devlop": "^1.0.0", - "katex": "^0.16.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-mdx-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", - "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", - "requires": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", - "requires": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "requires": { - "micromark-util-types": "^2.0.0" - } - }, - "micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "requires": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "requires": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "requires": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", - "requires": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "dependencies": { - "micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" - } - } - }, - "micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "requires": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "requires": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "requires": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "dependencies": { - "micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" - } - } - }, - "micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "requires": { - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "requires": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "requires": { - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==" - }, - "micromark-util-events-to-acorn": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", - "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", - "requires": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==" - }, - "micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "requires": { - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "requires": { - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "requires": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - }, - "dependencies": { - "micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", - "requires": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-subtokenize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", - "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", - "requires": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "dependencies": { - "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" - } - } - }, - "micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==" - }, - "micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==" - }, - "micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "requires": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "requires": { - "mime-db": "~1.33.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==" - }, - "mini-css-extract-plugin": { - "version": "2.7.6", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", - "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", - "requires": { - "schema-utils": "^4.0.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "mlly": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", - "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", - "requires": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.1", - "ufo": "^1.5.3" - } - }, - "mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" - }, - "mrmime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", - "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - } - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "nan": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", - "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", - "optional": true - }, - "nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "peer": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "requires": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - } - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" - }, - "node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" - }, - "non-layered-tidy-tree-layout": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", - "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "requires": { - "boolbase": "^1.0.0" - } - }, - "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==" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true - }, - "object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "requires": { - "isobject": "^3.0.0" - } - }, - "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==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "requires": { - "isobject": "^3.0.1" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "onchange": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/onchange/-/onchange-5.2.0.tgz", - "integrity": "sha512-kBNMF4KU1m0GkZCANckQZs3N41esf950T/gv7JIjNS6qWS8R34+iCKk/wmVRPEdaYCA+yi2aK2vNXS0RaB/V2A==", - "requires": { - "@blakeembrey/deque": "^1.0.3", - "arrify": "^1.0.1", - "chokidar": "^2.0.0", - "cross-spawn": "^6.0.0", - "minimist": "^1.2.0", - "supports-color": "^5.5.0", - "tree-kill": "^1.2.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "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==" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - } - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" - }, - "optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "peer": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - } - }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==" - }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "requires": { - "yocto-queue": "^1.0.0" - } - }, - "p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "requires": { - "p-limit": "^4.0.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "requires": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "requires": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - } - }, - "package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true - }, - "package-manager-detector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.0.tgz", - "integrity": "sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==" - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "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==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "requires": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "dependencies": { - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - } - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse-numeric-range": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" - }, - "parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "requires": { - "entities": "^4.4.0" - } - }, - "parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "requires": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==" - }, - "path-data-parser": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", - "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==" - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==" - }, - "path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==" - }, - "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==" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "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==" - }, - "path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "requires": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true - } - } - }, - "path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "requires": { - "isarray": "0.0.1" - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" - }, - "periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true - }, - "pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "requires": { - "find-up": "^6.3.0" - } - }, - "pkg-types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz", - "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==", - "requires": { - "confbox": "^0.1.7", - "mlly": "^1.7.1", - "pathe": "^1.1.2" - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" - } - } - }, - "points-on-curve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", - "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==" - }, - "points-on-path": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", - "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", - "requires": { - "path-data-parser": "0.1.0", - "points-on-curve": "0.2.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==" - }, - "postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "requires": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - } - }, - "postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "requires": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-colormin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", - "requires": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "colord": "^2.9.3", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-convert-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", - "requires": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-discard-comments": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", - "requires": {} - }, - "postcss-discard-duplicates": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", - "requires": {} - }, - "postcss-discard-empty": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", - "requires": {} - }, - "postcss-discard-overridden": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", - "requires": {} - }, - "postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "requires": { - "postcss-selector-parser": "^6.0.16" - } - }, - "postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - } - }, - "postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, - "requires": { - "camelcase-css": "^2.0.1" - } - }, - "postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, - "requires": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "dependencies": { - "lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true - }, - "yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "dev": true - } - } - }, - "postcss-loader": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.3.tgz", - "integrity": "sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA==", - "requires": { - "cosmiconfig": "^8.2.0", - "jiti": "^1.18.2", - "semver": "^7.3.8" - } - }, - "postcss-merge-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", - "requires": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-merge-longhand": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", - "requires": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.1.1" - } - }, - "postcss-merge-rules": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", - "requires": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" - } - }, - "postcss-minify-font-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-gradients": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", - "requires": { - "colord": "^2.9.3", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-params": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", - "requires": { - "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", - "requires": { - "postcss-selector-parser": "^6.0.16" - } - }, - "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "requires": {} - }, - "postcss-modules-local-by-default": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", - "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.1.1" - } - }, - "postcss-normalize-charset": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", - "requires": {} - }, - "postcss-normalize-display-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-positions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-string": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-unicode": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", - "requires": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-whitespace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-ordered-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", - "requires": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reduce-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reduce-initial": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", - "requires": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-sort-media-queries": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", - "requires": { - "sort-css-media-queries": "2.2.0" - } - }, - "postcss-svgo": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", - "requires": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - } - }, - "postcss-unique-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", - "requires": { - "postcss-selector-parser": "^6.0.16" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "postcss-zindex": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", - "requires": {} - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "peer": true - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "requires": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" - }, - "prism-react-renderer": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.0.tgz", - "integrity": "sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw==", - "requires": { - "@types/prismjs": "^1.26.0", - "clsx": "^2.0.0" - } - }, - "prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "property-information": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", - "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==" - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "dependencies": { - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - } - } - }, - "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==" - }, - "pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", - "requires": { - "escape-goat": "^4.0.0" - } - }, - "qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "requires": { - "side-channel": "^1.0.6" - } - }, - "queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "requires": { - "inherits": "~2.0.3" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" - }, - "random-id": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/random-id/-/random-id-0.0.2.tgz", - "integrity": "sha512-e1E0fCzmRQcSxeAFnCybHkVi4filc7c07INtA1BAjKFRfKyO+upZ3q0OhxMnyJ2PRwTSpy/jiMN0ZXwLtyQaBw==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==" - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - } - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" - } - } - }, - "react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "requires": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "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==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" - }, - "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==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "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==", - "requires": { - "p-limit": "^3.0.2" - } - }, - "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==" - }, - "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==" - } - } - }, - "react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - } - }, - "react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" - }, - "react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "requires": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - } - }, - "react-icons": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", - "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", - "requires": {} - }, - "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==" - }, - "react-json-view-lite": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", - "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", - "requires": {} - }, - "react-lite-youtube-embed": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/react-lite-youtube-embed/-/react-lite-youtube-embed-2.4.0.tgz", - "integrity": "sha512-Xo6cM1zPlROvvM97JkqQIoXstlQDaC4+DawmM7BB7Hh1cXrkBHEGq1iJlQxBTUWAUklmpcC7ph7qg7CztXtABQ==", - "requires": {} - }, - "react-loadable": { - "version": "npm:@docusaurus/react-loadable@6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", - "requires": { - "@types/react": "*" - } - }, - "react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "requires": { - "@babel/runtime": "^7.10.3" - } - }, - "react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-router-config": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "requires": { - "@babel/runtime": "^7.1.2" - } - }, - "react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-simple-chatbot": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/react-simple-chatbot/-/react-simple-chatbot-0.6.1.tgz", - "integrity": "sha512-q9y5GXwBvD+YvLgDVyDuZHYMkrcgIirm1FVV9RkR7XojPmbiX1lCzT6ib8U1M5zh42kTUBRnszXzkAGm9e0K8w==", - "requires": { - "eslint-config-prettier": "^4.1.0", - "eslint-plugin-prettier": "^3.0.1", - "flatted": "^2.0.0", - "onchange": "^5.2.0", - "prettier": "^1.16.4", - "prop-types": "^15.6.0", - "random-id": "0.0.2", - "react": "^16.4.1", - "react-dom": "^16.4.1" - }, - "dependencies": { - "react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - } - }, - "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - } - } - }, - "react-toastify": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.6.tgz", - "integrity": "sha512-yYjp+omCDf9lhZcrZHKbSq7YMuK0zcYkDFTzfRFgTXkTFHZ1ToxwAonzA4JI5CxA91JpjFLmwEsZEgfYfOqI1A==", - "requires": { - "clsx": "^2.1.0" - } - }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "requires": { - "pify": "^2.3.0" - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "reading-time": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "requires": { - "resolve": "^1.1.6" - } - }, - "recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "requires": { - "minimatch": "^3.0.5" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, - "regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "requires": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - } - }, - "registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "requires": { - "@pnpm/npm-conf": "^2.1.0" - } - }, - "registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "requires": { - "rc": "1.2.8" - } - }, - "regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" - } - } - }, - "rehype-katex": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", - "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", - "requires": { - "@types/hast": "^3.0.0", - "@types/katex": "^0.16.0", - "hast-util-from-html-isomorphic": "^2.0.0", - "hast-util-to-text": "^4.0.0", - "katex": "^0.16.0", - "unist-util-visit-parents": "^6.0.0", - "vfile": "^6.0.0" - } - }, - "rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "requires": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" - }, - "remark-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", - "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - } - }, - "remark-emoji": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", - "requires": { - "@types/mdast": "^4.0.2", - "emoticon": "^4.0.1", - "mdast-util-find-and-replace": "^3.0.1", - "node-emoji": "^2.1.0", - "unified": "^11.0.4" - } - }, - "remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - } - }, - "remark-gfm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - } - }, - "remark-math": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", - "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-math": "^3.0.0", - "micromark-extension-math": "^3.0.0", - "unified": "^11.0.0" - } - }, - "remark-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", - "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", - "requires": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - } - }, - "remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - } - }, - "remark-rehype": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz", - "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==", - "requires": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - } - }, - "remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "requires": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" - }, - "renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - }, - "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - } - } - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "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==" - }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==" - }, - "responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "requires": { - "lowercase-keys": "^3.0.0" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" - }, - "roughjs": { - "version": "4.6.6", - "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", - "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", - "requires": { - "hachure-fill": "^0.5.2", - "path-data-parser": "^0.1.0", - "points-on-curve": "^0.2.0", - "points-on-path": "^0.2.1" - } - }, - "rtl-detect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", - "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" - }, - "rtlcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", - "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0", - "postcss": "^8.4.21", - "strip-json-comments": "^3.1.1" - } - }, - "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==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" - }, - "sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "requires": { - "mri": "^1.1.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" - }, - "scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - } - }, - "search-insights": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", - "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", - "peer": true - }, - "section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "requires": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "requires": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "requires": { - "semver": "^7.3.5" - } - }, - "send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - } - } - }, - "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-handler": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", - "requires": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "3.3.0", - "range-parser": "1.2.0" - }, - "dependencies": { - "path-to-regexp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", - "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==" - } - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" - } - } - }, - "serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "requires": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - } - }, - "set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - } - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "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==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "sirv": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", - "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", - "requires": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^3.0.0" - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "sitemap": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", - "requires": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "dependencies": { - "@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - } - } - }, - "skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "requires": { - "unicode-emoji-modifier-base": "^1.0.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "sort-css-media-queries": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==" - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" - }, - "source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" - }, - "space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==" - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "std-env": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.5.0.tgz", - "integrity": "sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - } - } - }, - "stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", - "requires": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - } - }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "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==" - }, - "strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - }, - "dependencies": { - "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 - } - } - }, - "style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "requires": { - "inline-style-parser": "0.1.1" - } - }, - "styled-components": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz", - "integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@emotion/is-prop-valid": "^0.8.1", - "@emotion/unitless": "^0.7.0", - "babel-plugin-styled-components": ">= 1", - "css-to-react-native": "^2.2.2", - "memoize-one": "^5.0.0", - "merge-anything": "^2.2.4", - "prop-types": "^15.5.4", - "react-is": "^16.6.0", - "stylis": "^3.5.0", - "stylis-rule-sheet": "^0.0.10", - "supports-color": "^5.5.0" - }, - "dependencies": { - "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==" - }, - "stylis": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", - "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" - }, - "stylis-rule-sheet": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", - "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==", - "requires": {} - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "stylehacks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", - "requires": { - "browserslist": "^4.23.0", - "postcss-selector-parser": "^6.0.16" - } - }, - "stylis": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", - "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" - }, - "sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - }, - "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - } - }, - "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "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==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "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==" - }, - "svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - } - } - }, - "swiper": { - "version": "11.1.14", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.1.14.tgz", - "integrity": "sha512-VbQLQXC04io6AoAjIUWuZwW4MSYozkcP9KjLdrsG/00Q/yiwvhz9RQyt0nHXV10hi9NVnDNy1/wv7Dzq1lkOCQ==" - }, - "tailwindcss": { - "version": "3.4.14", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", - "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", - "dev": true, - "requires": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "dependencies": { - "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, - "requires": { - "is-glob": "^4.0.3" - } - } - } - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" - }, - "terser": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.35.0.tgz", - "integrity": "sha512-TmYbQnzVfrx3RQsPoItoPplymixIAtp2R2xlpyVBYmFmvI34IzLhCLj8SimRb/kZXlq4t1gA+vbcTqLQ3+5Q5g==", - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - } - } - }, - "terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "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==" - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "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==" - }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "tinyexec": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", - "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==" - }, - "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==" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" - }, - "trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - }, - "dependencies": { - "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 - } - } - }, - "trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==" - }, - "ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==" - }, - "ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "peer": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "dependencies": { - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "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==", - "requires": { - "mime-db": "1.52.0" - } - } - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", - "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", - "peer": true - }, - "ufo": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", - "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==" - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" - }, - "unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==" - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" - }, - "unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" - }, - "unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", - "requires": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "requires": { - "crypto-random-string": "^4.0.0" - } - }, - "unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - } - }, - "unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "requires": { - "@types/unist": "^3.0.0" - } - }, - "unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "requires": { - "@types/unist": "^3.0.0" - } - }, - "unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "requires": { - "@types/unist": "^3.0.0" - } - }, - "unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - } - }, - "unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "requires": { - "@types/unist": "^3.0.0" - } - }, - "unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - } - }, - "unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" - }, - "update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "requires": { - "escalade": "^3.2.0", - "picocolors": "^1.1.0" - } - }, - "update-notifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", - "requires": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", - "configstore": "^6.0.0", - "has-yarn": "^3.0.0", - "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", - "is-installed-globally": "^0.4.0", - "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", - "latest-version": "^7.0.0", - "pupa": "^3.1.0", - "semver": "^7.3.7", - "semver-diff": "^4.0.0", - "xdg-basedir": "^5.1.0" - }, - "dependencies": { - "boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "requires": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - } - }, - "camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==" - }, - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==" - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" - } - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==" - }, - "url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "requires": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "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==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "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==", - "requires": { - "mime-db": "1.52.0" - } - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "uvu": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", - "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", - "requires": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - }, - "dependencies": { - "kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" - } - } - }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - } - }, - "vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", - "requires": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - } - }, - "vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "requires": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - } - }, - "vscode-jsonrpc": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", - "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==" - }, - "vscode-languageserver": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", - "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", - "requires": { - "vscode-languageserver-protocol": "3.17.5" - } - }, - "vscode-languageserver-protocol": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", - "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", - "requires": { - "vscode-jsonrpc": "8.2.0", - "vscode-languageserver-types": "3.17.5" - } - }, - "vscode-languageserver-textdocument": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", - "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" - }, - "vscode-languageserver-types": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" - }, - "vscode-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" - }, - "watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==" - }, - "web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - }, - "webpack": { - "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", - "requires": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "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==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "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==", - "requires": { - "mime-db": "1.52.0" - } - }, - "schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "webpack-bundle-analyzer": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", - "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", - "requires": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "is-plain-object": "^5.0.0", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" - } - } - }, - "webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "requires": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "dependencies": { - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "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==", - "requires": { - "mime-db": "1.52.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - } - } - }, - "webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", - "requires": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "dependencies": { - "ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "requires": {} - } - } - }, - "webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "requires": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" - }, - "webpackbar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", - "requires": { - "chalk": "^4.1.0", - "consola": "^2.15.3", - "pretty-time": "^1.1.0", - "std-env": "^3.0.1" - } - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "requires": { - "string-width": "^5.0.1" - } - }, - "wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "peer": true - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "requires": {} - }, - "xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==" - }, - "xml-js": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "requires": { - "sax": "^1.2.4" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==" - }, - "zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==" - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 68521868b..000000000 --- a/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "algo", - "version": "0.0.0", - "private": true, - "scripts": { - "docusaurus": "docusaurus", - "start": "docusaurus start", - "build": "docusaurus build", - "swizzle": "docusaurus swizzle", - "deploy": "gh-pages -d build", - "clear": "docusaurus clear", - "serve": "docusaurus serve", - "write-translations": "docusaurus write-translations", - "write-heading-ids": "docusaurus write-heading-ids" - }, - "dependencies": { - "@docusaurus/core": "^3.5.2", - "@docusaurus/plugin-content-blog": "^3.5.2", - "@docusaurus/plugin-content-docs": "^3.5.2", - "@docusaurus/plugin-debug": "^3.5.2", - "@docusaurus/preset-classic": "^3.5.2", - "@docusaurus/theme-mermaid": "^3.5.2", - "@docusaurus/theme-search-algolia": "^3.5.2", - "@fortawesome/free-brands-svg-icons": "^6.6.0", - "@fortawesome/react-fontawesome": "^0.2.2", - "@giscus/react": "^3.0.0", - "@heroicons/react": "^2.1.5", - "@mdx-js/react": "^3.0.0", - "axios": "^1.7.7", - "clsx": "^2.0.0", - "framer-motion": "^11.9.0", - "joi": "^17.13.3", - "mermaid": "^11.0.0", - "prism-react-renderer": "^2.1.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", - "react-icons": "^5.3.0", - "react-lite-youtube-embed": "^2.4.0", - "react-simple-chatbot": "^0.6.0", - "react-toastify": "^10.0.5", - "rehype-katex": "^7.0.1", - "remark-math": "^6.0.0", - "styled-components": "^4.4.1", - "swiper": "^11.1.14" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/types": "3.5.2", - "autoprefixer": "^10.4.20", - "gh-pages": "^6.1.0", - "postcss": "^8.4.47", - "tailwindcss": "^3.4.13" - }, - "browserslist": { - "production": [ - ">0.5%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 3 chrome version", - "last 3 firefox version", - "last 5 safari version" - ] - }, - "engines": { - "node": ">=18.0" - } -} diff --git a/plugins/my-plugin/index.js b/plugins/my-plugin/index.js deleted file mode 100644 index 63612cc0c..000000000 --- a/plugins/my-plugin/index.js +++ /dev/null @@ -1,50 +0,0 @@ -const Joi = require("joi"); - -module.exports = function (context, options) { - return { - name: "my-plugin", - // lifecycle methods - injectHtmlTags() { - return { - headTags: [ - { - tagName: "meta", - attributes: { - "og:description": "My custom OG: Description", - }, - }, - ], - }; - }, - extendCli(cli) { - cli - .command("my-command action") - .description("This is a custom command") - .action(() => { - console.log("Hello World! - This is a custom command!"); - console.log("Plugin options:", options); - }); - }, - configurePostCss(postcssOptions) { - // Add Tailwind CSS and other PostCSS plugins - postcssOptions.plugins = [ - require("postcss-import"), - require("tailwindcss"), - require("autoprefixer"), - ]; - return postcssOptions; - }, - }; -}; - -module.exports.validateOptions = ({ validate, options }) => { - const joiSchema = Joi.object({ - settings: Joi.string().alphanum().min(3).max(30).required(), - api: Joi.string().required(), - keys: Joi.string().min(2).required(), - }); - - const validateOptions = validate(joiSchema, options); - - return validateOptions; -}; \ No newline at end of file diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 1c81bef59..000000000 --- a/renovate.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "extends": [ - "config:base", - "config:recommended", - ":dependencyDashboard" - ], - "schedule": [ - "at any time" - ], - "packageRules": [ - { - "packagePatterns": ["*"], - "groupName": "all dependencies", - "groupSlug": "all" - } - ], - "automerge": false, - "automergeType": "pr", - "prHourlyLimit": 24, - "prConcurrentLimit": 10, - "labels": ["dependencies"], - "reviewers": ["Ajay-Dhangar"] - } \ No newline at end of file diff --git a/sidebars.js b/sidebars.js deleted file mode 100644 index 332758032..000000000 --- a/sidebars.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ - -// @ts-check - -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], - - // But you can create a sidebar manually - /* - tutorialSidebar: [ - 'intro', - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], - */ -}; - -export default sidebars; diff --git a/src/components/AdsComponent/Ads.tsx b/src/components/AdsComponent/Ads.tsx deleted file mode 100644 index 2869594e3..000000000 --- a/src/components/AdsComponent/Ads.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { useEffect } from "react"; -import Head from "@docusaurus/Head"; - -declare global { - interface Window { - adsbygoogle: any[]; - } -} - -const Ads: React.FC = () => { - useEffect(() => { - try { - (window.adsbygoogle = window.adsbygoogle || []).push({}); - } - catch (err) { - console.error(err); - } - }, []); - return ( - <> - - - -
    - - - - -
    - - ); -} diff --git a/src/pages/leaderboard/index.tsx b/src/pages/leaderboard/index.tsx deleted file mode 100644 index cfae2708c..000000000 --- a/src/pages/leaderboard/index.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import Layout from "@theme/Layout"; -import React from "react"; -import { motion } from "framer-motion"; -import { FaCrown } from "react-icons/fa"; - -const Leaderboard: React.FC = () => { - const leaders = [ - { name: "Ajay Dhangar", points: 1500, rank: 1 }, - { name: "Jane Doe", points: 1450, rank: 2 }, - { name: "John Smith", points: 1420, rank: 3 }, - ]; - - return ( - -
    -
    - - Leaderboard - - - - See where you rank against other coders! - - -
    - - - - - - - - - - {leaders.map((leader) => ( - - - - - - ))} - -
    RankNamePoints
    - {leader.rank === 1 ? ( - - ) : ( - leader.rank - )} - {leader.name}{leader.points}
    -
    -
    -
    -
    - ); -}; - -export default Leaderboard; diff --git a/src/pages/markdown-page.md b/src/pages/markdown-page.md deleted file mode 100644 index 9756c5b66..000000000 --- a/src/pages/markdown-page.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Markdown page example ---- - -# Markdown page example - -You don't need React to write simple standalone pages. diff --git a/src/pages/practice/index.tsx b/src/pages/practice/index.tsx deleted file mode 100644 index 700caae12..000000000 --- a/src/pages/practice/index.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import React from "react"; -import { LayoutGroup, motion } from "framer-motion"; -import { FaPlayCircle } from "react-icons/fa"; -import Layout from "@theme/Layout"; - -const Practice: React.FC = () => { - return ( - -
    -
    - - Practice Your Skills - - - - Sharpen your coding skills with hundreds of algorithm problems to practice. - - -
    - {/* Example Practice Problem */} - -

    - Problem 1: Two Sum -

    -

    - Given an array of integers, return indices of the two numbers such that they add up to a specific target. -

    - -
    - - {/* Example Problem 2 */} - -

    - Problem 2: Longest Substring Without Repeating Characters -

    -

    - Find the length of the longest substring without repeating characters. -

    - -
    - - {/* Add more problems as needed */} - - -

    - Problem 2: Add Two Numbers -

    -

    - You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order. -

    - -
    - - -

    - Problem 4: Median of Two Sorted Arrays -

    -

    - Given two sorted arrays, find the median of the two sorted arrays. -

    - -
    - - -

    - Problem 5: Longest Palindromic Substring -

    -

    - Given a string, find the longest palindromic substring in it. -

    - -
    - - -

    - Problem 6: Zigzag Conversion -

    -

    - Convert a string to a zigzag pattern on a given number of rows and read line by line. -

    - -
    - - -

    - Problem 7: Reverse Integer -

    -

    - Given a 32-bit signed integer, reverse its digits. -

    - -
    - - -

    - Problem 8: String to Integer (atoi) -

    -

    - Implement the `atoi` function, which converts a string to an integer. -

    - -
    - - -

    - Problem 9: Palindrome Number -

    -

    - Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward. -

    - -
    - - -

    - Problem 10: Regular Expression Matching -

    -

    - Implement regular expression matching with support for `.` and `*`. -

    - -
    - - -

    - Problem 11: Rotate List -

    -

    - Given the head of a linked list and an integer k, rotate the list to the right by k places. -

    - -
    - -
    -
    -
    -
    - ); -}; - -export default Practice; diff --git a/src/pages/quiz-solutions/array.md b/src/pages/quiz-solutions/array.md deleted file mode 100644 index edfb43741..000000000 --- a/src/pages/quiz-solutions/array.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Array Quiz Solutions -hide_table_of_contents: true ---- - -

    Array Quiz Solutions

    - -
    - -### 1. What will the output of the below code? - -```cpp -#include -using namespace std; - -int main() -{ - int arr[2] = { 1, 2 }; - cout << 0[arr] << ", " << 1[arr] << endl; - return 0; -} -``` -- **Options:** - - A) 1, 2 - - B) Syntax error - - C) Run time error - - D) None -- **Answer:** A) 1, 2 - -
    - Explanation: - In C++, array subscripting works in both ways. `arr[0]` is the same as `0[arr]`. Hence, `0[arr]` gives the first element of the array (1), and `1[arr]` gives the second element (2). Therefore, the output is 1, 2. -
    - - - -### 2. The minimum number of comparisons required to determine if an integer appears more than n/2 times in a sorted array of n integers is -- **Options:** - - A) Θ(n) - - B) Θ(logn) - - C) Θ(n*logn) - - D) Θ(1) -- **Answer:** A) Θ(n) - -
    - Explanation: - In a sorted array, once you find a majority element (if it exists), you only need to perform a linear scan to count its occurrences and verify if it appears more than n/2 times. Thus, the minimum number of comparisons is Θ(n). -
    - - - -### 3. An algorithm performs (logN) find operations, N insert operations, (logN) delete operations, and (logN) decrease-key operations on a set of data items with keys drawn from a linearly ordered set. Which one of the following data structures is most suited for the algorithm to achieve the best total asymptotic complexity? -- **Options:** - - A) Unsorted array - - B) Min-heap - - C) Sorted array - - D) Sorted doubly linked list -- **Answer:** B) Min-heap - -
    - Explanation: - Min-heaps are optimal for algorithms that require frequent insertion, deletion, and decrease-key operations. A min-heap supports insertions in O(log N) time and is efficient for find-minimum and delete-minimum operations, making it ideal for this problem. -
    - - - -### 4. Consider a two-dimensional array consisting of –ve and +ve numbers. What would be the worst-case time complexity of an algorithm to segregate the numbers having the same sign altogether? -- **Options:** - - A) O(N) - - B) O(N Log N) - - C) O(N * N) - - D) O(N Log Log N) -- **Answer:** A) O(N) - -
    - Explanation: - This problem can be solved in linear time by using the two-pointer technique, one starting at the beginning and the other at the end. Thus, the worst-case time complexity is O(N). -
    - - - -### 5. Let A[1...n] be an array of n distinct numbers. If i < j and A[i] > A[j], then the pair (i, j) is called an inversion of A. What is the expected number of inversions in any permutation on n elements? -- **Options:** - - A) n(n-1)/2 - - B) n(n-1)/4 - - C) n(n+1)/4 - - D) 2n[logn] -- **Answer:** A) n(n-1)/2 - -
    - Explanation: - An inversion occurs when two elements are out of order. In a worst-case scenario (a completely reverse sorted array), the number of inversions is n(n-1)/2, which is the maximum number of comparisons needed to sort the array. -
    - - - -

    -Now, let's Discuss! -

    - - - -
    \ No newline at end of file diff --git a/src/pages/quiz-solutions/b-trees.md b/src/pages/quiz-solutions/b-trees.md deleted file mode 100644 index 595a597a3..000000000 --- a/src/pages/quiz-solutions/b-trees.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: B-Tree Quiz -hide_table_of_contents: true ---- - -

    B-Tree Quiz Solutions

    - -
    - -### 1. What is a B-Tree? - -- **A)** A binary search tree that is balanced. -- **B)** A tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time. -- **C)** A type of tree that only allows three children per node. -- **D)** A tree used exclusively for storing strings. - -**Solution:** **B)** A tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time. - -
    - Explanation: - A B-Tree is a self-balancing tree data structure that keeps data sorted and allows operations like searching, insertion, and deletion in logarithmic time. It is widely used in database and file systems. -
    - - - -### 2. What is the minimum degree of a B-Tree? - -- **A)** The minimum number of keys a node can contain. -- **B)** The maximum number of children a node can have. -- **C)** The maximum number of keys a node can contain. -- **D)** The number of levels in the tree. - -**Solution:** **A)** The minimum number of keys a node can contain. - -
    - Explanation: - The minimum degree `t` of a B-Tree is the minimum number of keys each node can have, except for the root node. It defines the tree's branching factor. -
    - - - -### 3. In a B-Tree, each node can have a maximum of how many children? - -- **A)** 2 -- **B)** 3 -- **C)** 2t -- **D)** t - -**Solution:** **C)** 2t - -
    - Explanation: - In a B-Tree, each node can have up to `2t` children, where `t` is the minimum degree of the tree. The exact number of children depends on the number of keys in the node. -
    - - - -### 4. What is the main advantage of using a B-Tree over a binary search tree? - -- **A)** Faster search times. -- **B)** Less memory usage. -- **C)** Better balance and reduced height. -- **D)** Simplicity of implementation. - -**Solution:** **C)** Better balance and reduced height. - -
    - Explanation: - The primary advantage of a B-Tree is that it remains balanced, keeping its height minimal, which ensures that the time for insertions, deletions, and searches is kept logarithmic. -
    - - - -### 5. When inserting into a B-Tree, what happens if a node exceeds the maximum number of keys? - -- **A)** The node is deleted. -- **B)** The tree is restructured. -- **C)** The node is split into two nodes. -- **D)** No action is taken. - -**Solution:** **C)** The node is split into two nodes. - -
    - Explanation: - If a node exceeds the maximum allowed number of keys, it is split into two nodes, and the median key is pushed up to the parent node. This ensures the B-Tree remains balanced. -
    - - - -### 6. What does it mean for a B-Tree to be balanced? - -- **A)** All leaves are at the same depth. -- **B)** The number of keys in each node is equal. -- **C)** Each node contains the same number of children. -- **D)** The tree is a complete binary tree. - -**Solution:** **A)** All leaves are at the same depth. - -
    - Explanation: - A B-Tree is balanced because all leaf nodes appear at the same depth, ensuring that the tree's operations are efficient in terms of time complexity. -
    - - - -### 7. How is deletion handled in a B-Tree? - -- **A)** Simply remove the key from the node. -- **B)** Reorganize keys within the node only. -- **C)** It may require borrowing a key from a sibling or merging nodes. -- **D)** Deletion is not allowed in B-Trees. - -**Solution:** **C)** It may require borrowing a key from a sibling or merging nodes. -**Explanation:** Deletion in a B-Tree may lead to an underflow in a node, in which case keys may be borrowed from adjacent sibling nodes or merged with them to maintain the tree structure. - - - -### 8. Which of the following properties is NOT true for B-Trees? - -- **A)** All leaf nodes are at the same level. -- **B)** Each internal node has at least t-1 keys. -- **C)** The root node can have fewer than t keys. -- **D)** Every node can have an arbitrary number of children. - -**Solution:** **D)** Every node can have an arbitrary number of children. - -
    - Explanation: - In a B-Tree, the number of children a node can have is limited by the minimum degree `t`. Each internal node has between `t-1` and `2t-1` keys, but the root node can have fewer than `t` keys. -
    - - - -### 9. In which applications are B-Trees commonly used? - -- **A)** In-memory data structures. -- **B)** File systems and databases. -- **C)** Simple data retrieval tasks. -- **D)** Small data storage. - -**Solution:** **B)** File systems and databases. - -
    - Explanation: - B-Trees are commonly used in file systems and databases due to their ability to handle large amounts of data efficiently and maintain balanced search times. -
    - - - -### 10. What is the relationship between the height of a B-Tree and its order? - -- **A)** The height increases as the order increases. -- **B)** The height decreases as the order increases. -- **C)** The height is independent of the order. -- **D)** The height and order are always equal. - -**Solution:** **B)** The height decreases as the order increases. - -
    - Explanation: - As the order of a B-Tree increases, the number of keys per node increases, which reduces the height of the tree. This relationship helps maintain the tree's balance and efficiency. -
    - - - -

    -Now, let's Discuss! -

    - - - -
    \ No newline at end of file diff --git a/src/pages/quiz-solutions/binary-search-trees.md b/src/pages/quiz-solutions/binary-search-trees.md deleted file mode 100644 index b7d278fd2..000000000 --- a/src/pages/quiz-solutions/binary-search-trees.md +++ /dev/null @@ -1,111 +0,0 @@ -# Binary Search Tree Quiz - -## Questions and Solutions - -### 1. What is a binary search tree (BST)? -- **Options:** - - A) A tree where each node has at most two children. - - B) A tree where the left child is greater than the parent. - - C) A tree where the left child is less than the parent and the right child is greater. - - D) A tree where all nodes are on one side. -- **Answer:** C) A tree where the left child is less than the parent and the right child is greater. -- **Explanation:** In a BST, each node's left child is less than the node, and the right child is greater, maintaining the sorted order. - ---- - -### 2. What is the time complexity for searching an element in a balanced binary search tree? -- **Options:** - - A) O(n) - - B) O(log n) - - C) O(n log n) - - D) O(1) -- **Answer:** B) O(log n) -- **Explanation:** In a balanced BST, the height of the tree is log(n), making search operations efficient at O(log n). - ---- - -### 3. Which of the following is true about the in-order traversal of a binary search tree? -- **Options:** - - A) It visits the nodes in descending order. - - B) It visits the nodes in ascending order. - - C) It visits nodes in random order. - - D) It does not visit all nodes. -- **Answer:** B) It visits the nodes in ascending order. -- **Explanation:** In-order traversal of a BST visits nodes in ascending order due to the property of BST. - ---- - -### 4. Which operation in a binary search tree can have a worst-case time complexity of O(n)? -- **Options:** - - A) Insertion - - B) Deletion - - C) Searching - - D) All of the above -- **Answer:** D) All of the above -- **Explanation:** In the worst case, all operations can degrade to O(n) if the tree becomes unbalanced. - ---- - -### 5. What is the maximum number of nodes in a binary search tree with a height of 'h'? -- **Options:** - - A) h - - B) 2^h - 1 - - C) 2^h - - D) h^2 -- **Answer:** B) 2^h - 1 -- **Explanation:** A binary tree with height h can have at most 2^h - 1 nodes, which is full at height h. - ---- - -### 6. Which of the following traversals can be used to get a sorted order of elements in a binary search tree? -- **Options:** - - A) Pre-order - - B) In-order - - C) Post-order - - D) Level-order -- **Answer:** B) In-order -- **Explanation:** In-order traversal yields a sorted order of elements in a BST. - ---- - -### 7. In a binary search tree, what would happen if you tried to insert a duplicate value? -- **Options:** - - A) It will replace the existing value. - - B) It will be ignored. - - C) It will cause an error. - - D) It will create a duplicate node. -- **Answer:** B) It will be ignored. -- **Explanation:** BSTs typically do not allow duplicate values, so the insertion of a duplicate is ignored. - ---- - -### 8. What is the time complexity for finding the lowest common ancestor (LCA) of two nodes in a binary search tree? -- **Options:** - - A) O(n) - - B) O(log n) - - C) O(h) - - D) O(1) -- **Answer:** C) O(h) -- **Explanation:** Finding the LCA can take O(h) time, where h is the height of the tree, depending on the position of the nodes. - ---- - -### 9. Which of the following operations requires tree rotation in a binary search tree? -- **Options:** - - A) Insertion - - B) Deletion - - C) Balancing - - D) Both A and B -- **Answer:** C) Balancing -- **Explanation:** Rotations are needed during insertion and deletion to maintain balance in self-balancing BSTs. - ---- - -### 10. How can you check if a binary tree is a binary search tree? -- **Options:** - - A) By checking if in-order traversal is sorted. - - B) By checking if all nodes have two children. - - C) By checking if all nodes have unique values. - - D) By performing a pre-order traversal. -- **Answer:** A) By checking if in-order traversal is sorted. -- **Explanation:** If the in-order traversal of the tree is sorted, it confirms that the tree is a valid BST. diff --git a/src/pages/quiz-solutions/binary-trees.md b/src/pages/quiz-solutions/binary-trees.md deleted file mode 100644 index b74647646..000000000 --- a/src/pages/quiz-solutions/binary-trees.md +++ /dev/null @@ -1,89 +0,0 @@ -# Binary Tree Quiz - -## Questions - -### Easy Questions - -1. **What is the height of a binary tree with a single node?** - - A) 0 - - B) 1 - - C) 2 - - D) Depends on the tree - **Answer:** B) 1 - **Explanation:** The height of a tree is defined as the number of edges on the longest path from the root to a leaf. A single node has height 0, but considering the node itself, the height is 1. - -2. **Which traversal of a binary tree visits nodes in the order: left, root, right?** - - A) Pre-order - - B) In-order - - C) Post-order - - D) Level-order - **Answer:** B) In-order - **Explanation:** In-order traversal visits the left subtree first, then the root node, followed by the right subtree. - -3. **In a binary tree, what is the maximum number of nodes at depth 'd'?** - - A) 2^d - - B) 2^(d+1) - 1 - - C) 2d - - D) d^2 - **Answer:** A) 2^d - **Explanation:** At depth 'd', the maximum number of nodes is \(2^d\) because each level can double the number of nodes of the previous level. - -### Average Questions - -4. **What is the time complexity of searching for an element in a balanced binary search tree?** - - A) O(n) - - B) O(log n) - - C) O(n log n) - - D) O(1) - **Answer:** B) O(log n) - **Explanation:** In a balanced binary search tree, the height is logarithmic with respect to the number of nodes, leading to O(log n) time complexity for search operations. - -5. **Which of the following statements is true about a binary search tree?** - - A) The left subtree of a node contains only nodes with keys less than the node's key. - - B) The right subtree of a node contains only nodes with keys greater than the node's key. - - C) Both A and B. - - D) None of the above. - **Answer:** C) Both A and B. - **Explanation:** A binary search tree maintains the property where the left subtree has nodes with keys less than the parent's key, and the right subtree has nodes with keys greater than the parent's key. - -6. **In a binary tree, which of the following properties is true for a complete binary tree?** - - A) All levels are completely filled except possibly the last level. - - B) All nodes are as far left as possible. - - C) All leaves are at the same level. - - D) A and B. - **Answer:** D) A and B. - **Explanation:** A complete binary tree has all levels fully filled except possibly the last level, which is filled from left to right. - -### Difficult Questions - -7. **What is the maximum depth of a binary tree with 'n' nodes?** - - A) n - - B) log n - - C) n/2 - - D) n - 1 - **Answer:** A) n - **Explanation:** In the worst case (for example, a skewed tree), the maximum depth can be equal to the number of nodes (n). - -8. **Which of the following algorithms can be used to find the lowest common ancestor (LCA) in a binary tree?** - - A) Recursive approach - - B) Iterative approach - - C) Both A and B - - D) None of the above - **Answer:** C) Both A and B - **Explanation:** Both recursive and iterative approaches can be used to find the LCA, depending on the structure and properties of the tree. - -9. **Which of the following traversal methods would give the nodes of a binary tree in descending order?** - - A) In-order traversal - - B) Pre-order traversal - - C) Post-order traversal - - D) Reverse in-order traversal - **Answer:** D) Reverse in-order traversal - **Explanation:** Reverse in-order traversal visits nodes in the order of right subtree, root, and then left subtree, resulting in a descending order. - -10. **What is the worst-case time complexity for inserting an element in a binary search tree?** - - A) O(log n) - - B) O(n) - - C) O(n log n) - - D) O(1) - **Answer:** B) O(n) - **Explanation:** In the worst case, if the tree is skewed, the insertion operation could take O(n) time. diff --git a/src/pages/quiz-solutions/index.tsx b/src/pages/quiz-solutions/index.tsx deleted file mode 100644 index f910a6592..000000000 --- a/src/pages/quiz-solutions/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; -import Layout from "@theme/Layout"; -import Header from "../../components/Header"; -import QuizCard from "../../components/QuizCard"; -import quizData from "../../data/quizData"; - -const Quizes: React.FC = () => ( - -
    -
    -
    - {quizData.map((quiz, index) => ( - - ))} -
    -
    -
    -); - -export default Quizes; diff --git a/src/pages/quiz-solutions/queues.md b/src/pages/quiz-solutions/queues.md deleted file mode 100644 index 870576a38..000000000 --- a/src/pages/quiz-solutions/queues.md +++ /dev/null @@ -1,162 +0,0 @@ - -# Queue Quiz - -## 1. Following is C-like pseudo-code of a function that takes a Queue as an argument, and uses a stack S to do processing. - -```c -void fun(Queue *Q) -{ - Stack S; // Say it creates an empty stack S - - // Run while Q is not empty - while (!isEmpty(Q)) - { - // deQueue an item from Q and push the dequeued item to S - push(&S, deQueue(Q)); - } - - // Run while Stack S is not empty - while (!isEmpty(&S)) - { - // Pop an item from S and enqueue the popped item to Q - enQueue(Q, pop(&S)); - } -} -``` - -- **Options:** - - A) Removes the last from Q - - B) Keeps the Q same as it was before the call - - C) Makes Q empty - - D) Reverses the Q - -- **Answer:** D) Reverses the Q - -- **Explanation:** - The function uses a stack to reverse the queue. First, all elements are dequeued from the queue and pushed into the stack. Then, elements are popped from the stack and enqueued back into the queue. Since the stack follows LIFO order, the queue is reversed. - - -## 2. How many stacks are needed to implement a queue? Consider the situation where no other data structure like arrays or linked lists is available to you. - -- **Options:** - - A) 1 - - B) 2 - - C) 3 - - D) 4 - -- **Answer:** B) 2 - -- **Explanation:** - To implement a queue using stacks, two stacks are required. One stack is used for enqueuing elements, and the other is used for dequeuing them. - - -## 3. Which of the following operations on a queue data structure has a time complexity of O(1)? - -- **Options:** - - A) Enqueue - - B) Dequeue - - C) Peek - - D) Clear - -- **Answer:** A and B - -- **Explanation:** - Both enqueue and dequeue operations in a standard queue have a time complexity of O(1) as they involve simple pointer adjustments. - - -## 4. A priority queue can be efficiently implemented using which of the following data structures? - -- **Options:** - - A) Array - - B) Linked List - - C) Heap Data Structures like Binary Heap, Fibonacci Heap - - D) None of the above - -- **Answer:** C) Heap Data Structures like Binary Heap, Fibonacci Heap - -- **Explanation:** - Heaps are the most efficient data structures to implement priority queues as they allow insertion and removal of elements in logarithmic time. - - -## 5. Which of the following is true about linked list implementation of a queue? - -- **Options:** - - A) In push operation, if new nodes are inserted at the beginning of the linked list, then in pop operation, nodes must be removed from the end. - - B) In push operation, if new nodes are inserted at the end, then in pop operation, nodes must be removed from the beginning. - - C) Both of the above - - D) None of the above - -- **Answer:** C) Both of the above - -- **Explanation:** - In a linked list implementation of a queue, nodes can either be inserted at the beginning or end, and the opposite operation should be performed to remove nodes, depending on where the nodes were added. - - -## 6. A Priority-Queue is implemented as a Max-Heap. Initially, it has 5 elements. The level-order traversal of the heap is given below: 10, 8, 5, 3, 2. Two new elements '1' and '7' are inserted in the heap in that order. The level-order traversal of the heap after the insertion of the elements is: - -- **Options:** - - A) 10, 8, 7, 5, 3, 2, 1 - - B) 10, 8, 7, 2, 3, 1, 5 - - C) 10, 8, 7, 1, 2, 3, 5 - - D) 10, 8, 7, 3, 2, 1, 5 - -- **Answer:** A) 10, 8, 7, 5, 3, 2, 1 - -- **Explanation:** - Inserting elements '1' and '7' into the Max-Heap results in the heap structure adjusting such that the maximum element remains at the root. The final level-order traversal after the insertions is 10, 8, 7, 5, 3, 2, 1. - - -## 7. Which of the following is true about the circular queue? - -- **Options:** - - A) It avoids memory wastage compared to the simple linear queue. - - B) It has a fixed size and cannot be dynamically resized. - - C) Dequeue and enqueue operations wrap around at the end. - - D) All of the above - -- **Answer:** D) All of the above - -- **Explanation:** - Circular queues eliminate the problem of unused space in linear queues by wrapping around the enqueue and dequeue operations. It uses fixed-size memory but optimizes the use of available space. - - -## 8. In a circular queue, if `front == rear + 1`, what does it signify? - -- **Options:** - - A) Queue is empty - - B) Queue is full - - C) Queue is circular - - D) Invalid state - -- **Answer:** B) Queue is full - -- **Explanation:** - In a circular queue, the condition `front == rear + 1` indicates that the queue is full because the rear has wrapped around and is just before the front. - - -## 9. What is the time complexity of inserting an element in an unsorted priority queue? - -- **Options:** - - A) O(1) - - B) O(log n) - - C) O(n) - - D) O(n^2) - -- **Answer:** A) O(1) - -- **Explanation:** - Inserting an element into an unsorted priority queue takes constant time because there is no need to maintain order during insertion. However, removal of the highest priority element will take O(n) time. - - -## 10. How is a double-ended queue (Deque) different from a standard queue? - -- **Options:** - - A) It allows insertion and deletion from both ends. - - B) It only allows deletion from one end. - - C) It is always implemented using a circular array. - - D) It has more memory overhead compared to a queue. - -- **Answer:** A) It allows insertion and deletion from both ends. - -- **Explanation:** - A double-ended queue (Deque) is a generalized form of a queue where insertion and deletion operations can be performed at both the front and rear ends. diff --git a/src/pages/quiz-solutions/red-black-trees.md b/src/pages/quiz-solutions/red-black-trees.md deleted file mode 100644 index 1009318a5..000000000 --- a/src/pages/quiz-solutions/red-black-trees.md +++ /dev/null @@ -1,111 +0,0 @@ -# Red-Black Tree Quiz - -## Questions and Solutions - -### 1. What is a Red-Black Tree? -- **Options:** - - A) A binary search tree with additional color properties. - - B) A tree that only allows red nodes. - - C) A tree where all nodes are black. - - D) A tree with no duplicate values. -- **Answer:** A) A binary search tree with additional color properties. -- **Explanation:** A Red-Black Tree is a binary search tree that follows specific properties to maintain balance, ensuring efficient operations. - ---- - -### 2. What are the two colors used in a Red-Black Tree? -- **Options:** - - A) Red and Blue - - B) Black and White - - C) Red and Black - - D) Green and Yellow -- **Answer:** C) Red and Black -- **Explanation:** Red-Black Trees use two colors (red and black) to maintain balance and ensure that the tree remains approximately balanced. - ---- - -### 3. What is the maximum height of a Red-Black Tree with n nodes? -- **Options:** - - A) O(n) - - B) O(log n) - - C) O(2 log n) - - D) O(sqrt(n)) -- **Answer:** B) O(log n) -- **Explanation:** The maximum height of a Red-Black Tree is O(log n), ensuring that operations like insertion, deletion, and search remain efficient. - ---- - -### 4. Which of the following properties must be true for a Red-Black Tree? -- **Options:** - - A) The root must be red. - - B) Red nodes cannot have red children. - - C) All leaves are red. - - D) Every path from a node to its leaves must have the same number of red nodes. -- **Answer:** B) Red nodes cannot have red children. -- **Explanation:** One of the fundamental properties of Red-Black Trees is that red nodes cannot have red children, which helps maintain balance. - ---- - -### 5. What is the role of rotations in Red-Black Trees? -- **Options:** - - A) To delete nodes. - - B) To maintain the balance of the tree. - - C) To insert nodes. - - D) To traverse the tree. -- **Answer:** B) To maintain the balance of the tree. -- **Explanation:** Rotations are used to restore balance in the tree after insertions and deletions, ensuring the Red-Black properties are maintained. - ---- - -### 6. When a new node is inserted into a Red-Black Tree, what color is it initially? -- **Options:** - - A) Red - - B) Black - - C) Blue - - D) Green -- **Answer:** A) Red -- **Explanation:** Newly inserted nodes in a Red-Black Tree are always colored red to maintain the tree's balance. - ---- - -### 7. In a Red-Black Tree, how do you ensure that the tree remains balanced after an insertion? -- **Options:** - - A) By performing rotations and recoloring nodes. - - B) By deleting the inserted node. - - C) By adjusting the tree's height. - - D) By increasing the tree's depth. -- **Answer:** A) By performing rotations and recoloring nodes. -- **Explanation:** Balancing is achieved through rotations and recoloring, following specific rules based on the colors of the affected nodes. - ---- - -### 8. Which of the following scenarios requires a right rotation in a Red-Black Tree? -- **Options:** - - A) Inserting a red node in the left subtree of a left child. - - B) Inserting a red node in the right subtree of a right child. - - C) Inserting a red node in the right subtree of a left child. - - D) Inserting a black node. -- **Answer:** A) Inserting a red node in the left subtree of a left child. -- **Explanation:** This scenario causes an imbalance that is corrected with a right rotation. - ---- - -### 9. What happens if a Red-Black Tree property is violated during an insertion? -- **Options:** - - A) The tree is deleted. - - B) The tree is rebalanced. - - C) The insertion is aborted. - - D) No action is taken. -- **Answer:** B) The tree is rebalanced. -- **Explanation:** If any property is violated, the tree undergoes rebalancing through rotations and recoloring to restore its properties. - ---- - -### 10. What is the primary advantage of using a Red-Black Tree over a regular Binary Search Tree? -- **Options:** - - A) It requires less memory. - - B) It guarantees O(log n) time complexity for insertions, deletions, and searches. - - C) It can store duplicate values. - - D) It allows for faster traversals. -- **Answer:** B) It guarantees O(log n) time complexity for insertions, deletions, and searches. -- **Explanation:** The balanced nature of Red-Black Trees ensures that operations maintain logarithmic time complexity, making them efficient for dynamic sets. diff --git a/src/pages/quiz-solutions/stack.md b/src/pages/quiz-solutions/stack.md deleted file mode 100644 index 0acbd475c..000000000 --- a/src/pages/quiz-solutions/stack.md +++ /dev/null @@ -1,270 +0,0 @@ - -# Stack Quiz Solutions - -## Question 1 - -**Question:** - -Following is C-like pseudo code of a function that takes a number as an argument, and uses a stack S to do processing. - -```c -void fun(int n) -{ - Stack S; // Say it creates an empty stack S - while (n > 0) - { - push(&S, n%2); - n = n/2; - } - - while (!isEmpty(&S)) - printf("%d ", pop(&S)); -} -``` - -What does the above function do in general? - -**Options:** - -- A) Prints binary representation of n in reverse order -- B) Prints binary representation of n -- C) Prints the value of Logn -- D) Prints the value of Logn in reverse order - -**Answer:** A) Prints binary representation of n in reverse order - -**Explanation:** - -The first loop converts the number `n` to its binary equivalent by repeatedly dividing `n` by 2 and pushing the remainder (which is the binary digit) onto the stack. The second loop pops the stack and prints the binary digits, which results in the binary number being printed in reverse order. - ---- - -## Question 2 - -**Question:** - -Consider the following pseudocode that uses a stack: - -```c -declare a stack of characters -while (there are more characters in the word to read) -{ - read a character - push the character on the stack -} -while (the stack is not empty) -{ - pop a character off the stack - write the character to the screen -} -``` - -What is the output for input "geeksquiz"? - -**Options:** - -- A) geeksquizgeeksquiz -- B) ziuqskeeg -- C) geeksquiz -- D) ziuqskeegziuqskeeg - -**Answer:** B) ziuqskeeg - -**Explanation:** - -The first loop pushes all the characters of the word "geeksquiz" onto the stack. The second loop pops the stack, which reverses the order of the characters, resulting in "ziuqskeeg". - ---- - -## Question 3 - -**Question:** - -Following is an incorrect pseudocode for the algorithm which is supposed to determine whether a sequence of parentheses is balanced: - -```c -declare a character stack -while (more input is available) -{ - read a character - if (the character is a '(' ) - push it on the stack - else if (the character is a ')' and the stack is not empty) - pop a character off the stack - else - print "unbalanced" and exit -} -print "balanced" -``` - -Which of these unbalanced sequences does the above code think is balanced? - -**Options:** - -- A) ((()) -- B) ())(()) -- C) (()()) -- D) (()))() - -**Answer:** D) (()))() - -**Explanation:** - -The code checks if each ')' has a corresponding '(' by using a stack. However, it fails to detect unbalanced sequences like `D) (()))()` because it only checks if the stack is empty at the end, and does not properly handle cases with too many closing parentheses. - ---- - -## Question 4 - -**Question:** - -The following postfix expression with single-digit operands is evaluated using a stack: - -``` -8 2 3 ^ / 2 3 * + 5 1 * - -``` - -The top two elements of the stack after the first `*` is evaluated are: - -**Options:** - -- A) 6, 1 -- B) 5, 7 -- C) 3, 2 -- D) 1, 5 - -**Answer:** A) 6, 1 - -**Explanation:** - -The postfix expression is evaluated from left to right. After the first multiplication operation (`2 * 3`), the top two elements left on the stack are `6` and `1`. - ---- - -## Question 5 - -**Question:** - -A single array `A[1..MAXSIZE]` is used to implement two stacks. The two stacks grow from opposite ends of the array. If the space is to be used efficiently, the condition for “stack full” is: - -**Options:** - -- A) (top1 = MAXSIZE/2) and (top2 = MAXSIZE/2+1) -- B) top1 + top2 + 1 = MAXSIZE -- C) (top1= MAXSIZE/2) or (top2 = MAXSIZE) -- D) top1= top2 -1 - -**Answer:** B) top1 + top2 + 1 = MAXSIZE - -**Explanation:** - -For two stacks growing from opposite ends of the array, the space is fully utilized when the sum of the indices of the top elements of both stacks equals `MAXSIZE - 1`. - ---- - -## Question 6 - -**Question:** - -Assume that the operators `+`, `-`, `×` are left-associative and `^` is right-associative. The order of precedence (from highest to lowest) is `^`, `×`, `+`, `-`. The postfix expression corresponding to the infix expression `a + b × c - d ^ e ^ f` is: - -**Options:** - -- A) `abc × + def ^ ^ -` -- B) `abc × + de ^ f ^ -` -- C) `ab + c × d - e ^ f ^` -- D) `- + a × bc ^ ^ def` - -**Answer:** A) abc × + def ^ ^ - - -**Explanation:** - -Following the operator precedence and associativity rules, the correct postfix expression is `abc × + def ^ ^ -`. - ---- - -## Question 7 - -**Question:** - -The result of evaluating the postfix expression `10 5 + 60 6 / * 8 –` is: - -**Options:** - -- A) 284 -- B) 213 -- C) 142 -- D) 71 - -**Answer:** C) 142 - -**Explanation:** - -Evaluating the postfix expression step by step: -- `10 5 +` → 15 -- `60 6 /` → 10 -- `15 * 10` → 150 -- `150 - 8` → 142 - ---- - -## Question 8 - -**Question:** - -A function `f` defined on stacks of integers satisfies the following properties: `f(∅) = 0` and `f(push(S, i)) = max(f(S), 0) + i` for all stacks `S` and integers `i`. If a stack `S` contains the integers `2, -3, 2, -1, 2` in order from bottom to top, what is `f(S)`? - -**Options:** - -- A) 6 -- B) 4 -- C) 3 -- D) 2 - -**Answer:** A) 6 - -**Explanation:** - -Evaluating the function `f` for each push operation results in the maximum sum being 6. - ---- - -## Question 9 - -**Question:** - -A priority queue `Q` is used to implement a stack `S` that stores characters. `PUSH(C)` is implemented as `INSERT(Q, C, K)` where `K` is an appropriate integer key chosen by the implementation. For a sequence of operations, the keys chosen are in: - -**Options:** - -- A) Non-increasing order -- B) Non-decreasing order -- C) Strictly increasing order -- D) Strictly decreasing order - -**Answer:** C) Strictly increasing order - -**Explanation:** - -For the stack to behave correctly with a priority queue, each push operation should use a key that is strictly greater than the previous one, ensuring the correct order of pop operations. - ---- - -## Question 10 - -**Question:** - -If the sequence of operations - `push(1)`, `push(2)`, `pop`, `push(1)`, `push(2)`, `pop`, `pop`, `pop`, `push(2)`, `pop` are performed on a stack, the sequence of popped out values is: - -**Options:** - -- A) 2,2,1,1,2 -- B) 2,2,1,2,2 -- C) 2,1,2,2,1 -- D) 2,1,2,2,2 - -**Answer:** C) 2,1,2,2,1 - -**Explanation:** - -Following the sequence of operations on the stack, the values are popped in the order `2,1,2,2,1`. diff --git a/src/pages/quizes/arrays.tsx b/src/pages/quizes/arrays.tsx deleted file mode 100644 index 31d6b48f0..000000000 --- a/src/pages/quizes/arrays.tsx +++ /dev/null @@ -1,252 +0,0 @@ -import React, { useState } from "react"; -import Layout from "@theme/Layout"; - -const ArrayQuiz: React.FC = () => { - const questions = [ - { - question: ( - <> - 1. What will the output of the below code? -
    -            {`#include 
    -using namespace std;
    -
    -int main()
    -{
    -    int arr[2] = { 1, 2 };
    -    cout << 0[arr] << ", " << 1[arr] << endl;
    -    return 0;
    -}`}
    -          
    - - ), - options: ["A) 1, 2", "B) Syntax error", "C) Run time error", "D) None"], - answer: "A) 1, 2", - }, - { - question: ( - <> - 2. What will the output of the below code? -
    -            {`#include 
    -using namespace std;
    -
    -int main()
    -{
    -    int arr[5] = { 1, 2, 3, 4, 5 };
    -    cout << arr[5] << endl;
    -    return 0;
    -}`}
    -          
    - - ), - options: ["A) 5", "B) 0", "C) Garbage value", "D) None"], - answer: "C) Garbage value", - }, - { - question: ( - <> - 3. What will the output of the below code? -
    -            {`#include 
    -using namespace std;
    -
    -int main()
    -{
    -    int arr[5] = { 1, 2, 3, 4, 5 };
    -    cout << arr[4] << endl;
    -    return 0;
    -}`}
    -          
    - - ), - options: ["A) 5", "B) 0", "C) 4", "D) None"], - answer: "A) 5", - }, - { - question: ( - <> - 4. What will the output of the below code? -
    -            {`#include 
    -using namespace std;
    -
    -int main()
    -{
    -    int arr[5] = { 1, 2, 3, 4, 5 };
    -    cout << arr[0] << endl;
    -    return 0;
    -}`}
    -          
    - - ), - options: ["A) 1", "B) 0", "C) 5", "D) None"], - answer: "A) 1", - }, - { - question: ( - <> - 5. What is the time complexity of accessing an element in an array by - its index? - - ), - options: ["A) O(1)", "B) O(n)", "C) O(log n)", "D) O(n^2)"], - answer: "A) O(1)", - }, - { - question: ( - <>6. Which of the following statements is true about arrays in C++? - ), - options: [ - "A) The elements of an array are stored in contiguous memory locations", - "B) The elements of an array are stored in non-contiguous memory locations", - "C) The elements of an array are stored in random memory locations", - "D) None of the above", - ], - answer: - "A) The elements of an array are stored in contiguous memory locations", - }, - { - question: ( - <> - 7. In C++, if an array is declared as int arr[5];, what will be the - default value of its elements? - - ), - options: ["A) 0", "B) 1", "C) Random value", "D) None"], - answer: "A) 0", - }, - { - question: ( - <> - 8. What will be the output of the below code? -
    -            {`#include 
    -using namespace std;
    -
    -int main()
    -{
    -    int arr[5];
    -    cout << arr[0] << endl;
    -    return 0;
    -}`}
    -          
    - - ), - options: ["A) 0", "B) 1", "C) Random value", "D) None"], - answer: "A) 0", - }, - { - question: ( - <> - 9. What will be the output of the below code? -
    -            {`#include 
    -using namespace std;
    -
    -int main()
    -{
    -    int arr[5] = { 1, 2, 3, 4, 5 };
    -    cout << arr << endl;
    -    return 0;
    -}`}
    -          
    - - ), - options: ["A) Address of the first element", "B) 1", "C) 2", "D) None"], - answer: "A) Address of the first element", - }, - ]; - - const [currentQuestion, setCurrentQuestion] = useState(0); - const [score, setScore] = useState(0); - const [showResult, setShowResult] = useState(false); - const [selectedOption, setSelectedOption] = useState(null); - const [userAnswers, setUserAnswers] = useState([]); - - const handleAnswer = (selected: string) => { - setSelectedOption(selected); - setUserAnswers((prevAnswers) => [...prevAnswers, selected]); - if (selected === questions[currentQuestion].answer) { - setScore(score + 1); - } - }; - - const nextQuestion = () => { - if (currentQuestion < questions.length - 1) { - setCurrentQuestion(currentQuestion + 1); - setSelectedOption(null); - } else { - setShowResult(true); - } - }; - - return ( - -
    -
    -

    Quiz on Arrays

    - {showResult ? ( -
    -
    -

    - Your Score: {score} 🎉 -

    -

    - {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} -

    -
    - - {/* Solutions Section */} -
    -

    Solutions:

    - {questions.map((q, index) => ( -
    -

    {q.question}

    -

    - Your Answer: {userAnswers[index]} -

    -

    - Correct Answer: {q.answer} -

    -

    - Explanation: {q.explanation} -

    -
    - ))} -
    -
    - ) : ( -
    -

    - {questions[currentQuestion].question} -

    -
    - {questions[currentQuestion].options.map((option, index) => ( - - ))} -
    - -
    - )} -
    -
    -
    - ); -}; - -export default ArrayQuiz; diff --git a/src/pages/quizes/b-tree.tsx b/src/pages/quizes/b-tree.tsx deleted file mode 100644 index 2cdcd554a..000000000 --- a/src/pages/quizes/b-tree.tsx +++ /dev/null @@ -1,203 +0,0 @@ -import React, { useState } from "react"; -import Layout from "@theme/Layout"; - -const BTree: React.FC = () => { - const questions = [ - { - question: "1. What is a B-Tree?", - options: [ - "A) A binary search tree that is balanced.", - "B) A tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time.", - "C) A type of tree that only allows three children per node.", - "D) A tree used exclusively for storing strings.", - ], - answer: - "B) A tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time.", - }, - { - question: "2. What is the minimum degree of a B-Tree?", - options: [ - "A) The minimum number of keys a node can contain.", - "B) The maximum number of children a node can have.", - "C) The maximum number of keys a node can contain.", - "D) The number of levels in the tree.", - ], - answer: "A) The minimum number of keys a node can contain.", - }, - { - question: - "3. In a B-Tree, each node can have a maximum of how many children?", - options: ["A) 2", "B) 3", "C) 2t", "D) t"], - answer: "C) 2t", - }, - { - question: - "4. What is the main advantage of using a B-Tree over a binary search tree?", - options: [ - "A) Faster search times.", - "B) Less memory usage.", - "C) Better balance and reduced height.", - "D) Simplicity of implementation.", - ], - answer: "C) Better balance and reduced height.", - }, - { - question: - "5. When inserting into a B-Tree, what happens if a node exceeds the maximum number of keys?", - options: [ - "A) The node is deleted.", - "B) The tree is restructured.", - "C) The node is split into two nodes.", - "D) No action is taken.", - ], - answer: "C) The node is split into two nodes.", - }, - { - question: "6. What does it mean for a B-Tree to be balanced?", - options: [ - "A) All leaves are at the same depth.", - "B) The number of keys in each node is equal.", - "C) Each node contains the same number of children.", - "D) The tree is a complete binary tree.", - ], - answer: "A) All leaves are at the same depth.", - }, - { - question: "7. How is deletion handled in a B-Tree?", - options: [ - "A) Simply remove the key from the node.", - "B) Reorganize keys within the node only.", - "C) It may require borrowing a key from a sibling or merging nodes.", - "D) Deletion is not allowed in B-Trees.", - ], - answer: - "C) It may require borrowing a key from a sibling or merging nodes.", - }, - { - question: "8. Which of the following properties is NOT true for B-Trees?", - options: [ - "A) All leaf nodes are at the same level.", - "B) Each internal node has at least t-1 keys.", - "C) The root node can have fewer than t keys.", - "D) Every node can have an arbitrary number of children.", - ], - answer: "D) Every node can have an arbitrary number of children.", - }, - { - question: "9. In which applications are B-Trees commonly used?", - options: [ - "A) In-memory data structures.", - "B) File systems and databases.", - "C) Simple data retrieval tasks.", - "D) Small data storage.", - ], - answer: "B) File systems and databases.", - }, - { - question: - "10. What is the relationship between the height of a B-Tree and its order?", - options: [ - "A) The height increases as the order increases.", - "B) The height decreases as the order increases.", - "C) The height is independent of the order.", - "D) The height and order are always equal.", - ], - answer: "B) The height decreases as the order increases.", - }, - ]; - - const [currentQuestion, setCurrentQuestion] = useState(0); - const [score, setScore] = useState(0); - const [showResult, setShowResult] = useState(false); - const [selectedOption, setSelectedOption] = useState(null); - const [userAnswers, setUserAnswers] = useState([]); - - const handleAnswer = (selected: string) => { - setSelectedOption(selected); - setUserAnswers((prevAnswers) => [...prevAnswers, selected]); - if (selected === questions[currentQuestion].answer) { - setScore(score + 1); - } - }; - - const nextQuestion = () => { - if (currentQuestion < questions.length - 1) { - setCurrentQuestion(currentQuestion + 1); - setSelectedOption(null); // Reset selected option for the next question - } else { - setShowResult(true); - } - }; - - return ( - -
    -
    -

    Quiz on B-Trees

    - {showResult ? ( -
    -
    -

    - Your Score: {score} 🎉 -

    -

    - {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} -

    -
    - - {/* Solutions Section */} -
    -

    Solutions:

    - {questions.map((q, index) => ( -
    -

    {q.question}

    -

    - Your Answer: {userAnswers[index]} -

    -

    - Correct Answer: {q.answer} -

    -

    - Explanation: {q.explanation} -

    -
    - ))} -
    -
    - ) : ( -
    -

    - {questions[currentQuestion].question} -

    -
    - {questions[currentQuestion].options.map((option, index) => ( - - ))} -
    - -
    - )} -
    -
    -
    - ); -}; - -export default BTree; diff --git a/src/pages/quizes/binary-search-tree.tsx b/src/pages/quizes/binary-search-tree.tsx deleted file mode 100644 index ea9dfc62e..000000000 --- a/src/pages/quizes/binary-search-tree.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import React, { useState } from "react"; -import Layout from "@theme/Layout"; - -const BinarySearchTreeQuiz: React.FC = () => { - const questions = [ - { - question: "1. What is a binary search tree (BST)?", - options: [ - "A) A tree where each node has at most two children.", - "B) A tree where the left child is greater than the parent.", - "C) A tree where the left child is less than the parent and the right child is greater.", - "D) A tree where all nodes are on one side.", - ], - answer: "C) A tree where the left child is less than the parent and the right child is greater.", - explanation: "In a BST, each node's left child is less than the node, and the right child is greater, maintaining the sorted order.", - }, - { - question: "2. What is the time complexity for searching an element in a balanced binary search tree?", - options: ["A) O(n)", "B) O(log n)", "C) O(n log n)", "D) O(1)"], - answer: "B) O(log n)", - explanation: "In a balanced BST, the height of the tree is log(n), making search operations efficient at O(log n).", - }, - // Additional questions... - ]; - - const [currentQuestion, setCurrentQuestion] = useState(0); - const [score, setScore] = useState(0); - const [showResult, setShowResult] = useState(false); - const [selectedOption, setSelectedOption] = useState(null); - const [userAnswers, setUserAnswers] = useState([]); - - const handleAnswer = (selected: string) => { - setSelectedOption(selected); - setUserAnswers((prevAnswers) => [...prevAnswers, selected]); - - if (selected === questions[currentQuestion].answer) { - setScore(score + 1); - } - }; - - const nextQuestion = () => { - if (currentQuestion < questions.length - 1) { - setCurrentQuestion(currentQuestion + 1); - setSelectedOption(null); - } else { - setShowResult(true); - } - }; - - return ( - -
    -
    -

    Quiz on Binary Search Trees

    - {showResult ? ( -
    -
    -

    - Your Score: {score} 🎉 -

    -

    - {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} -

    -
    - - {/* Solutions Section */} -
    -

    Solutions:

    - {questions.map((q, index) => ( -
    -

    {q.question}

    -

    - Your Answer: {userAnswers[index]} -

    -

    - Correct Answer: {q.answer} -

    -

    - Explanation: {q.explanation} -

    -
    - ))} -
    -
    - ) : ( -
    -

    - {questions[currentQuestion].question} -

    -
    - {questions[currentQuestion].options.map((option, index) => ( - - ))} -
    - -
    - )} -
    -
    -
    - ); -}; - -export default BinarySearchTreeQuiz; diff --git a/src/pages/quizes/binary-tree.tsx b/src/pages/quizes/binary-tree.tsx deleted file mode 100644 index 56dc5102c..000000000 --- a/src/pages/quizes/binary-tree.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import React, { useState } from "react"; -import Layout from "@theme/Layout"; - -const BinaryTreeQuiz: React.FC = () => { - const questions = [ - // Easy Questions - { - question: "1. What is the height of a binary tree with a single node?", - options: ["A) 0", "B) 1", "C) 2", "D) Depends on the tree"], - answer: "B) 1", - }, - { - question: - "2. Which traversal of a binary tree visits nodes in the order: left, root, right?", - options: [ - "A) Pre-order", - "B) In-order", - "C) Post-order", - "D) Level-order", - ], - answer: "B) In-order", - }, - { - question: - "3. In a binary tree, what is the maximum number of nodes at depth 'd'?", - options: ["A) 2^d", "B) 2^(d+1) - 1", "C) 2d", "D) d^2"], - answer: "A) 2^d", - }, - // Average Questions - { - question: - "4. What is the time complexity of searching for an element in a balanced binary search tree?", - options: ["A) O(n)", "B) O(log n)", "C) O(n log n)", "D) O(1)"], - answer: "B) O(log n)", - }, - { - question: - "5. Which of the following statements is true about a binary search tree?", - options: [ - "A) The left subtree of a node contains only nodes with keys less than the node's key.", - "B) The right subtree of a node contains only nodes with keys greater than the node's key.", - "C) Both A and B.", - "D) None of the above.", - ], - answer: "C) Both A and B.", - }, - { - question: - "6. In a binary tree, which of the following properties is true for a complete binary tree?", - options: [ - "A) All levels are completely filled except possibly the last level.", - "B) All nodes are as far left as possible.", - "C) All leaves are at the same level.", - "D) A and B.", - ], - answer: "D) A and B.", - }, - // Difficult Questions - { - question: "7. What is the maximum depth of a binary tree with 'n' nodes?", - options: ["A) n", "B) log n", "C) n/2", "D) n - 1"], - answer: "A) n", - }, - { - question: - "8. Which of the following algorithms can be used to find the lowest common ancestor (LCA) in a binary tree?", - options: [ - "A) Recursive approach", - "B) Iterative approach", - "C) Both A and B", - "D) None of the above", - ], - answer: "C) Both A and B", - }, - { - question: - "9. Which of the following traversal methods would give the nodes of a binary tree in descending order?", - options: [ - "A) In-order traversal", - "B) Pre-order traversal", - "C) Post-order traversal", - "D) Reverse in-order traversal", - ], - answer: "D) Reverse in-order traversal", - }, - { - question: - "10. What is the worst-case time complexity for inserting an element in a binary search tree?", - options: ["A) O(log n)", "B) O(n)", "C) O(n log n)", "D) O(1)"], - answer: "B) O(n)", - }, - ]; - - const [currentQuestion, setCurrentQuestion] = useState(0); - const [score, setScore] = useState(0); - const [showResult, setShowResult] = useState(false); - const [selectedOption, setSelectedOption] = useState(null); - const [userAnswers, setUserAnswers] = useState([]); - - const handleAnswer = (selected: string) => { - setSelectedOption(selected); - setUserAnswers((prevAnswers) => [...prevAnswers, selected]); - if (selected === questions[currentQuestion].answer) { - setScore(score + 1); - } - }; - - const nextQuestion = () => { - if (currentQuestion < questions.length - 1) { - setCurrentQuestion(currentQuestion + 1); - setSelectedOption(null); - } else { - setShowResult(true); - } - }; - - return ( - -
    -
    -

    Quiz on Binary Tree

    - {showResult ? ( -
    -
    -

    - Your Score: {score} 🎉 -

    -

    - {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} -

    -
    - - {/* Solutions Section */} -
    -

    Solutions:

    - {questions.map((q, index) => ( -
    -

    {q.question}

    -

    - Your Answer: {userAnswers[index]} -

    -

    - Correct Answer: {q.answer} -

    -

    - Explanation: {q.explanation} -

    -
    - ))} -
    -
    - ) : ( -
    -

    - {questions[currentQuestion].question} -

    -
    - {questions[currentQuestion].options.map((option, index) => ( - - ))} -
    - -
    - )} -
    -
    -
    - ); -}; - -export default BinaryTreeQuiz; diff --git a/src/pages/quizes/index.tsx b/src/pages/quizes/index.tsx deleted file mode 100644 index dc22e2f8a..000000000 --- a/src/pages/quizes/index.tsx +++ /dev/null @@ -1,203 +0,0 @@ -import React from "react"; -import { LayoutGroup, motion } from "framer-motion"; -import { FaPlayCircle } from "react-icons/fa"; -import Layout from "@theme/Layout"; - -const Quizes: React.FC = () => { - return ( - -
    -
    - - Test Your Data Structures Skills - - - - Sharpen your data structures knowledge with quizzes from basic to advanced topics. - - -
    - {/* Array Quiz Card */} - -

    - Quiz on Arrays -

    -

    - Test your knowledge on array operations and algorithms. -

    - -
    - - {/* Stack Quiz Card */} - -

    - Quiz on Stacks -

    -

    - Evaluate your understanding of stack operations and applications. -

    - -
    - - {/* Queue Quiz Card */} - -

    - Quiz on Queues -

    -

    - Challenge your knowledge on queue implementations and their use cases. -

    - - -
    - - {/* Binary Tree Quiz Card */} - -

    - Quiz on Binary Trees -

    -

    - Test your understanding of Binary Tree structures and traversals. -

    - -
    - - {/* Binary Search Tree Quiz Card */} - -

    - Quiz on Binary Search Trees (BST) -

    -

    - Evaluate your knowledge of Binary Search Tree properties and operations. -

    - -
    - - {/* AVL Tree Quiz Card */} - -

    - Quiz on AVL Trees -

    -

    - Test your skills on the balancing properties of AVL Trees. -

    - -
    - - {/* Red-Black Tree Quiz Card */} - -

    - Quiz on Red-Black Trees -

    -

    - Challenge your understanding of the properties and algorithms of Red-Black Trees. -

    - -
    - - {/* B-Tree Quiz Card */} - -

    - Quiz on B-Trees -

    -

    - Test your understanding of B-Tree properties and their applications. -

    - -
    -
    -
    -
    -
    - ); -}; - -export default Quizes; - diff --git a/src/pages/quizes/queue.tsx b/src/pages/quizes/queue.tsx deleted file mode 100644 index af3fa1bcc..000000000 --- a/src/pages/quizes/queue.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import React, { useState } from "react"; -import Layout from "@theme/Layout"; - -const QueueQuiz: React.FC = () => { - const questions = [ - { - question: ( - <> - 1. Following is C like pseudo-code of a function that takes a Queue as an argument, and uses a stack S to do processing. -
    -            {`void fun(Queue *Q)
    -{
    -    Stack S;  // Say it creates an empty stack S
    -
    -    // Run while Q is not empty
    -    while (!isEmpty(Q))
    -    {
    -        // deQueue an item from Q and push the dequeued item to S
    -        push(&S, deQueue(Q));
    -    }
    -
    -    // Run while Stack S is not empty
    -    while (!isEmpty(&S))
    -    {
    -      // Pop an item from S and enqueue the popped item to Q
    -      enQueue(Q, pop(&S));
    -    }
    -}`}
    -          
    - - ), - options: [ - "A) Removes the last from Q", - "B) Keeps the Q same as it was before the call", - "C) Makes Q empty", - "D) Reverses the Q" - ], - answer: "D) Reverses the Q", - }, - { - question: "2. How many stacks are needed to implement a queue? Consider the situation where no other data structure like arrays, linked list is available to you.", - options: ["A) 1", "B) 2", "C) 3", "D) 4"], - answer: "B) 2", - }, - { - question: "3. Which of the following operations on a queue data structure has a time complexity of O(1)?", - options: ["A) Enqueue", "B) Dequeue", "C) Peek", "D) Clear"], - answer: "A and B", - }, - { - question: "4. A priority queue can be efficiently implemented using which of the following data structures?", - options: ["A) Array", "B) Linked List", "C) Heap Data Structures like Binary Heap, Fibonacci Heap", "D) None of the above"], - answer: "C) Heap Data Structures like Binary Heap, Fibonacci Heap", - }, - { - question: "5. Which of the following is true about linked list implementation of a queue?", - options: [ - "A) In push operation, if new nodes are inserted at the beginning of linked list, then in pop operation, nodes must be removed from end.", - "B) In push operation, if new nodes are inserted at the end, then in pop operation, nodes must be removed from the beginning.", - "C) Both of the above", - "D) None of the above" - ], - answer: "C) Both of the above", - }, - { - question: "6. A Priority-Queue is implemented as a Max-Heap. Initially, it has 5 elements. The level-order traversal of the heap is given below: 10, 8, 5, 3, 2. Two new elements '1' and '7' are inserted in the heap in that order. The level-order traversal of the heap after the insertion of the elements is:", - options: [ - "A) 10, 8, 7, 5, 3, 2, 1", - "B) 10, 8, 7, 2, 3, 1, 5", - "C) 10, 8, 7, 1, 2, 3, 5", - "D) 10, 8, 7, 3, 2, 1, 5" - ], - answer: "A) 10, 8, 7, 5, 3, 2, 1", - }, - { - question: ( - <> - 7. An implementation of a queue Q, using two stacks S1 and S2, is given below: -
    -            {`void insert(Q, x) {
    -   push(S1, x);
    -}
    - 
    -void delete(Q){
    -   if(stack-empty(S2)) then 
    -      if(stack-empty(S1)) then {
    -          print(“Q is empty”);
    -          return;
    -      }
    -      else while (!(stack-empty(S1))){
    -          x=pop(S1);
    -          push(S2,x);
    -      }
    -   x=pop(S2);
    -}`}
    -          
    - - ), - options: [ - "A) n+m <= x < 2n and 2m <= y <= n+m", - "B) n+m <= x < 2n and 2m <= y <= 2n", - "C) 2m <= x < 2n and 2m <= y <= n+m", - "D) 2m <= x < 2n and 2m <= y <= 2n" - ], - answer: "A) n+m <= x < 2n and 2m <= y <= n+m", - }, - { - question: ( - <> - 8. Consider the following operation along with Enqueue and Dequeue operations on queues, where k is a global parameter. -
    -            {`MultiDequeue(Q){
    -   m = k
    -   while (Q is not empty and m  > 0) {
    -      Dequeue(Q)
    -      m = m - 1
    -   }
    -}`}
    -          
    - What is the worst-case time complexity of a sequence of n MultiDequeue() operations on an initially empty queue? - - ), - options: [ - "A) Θ(n)", - "B) Θ(n + k)", - "C) Θ(nk)", - "D) Θ(n²)" - ], - answer: "B) Θ(n + k)", - }, - { - question: ( - <> - 9. Consider the following pseudo code. Assume that IntQueue is an integer queue. What does the function fun do? -
    -            {`fun(int n)
    -{
    -   IntQueue q = new IntQueue();
    -   q.enqueue(0);
    -   q.enqueue(1);
    -   for (int i = 0; i < n; i++)
    -   {
    -      int a = q.dequeue();
    -      int b = q.dequeue();
    -      q.enqueue(b);
    -      q.enqueue(a + b);
    -      print(a);
    -   }
    -}`}
    -          
    - - ), - options: [ - "A) Prints numbers from 0 to n-1", - "B) Prints numbers from n-1 to 0", - "C) Prints first n Fibonacci numbers", - "D) Prints first n Fibonacci numbers in reverse order" - ], - answer: "C) Prints first n Fibonacci numbers", - }, - { - question: "10. Which of the following is NOT a common operation in a queue data structure?", - options: ["A) Enqueue", "B) Dequeue", "C) Peek", "D) Shuffle"], - answer: "D) Shuffle", - }, - ]; - - const [currentQuestion, setCurrentQuestion] = useState(0); - const [score, setScore] = useState(0); - const [showResult, setShowResult] = useState(false); - const [selectedOption, setSelectedOption] = useState(null); - - const handleAnswer = (selected: string) => { - setSelectedOption(selected); - if (selected === questions[currentQuestion].answer) { - setScore(score + 1); - } - }; - - const nextQuestion = () => { - if (currentQuestion < questions.length - 1) { - setCurrentQuestion(currentQuestion + 1); - setSelectedOption(null); // Reset selected option for the next question - } else { - setShowResult(true); - } - }; - - return ( - -
    -

    Quiz on Queues

    - {showResult ? ( -
    -

    Your Score: {score} 🎉

    -

    - {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} -

    -
    - ) : ( -
    -

    {questions[currentQuestion].question}

    -
    - {questions[currentQuestion].options.map((option, index) => ( -
    - handleAnswer(option)} - /> - -
    - ))} -
    - -
    - )} -
    -
    - ); -}; - -export default QueueQuiz; diff --git a/src/pages/quizes/queues.tsx b/src/pages/quizes/queues.tsx deleted file mode 100644 index 34cb89d8a..000000000 --- a/src/pages/quizes/queues.tsx +++ /dev/null @@ -1,207 +0,0 @@ -import React, { useState } from "react"; -import Layout from "@theme/Layout"; - -const QueueQuiz: React.FC = () => { - const questions = [ - // Easy Questions - { - question: "1. What will happen if you try to dequeue an item from an empty queue?", - options: ["A) Returns null", "B) Throws an error", "C) Returns undefined", "D) No operation"], - answer: "B) Throws an error", - }, - { - question: "2. In a circular queue, what is the primary benefit compared to a linear queue?", - options: ["A) More memory usage", "B) Faster access time", "C) Efficient use of space", "D) Simpler implementation"], - answer: "C) Efficient use of space", - }, - { - question: ( - <> - 3. Consider the following operations on a queue: -
    -            {`enqueue(1);
    -enqueue(2);
    -enqueue(3);
    -dequeue();
    -enqueue(4);
    -dequeue();`}
    -          
    - What will be the output of the dequeue operations? - - ), - options: ["A) 1, 2", "B) 1, 3", "C) 2, 4", "D) 3, 4"], - answer: "A) 1, 2", - }, - // Average Questions - { - question: "4. Which data structure is commonly used to implement a queue?", - options: ["A) Array", "B) Linked List", "C) Stack", "D) Both A and B"], - answer: "D) Both A and B", - }, - { - question: "5. What is the time complexity of enqueue and dequeue operations in a linked list-based queue?", - options: ["A) O(1)", "B) O(n)", "C) O(log n)", "D) O(n^2)"], - answer: "A) O(1)", - }, - { - question: "6. In a queue, which operation is used to remove an element from the front?", - options: ["A) push", "B) pop", "C) enqueue", "D) dequeue"], - answer: "D) dequeue", - }, - { - question: ( - <> - 7. Given the following pseudocode for a queue operation: -
    -            {`if (front == -1) {
    -    front = 0;
    -}
    -rear++;
    -queue[rear] = value;`}
    -          
    - What does this pseudocode represent? - - ), - options: [ - "A) Enqueue operation", - "B) Dequeue operation", - "C) Peek operation", - "D) IsEmpty operation", - ], - answer: "A) Enqueue operation", - }, - // Difficult QuestionsclassName="options" - { - question: "8. Which of the following is not a type of queue?", - options: ["A) Simple Queue", "B) Circular Queue", "C) Double-ended Queue", "D) Random Queue"], - answer: "D) Random Queue", - }, - { - question: ( - <> - 9. In a priority queue, elements are dequeued based on: -
    -            {`1. Their position in the queue
    -2. Their priority level`}
    -          
    - Which statement is correct? - - ), - options: [ - "A) Only by position", - "B) Only by priority level", - "C) Both position and priority level", - "D) Neither", - ], - answer: "B) Only by priority level", - }, - { - question: ( - <> - 10. What will be the output of the following queue operations if the initial queue is empty? -
    -            {`enqueue(10);
    -enqueue(20);
    -dequeue();
    -enqueue(30);`}
    -          
    - What will be the current front of the queue? - - ), - options: ["A) 10", "B) 20", "C) 30", "D) Queue is empty"], - answer: "C) 30", - }, - ]; - - const [currentQuestion, setCurrentQuestion] = useState(0); - const [score, setScore] = useState(0); - const [showResult, setShowResult] = useState(false); - const [selectedOption, setSelectedOption] = useState(null); - const [userAnswers, setUserAnswers] = useState([]); - - const handleAnswer = (selected: string) => { - setSelectedOption(selected); - setUserAnswers((prevAnswers) => [...prevAnswers, selected]); - if (selected === questions[currentQuestion].answer) { - setScore(score + 1); - } - }; - - const nextQuestion = () => { - if (currentQuestion < questions.length - 1) { - setCurrentQuestion(currentQuestion + 1); - setSelectedOption(null); // Reset selected option for the next question - } else { - setShowResult(true); - } - }; - - return ( - -
    -
    -

    Quiz on Queues

    - {showResult ? ( -
    -
    -

    - Your Score: {score} 🎉 -

    -

    - {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} -

    -
    - - {/* Solutions Section */} -
    -

    Solutions:

    - {questions.map((q, index) => ( -
    -

    {q.question}

    -

    - Your Answer: {userAnswers[index]} -

    -

    - Correct Answer: {q.answer} -

    -

    - Explanation: {q.explanation} -

    -
    - ))} -
    -
    - ) : ( -
    -

    - {questions[currentQuestion].question} -

    -
    - {questions[currentQuestion].options.map((option, index) => ( - - ))} -
    - -
    - )} -
    -
    -
    - ); -}; - -export default QueueQuiz; diff --git a/src/pages/quizes/red-black-tree.tsx b/src/pages/quizes/red-black-tree.tsx deleted file mode 100644 index 5714a52b1..000000000 --- a/src/pages/quizes/red-black-tree.tsx +++ /dev/null @@ -1,242 +0,0 @@ -import React, { useState } from "react"; -import Layout from "@theme/Layout"; - -const RedBlackTreeQuiz: React.FC = () => { - const questions = [ - // Easy Questions - { - question: ( - <> - 1. What is a Red-Black Tree? - - ), - options: [ - "A) A binary search tree with additional color properties.", - "B) A tree that only allows red nodes.", - "C) A tree where all nodes are black.", - "D) A tree with no duplicate values.", - ], - answer: "A) A binary search tree with additional color properties.", - }, - { - question: ( - <> - 2. What are the two colors used in a Red-Black Tree? - - ), - options: [ - "A) Red and Blue", - "B) Black and White", - "C) Red and Black", - "D) Green and Yellow", - ], - answer: "C) Red and Black", - }, - { - question: ( - <> - 3. What is the maximum height of a Red-Black Tree with n nodes? - - ), - options: [ - "A) O(n)", - "B) O(log n)", - "C) O(2 log n)", - "D) O(sqrt(n))", - ], - answer: "B) O(log n)", - }, - // Average Questions - { - question: ( - <> - 4. Which of the following properties must be true for a Red-Black Tree? - - ), - options: [ - "A) The root must be red.", - "B) Red nodes cannot have red children.", - "C) All leaves are red.", - "D) Every path from a node to its leaves must have the same number of red nodes.", - ], - answer: "B) Red nodes cannot have red children.", - }, - { - question: ( - <> - 5. What is the role of rotations in Red-Black Trees? - - ), - options: [ - "A) To delete nodes.", - "B) To maintain the balance of the tree.", - "C) To insert nodes.", - "D) To traverse the tree.", - ], - answer: "B) To maintain the balance of the tree.", - }, - { - question: ( - <> - 6. When a new node is inserted into a Red-Black Tree, what color is it initially? - - ), - options: [ - "A) Red", - "B) Black", - "C) Blue", - "D) Green", - ], - answer: "A) Red", - }, - // Difficult Questions - { - question: ( - <> - 7. In a Red-Black Tree, how do you ensure that the tree remains balanced after an insertion? - - ), - options: [ - "A) By performing rotations and recoloring nodes.", - "B) By deleting the inserted node.", - "C) By adjusting the tree's height.", - "D) By increasing the tree's depth.", - ], - answer: "A) By performing rotations and recoloring nodes.", - }, - { - question: ( - <> - 8. Which of the following scenarios requires a right rotation in a Red-Black Tree? - - ), - options: [ - "A) Inserting a red node in the left subtree of a left child.", - "B) Inserting a red node in the right subtree of a right child.", - "C) Inserting a red node in the right subtree of a left child.", - "D) Inserting a black node.", - ], - answer: "A) Inserting a red node in the left subtree of a left child.", - }, - { - question: ( - <> - 9. What happens if a Red-Black Tree property is violated during an insertion? - - ), - options: [ - "A) The tree is deleted.", - "B) The tree is rebalanced.", - "C) The insertion is aborted.", - "D) No action is taken.", - ], - answer: "B) The tree is rebalanced.", - }, - { - question: ( - <> - 10. What is the primary advantage of using a Red-Black Tree over a regular Binary Search Tree? - - ), - options: [ - "A) It requires less memory.", - "B) It guarantees O(log n) time complexity for insertions, deletions, and searches.", - "C) It can store duplicate values.", - "D) It allows for faster traversals.", - ], - answer: "B) It guarantees O(log n) time complexity for insertions, deletions, and searches.", - }, - ]; - - const [currentQuestion, setCurrentQuestion] = useState(0); - const [score, setScore] = useState(0); - const [showResult, setShowResult] = useState(false); - const [selectedOption, setSelectedOption] = useState(null); - const [userAnswers, setUserAnswers] = useState([]); - - const handleAnswer = (selected: string) => { - setSelectedOption(selected); - setUserAnswers((prevAnswers) => [...prevAnswers, selected]); - if (selected === questions[currentQuestion].answer) { - setScore(score + 1); - } - }; - - const nextQuestion = () => { - if (currentQuestion < questions.length - 1) { - setCurrentQuestion(currentQuestion + 1); - setSelectedOption(null); // Reset selected option for the next question - } else { - setShowResult(true); - } - }; - - return ( - -
    -
    -

    Quiz on Red-Black Trees

    - {showResult ? ( -
    -
    -

    - Your Score: {score} 🎉 -

    -

    - {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} -

    -
    - - {/* Solutions Section */} -
    -

    Solutions:

    - {questions.map((q, index) => ( -
    -

    {q.question}

    -

    - Your Answer: {userAnswers[index]} -

    -

    - Correct Answer: {q.answer} -

    -

    - Explanation: {q.explanation} -

    -
    - ))} -
    -
    - ) : ( -
    -

    - {questions[currentQuestion].question} -

    -
    - {questions[currentQuestion].options.map((option, index) => ( - - ))} -
    - -
    - )} -
    -
    -
    - ); -}; - -export default RedBlackTreeQuiz; diff --git a/src/pages/quizes/stack.tsx b/src/pages/quizes/stack.tsx deleted file mode 100644 index 415a3f441..000000000 --- a/src/pages/quizes/stack.tsx +++ /dev/null @@ -1,291 +0,0 @@ -import React, { useState } from "react"; -import Layout from "@theme/Layout"; - -const StackQuiz: React.FC = () => { - const questions = [ - // Easy Questions - { - question: ( - <> - Following is C like pseudo code of a function that takes a number as an argument, and uses a stack S to do processing. -
    -            {`void fun(int n)
    -{
    -    Stack S;  // Say it creates an empty stack S
    -    while (n > 0)
    -    {
    -      push(&S, n%2);
    -      n = n/2;
    -    }
    -
    -    while (!isEmpty(&S))
    -      printf("%d ", pop(&S));
    -}`}
    -          
    - What does the above function do in general? - - ), - options: [ - "A) Prints binary representation of n in reverse order", - "B) Prints binary representation of n", - "C) Prints the value of Logn", - "D) Prints the value of Logn in reverse order", - ], - answer: "A) Prints binary representation of n in reverse order", - }, - { - question: ( - <> - Consider the following pseudocode that uses a stack: -
    -            {`declare a stack of characters
    -while (there are more characters in the word to read)
    -{
    -    read a character
    -    push the character on the stack
    -}
    -while (the stack is not empty)
    -{
    -    pop a character off the stack
    -    write the character to the screen
    -}`}
    -          
    - What is output for input "geeksquiz"? - - ), - options: [ - "A) geeksquizgeeksquiz", - "B) ziuqskeeg", - "C) geeksquiz", - "D) ziuqskeegziuqskeeg", - ], - answer: "B) ziuqskeeg", - }, - { - question: ( - <> - Following is an incorrect pseudocode for the algorithm which is supposed to determine whether a sequence of parentheses is balanced: -
    -            {`declare a character stack 
    -while (more input is available)
    -{
    -    read a character
    -    if (the character is a '(' ) 
    -        push it on the stack
    -    else if (the character is a ')' and the stack is not empty)
    -        pop a character off the stack
    -    else
    -        print "unbalanced" and exit
    -}
    -print "balanced"`}
    -          
    - Which of these unbalanced sequences does the above code think is balanced? - - ), - options: [ - "A) ((())", - "B) ())(()", - "C) (()())", - "D) (()))()", - ], - answer: "D) (()))()", - }, - // Average Questions - { - question: ( - <> - The following postfix expression with single digit operands is evaluated using a stack: -
    -            {`8 2 3 ^ / 2 3 * + 5 1 * -`}
    -          
    - The top two elements of the stack after the first * is evaluated are: - - ), - options: [ - "A) 6, 1", - "B) 5, 7", - "C) 3, 2", - "D) 1, 5", - ], - answer: "A) 6, 1", - }, - { - question: ( - <> - A single array A[1..MAXSIZE] is used to implement two stacks. The two stacks grow from opposite ends of the array. If the space is to be used efficiently, the condition for “stack full” is: - - ), - options: [ - "A) (top1 = MAXSIZE/2) and (top2 = MAXSIZE/2+1)", - "B) top1 + top2 + 1 = MAXSIZE", - "C) (top1= MAXSIZE/2) or (top2 = MAXSIZE)", - "D) top1= top2 -1", - ], - answer: "B) top1 + top2 + 1 = MAXSIZE", - }, - { - question: ( - <> - Assume that the operators +, -, × are left associative and ^ is right associative. The order of precedence (from highest to lowest) is ^, x , +, -. The postfix expression corresponding to the infix expression a + b × c - d ^ e ^ f is - - ), - options: [ - "A) abc × + def ^ ^ -", - "B) abc × + de ^ f ^ -", - "C) ab + c × d - e ^ f ^", - "D) - + a × bc ^ ^ def", - ], - answer: "A) abc × + def ^ ^ -", - }, - // Difficult Questions - { - question: ( - <> - The result evaluating the postfix expression 10 5 + 60 6 / * 8 – is - - ), - options: [ - "A) 284", - "B) 213", - "C) 142", - "D) 71", - ], - answer: "C) 142", // Removed answer - }, - { - question: ( - <> - A function f defined on stacks of integers satisfies the following properties. f(∅) = 0 and f(push(S, i)) = max(f(S), 0) + i for all stacks S and integers i. - If a stack S contains the integers 2, -3, 2, -1, 2 in order from bottom to top, what is f(S)? - - ), - options: [ - "A) 6", - "B) 4", - "C) 3", - "D) 2", - ], - answer: "A) 6", - }, - { - question: ( - <> - A priority queue Q is used to implement a stack S that stores characters. PUSH(C) is implemented as INSERT(Q, C, K) where K is an appropriate integer key chosen by the implementation. For a sequence of operations, the keys chosen are in - - ), - options: [ - "A) Non-increasing order", - "B) Non-decreasing order", - "C) strictly increasing order", - "D) strictly decreasing order", - ], - answer: "C) strictly increasing order", - }, - { - question: ( - <> - If the sequence of operations - push (1), push (2), pop, push (1), push (2), pop, pop, pop, push (2), pop are performed on a stack, the sequence of popped out values - - ), - options: [ - "A) 2,2,1,1,2", - "B) 2,2,1,2,2", - "C) 2,1,2,2,1", - "D) 2,1,2,2,2", - ], - answer: "C) 2,1,2,2,1", - }, - ]; - - const [currentQuestion, setCurrentQuestion] = useState(0); - const [score, setScore] = useState(0); - const [showResult, setShowResult] = useState(false); - const [selectedOption, setSelectedOption] = useState(null); - const [userAnswers, setUserAnswers] = useState([]); - - const handleAnswer = (selected: string) => { - setSelectedOption(selected); - setUserAnswers((prevAnswers) => [...prevAnswers, selected]); - if (selected === questions[currentQuestion].answer) { - setScore(score + 1); - } - }; - - const nextQuestion = () => { - if (currentQuestion < questions.length - 1) { - setCurrentQuestion(currentQuestion + 1); - setSelectedOption(null); // Reset selected option for the next question - } else { - setShowResult(true); - } - }; - - return ( - -
    -
    -

    Quiz on Stack

    - {showResult ? ( -
    -
    -

    - Your Score: {score} 🎉 -

    -

    - {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} -

    -
    - - {/* Solutions Section */} -
    -

    Solutions:

    - {questions.map((q, index) => ( -
    -

    {q.question}

    -

    - Your Answer: {userAnswers[index]} -

    -

    - Correct Answer: {q.answer} -

    -

    - Explanation: {q.explanation} -

    -
    - ))} -
    -
    - ) : ( -
    -

    - {questions[currentQuestion].question} -

    -
    - {questions[currentQuestion].options.map((option, index) => ( - - ))} -
    - -
    - )} -
    -
    -
    - ); -}; - -export default StackQuiz; diff --git a/src/pages/resources/index.tsx b/src/pages/resources/index.tsx deleted file mode 100644 index 6c7931a77..000000000 --- a/src/pages/resources/index.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React from "react"; -import Layout from "@theme/Layout"; -import { motion } from "framer-motion"; - -const resources = [ - { id: 1, title: "Introduction to Algorithms by CLRS", type: "Book", description: "One of the most comprehensive algorithm books.", link: "https://drive.google.com/file/d/0B3RHrbxFb7PfYjk4ZG01Z3lrbnc/view?resourcekey=0-aHyhqxUeXCNvRK3_QfNurg" }, - { id: 2, title: "LeetCode", type: "Website", description: "A platform for practicing algorithms with real problems.", link: "https://leetcode.com" }, - { id: 3, title: "Coursera: Algorithmic Toolbox", type: "Course", description: "An introductory course for algorithms.", link: "https://www.coursera.org/learn/algorithms-part1" }, - // Add more resources -]; - -const Resources: React.FC = () => { - return ( - -
    - -
    - - ); -}; - -export default Resources; diff --git a/src/pages/roadmap/index.tsx b/src/pages/roadmap/index.tsx deleted file mode 100644 index 27e2beea5..000000000 --- a/src/pages/roadmap/index.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import React from "react"; -import { motion } from "framer-motion"; -import Layout from "@theme/Layout"; - -interface Milestone { - title: string; - description: string; - status: "planned" | "in-progress" | "completed"; -} - -const milestones: Milestone[] = [ - { - title: "AI and Machine Learning Algorithms", - description: - "Integrate AI and machine learning algorithms to enhance the learning experience and provide advanced problem-solving tools.", - status: "planned", - }, - { - title: "Performance Benchmarking", - description: - "Implement performance benchmarking tools to compare different algorithm implementations across various metrics.", - status: "in-progress", - }, - { - title: "Support for Additional Languages", - description: - "Expand support for more programming languages such as Go, Rust, and Kotlin to cater to a broader developer audience.", - status: "planned", - }, - { - title: "Interactive Visualizations", - description: - "Develop interactive visualizations for algorithm performance and execution flow to aid in deeper understanding.", - status: "planned", - }, - { - title: "Mobile Application", - description: - "Launch a mobile application version of Algo to provide on-the-go access to tutorials, algorithms, and contributions.", - status: "completed", - }, -]; - -const Roadmap: React.FC = () => { - const getStatusColor = (status: string) => { - switch (status) { - case "completed": - return "text-green-500"; - case "in-progress": - return "text-yellow-500"; - case "planned": - return "text-blue-500"; - default: - return "text-gray-500"; - } - }; - - return ( - -
    - {/* Header Section */} -
    - - Our Roadmap - - - Discover the future plans and upcoming features for Algo. - -
    - - {/* Roadmap Items */} -
    - - {milestones.map((milestone, index) => ( - -
    - - • - -
    -
    -

    {milestone.title}

    -

    {milestone.description}

    - - {milestone.status.replace("-", " ")} - -
    -
    - ))} -
    -
    -
    -
    - ); -}; - -export default Roadmap; diff --git a/src/pages/terms/index.tsx b/src/pages/terms/index.tsx deleted file mode 100644 index 0dc86446b..000000000 --- a/src/pages/terms/index.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import React from "react"; -import Layout from "@theme/Layout"; -import { motion } from "framer-motion"; - -const TermsAndConditions: React.FC = () => { - return ( - -
    -
    - - Terms and Conditions - - - Please read these terms and conditions carefully before using our platform. - -
    - -
    - -
    -

    - Acceptance of Terms -

    -

    - By accessing or using our platform, you agree to be bound by these terms and conditions. If you do not agree - with any part of the terms, you must not use the platform. Continued use of the platform following any updates - to these terms will be deemed your acceptance of those changes. -

    -
    - -
    -

    - User Obligations -

    -

    - As a user, you are responsible for maintaining the confidentiality of your account information, including your - password, and for all activities that occur under your account. You agree not to use the platform for any unlawful - purpose or in violation of any applicable laws or regulations. You also agree not to interfere with the security - or performance of the platform or attempt to access unauthorized features. -

    -

    - You further agree that you will not: -

    -
      -
    • Submit false or misleading information.
    • -
    • Use the platform to infringe upon any intellectual property or other rights of third parties.
    • -
    • Engage in any activity that disrupts or interferes with the platform’s functionality.
    • -
    • Distribute viruses or any other harmful technologies.
    • -
    -
    - -
    -

    - Intellectual Property -

    -

    - All content on this platform, including but not limited to text, graphics, logos, icons, and images, is the property - of the platform or its content suppliers and is protected by copyright, trademark, and other intellectual property - laws. You agree not to reproduce, duplicate, copy, sell, or exploit any portion of the platform’s content without - express permission from the owner. -

    -
    - -
    -

    - Disclaimer of Warranties -

    -

    - The platform is provided on an "as-is" and "as-available" basis without any warranties of any kind, either express - or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose, - or non-infringement. We do not guarantee that the platform will be error-free or uninterrupted, nor do we make any - warranties about the results that may be obtained from using the platform. -

    -
    - -
    -

    - Limitation of Liability -

    -

    - In no event will we be liable for any direct, indirect, incidental, consequential, or punitive damages arising out of - or related to your use of the platform, even if we have been advised of the possibility of such damages. You agree - that your sole remedy for dissatisfaction with the platform is to discontinue its use. -

    -
    - -
    -

    - Governing Law and Jurisdiction -

    -

    - These terms and conditions are governed by and construed in accordance with the laws of [Your Jurisdiction]. You - agree to submit to the exclusive jurisdiction of the courts located in [Your Jurisdiction] for any disputes arising - out of or relating to your use of the platform. -

    -
    - -
    -

    - Termination -

    -

    - We reserve the right to terminate or suspend your access to the platform at any time, without notice, for conduct - that we believe violates these terms, is harmful to other users, or is illegal. Upon termination, your right to - use the platform will cease immediately. -

    -
    - -
    -

    - Changes to Terms and Conditions -

    -

    - We reserve the right to modify these terms at any time. Any changes will be effective immediately upon posting. It is - your responsibility to review these terms regularly. Continued use of the platform after changes are posted constitutes - your acceptance of the modified terms. -

    -
    - - -
    -
    -
    -
    - ); -}; - -export default TermsAndConditions; diff --git a/src/theme/Admonition/Icon/Danger.js b/src/theme/Admonition/Icon/Danger.js deleted file mode 100644 index 860625339..000000000 --- a/src/theme/Admonition/Icon/Danger.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import Danger from '@theme-original/Admonition/Icon/Danger'; - -export default function DangerWrapper(props) { - return ( - <> - - - ); -} diff --git a/src/theme/Admonition/Layout/index.js b/src/theme/Admonition/Layout/index.js deleted file mode 100644 index 161683d47..000000000 --- a/src/theme/Admonition/Layout/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import Layout from '@theme-original/Admonition/Layout'; - -export default function LayoutWrapper(props) { - return ( - <> - - - ); -} diff --git a/src/theme/CodeBlock/Line/index.js b/src/theme/CodeBlock/Line/index.js deleted file mode 100644 index f36761806..000000000 --- a/src/theme/CodeBlock/Line/index.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import clsx from 'clsx'; -import styles from './styles.module.css'; -export default function CodeBlockLine({ - line, - classNames, - showLineNumbers, - getLineProps, - getTokenProps, -}) { - if (line.length === 1 && line[0].content === '\n') { - line[0].content = ''; - } - const lineProps = getLineProps({ - line, - className: clsx(classNames, showLineNumbers && styles.codeLine), - }); - const lineTokens = line.map((token, key) => ( - - )); - return ( - - {showLineNumbers ? ( - <> - - {lineTokens} - - ) : ( - lineTokens - )} -
    -
    - ); -} diff --git a/src/theme/CodeBlock/Line/styles.module.css b/src/theme/CodeBlock/Line/styles.module.css deleted file mode 100644 index 7c28ed9aa..000000000 --- a/src/theme/CodeBlock/Line/styles.module.css +++ /dev/null @@ -1,45 +0,0 @@ -/* Intentionally has zero specificity, so that to be able to override -the background in custom CSS file due bug https://github.com/facebook/docusaurus/issues/3678 */ -:where(:root) { - --docusaurus-highlighted-code-line-bg: rgb(72 77 91); -} - -:where([data-theme='dark']) { - --docusaurus-highlighted-code-line-bg: rgb(100 100 100); -} - -:global(.theme-code-block-highlighted-line) { - background-color: var(--docusaurus-highlighted-code-line-bg); - display: block; - margin: 0 calc(-1 * var(--ifm-pre-padding)); - padding: 0 var(--ifm-pre-padding); -} - -.codeLine { - display: table-row; - counter-increment: line-count; -} - -.codeLineNumber { - display: table-cell; - text-align: right; - width: 1%; - position: sticky; - left: 0; - padding: 0 var(--ifm-pre-padding); - background: var(--ifm-pre-background); - overflow-wrap: normal; -} - -.codeLineNumber::before { - content: counter(line-count); - opacity: 0.4; -} - -:global(.theme-code-block-highlighted-line) .codeLineNumber::before { - opacity: 0.8; -} - -.codeLineContent { - padding-right: var(--ifm-pre-padding); -} diff --git a/src/theme/Footer/index.tsx b/src/theme/Footer/index.tsx deleted file mode 100644 index d5c2f6f7e..000000000 --- a/src/theme/Footer/index.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import React, { useEffect } from "react"; -import { FaGithub, FaLinkedin, FaDiscord, FaTwitter } from "react-icons/fa"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faTwitter } from "@fortawesome/free-brands-svg-icons"; - -import Link from "@docusaurus/Link"; - -const Footer = () => { - useEffect(() => { - // Create script element for GTranslate - const script = document.createElement("script"); - script.src = "https://cdn.gtranslate.net/widgets/latest/popup.js"; - script.defer = true; - document.body.appendChild(script); - - // Set GTranslate settings - window.gtranslateSettings = { - default_language: "en", - detect_browser_language: true, - wrapper_selector: ".gtranslate_wrapper", - }; - - // Cleanup script on component unmount - return () => { - document.body.removeChild(script); - }; - }, []); - - return ( -
    -
    -
    -
    -
    - - Algo Logo - - - Algo - - - -
    - {/*

    Algo

    */} -

    - A platform to learn and practice DSA with a collection of - algorithms and data structures in various languages. -

    -
    -
    - {/* Social Media Links */} -
    - - - - - - - - - - - - - - -
    -
    - - {/* Resources */} -
    -

    Resources

    -
      -
    • - - Documentation - -
    • -
    • - - Blog - -
    • -
    • - - Tutorials - -
    • -
    -
    - - {/* Community */} -
    -

    Community

    -
      -
    • - - Join Discord - -
    • -
    • - - Contributors - -
    • -
    • - - Events - -
    • -
    -
    -
    - - {/* Bottom Section */} -
    -
      -
    • - - Features - -
    • -
    • - - About Us - -
    • -
    • - - Contact - -
    • -
    • - - Privacy Policy - -
    • -
    • -
      -
    • -
    -

    - © {new Date().getFullYear()} Algo, Inc. Built with Docusaurus. -

    -
    -
    -
    - ); -}; - -export default Footer; diff --git a/src/theme/MDXComponents.js b/src/theme/MDXComponents.js deleted file mode 100644 index 6c255b0e0..000000000 --- a/src/theme/MDXComponents.js +++ /dev/null @@ -1,44 +0,0 @@ -import "react-lite-youtube-embed/dist/LiteYouTubeEmbed.css"; -import AdsComponent from "@site/src/components/AdsComponent"; -// import BrowserWindow from "@site/src/components/BrowserWindow"; -import ArrayVisualizations from "@site/src/components/DSA/arrays/ArrayVisualizations"; -import BubbleSortVisualization from "@site/src/components/DSA/arrays/BubbleSortVisualization"; -import InsertionSortVisualization from "@site/src/components/DSA/arrays/InsertionSortVisualization"; -import QuickSortVisualization from "@site/src/components/DSA/arrays/QuickSortVisualization"; -import HeapSortVisualization from "@site/src/components/DSA/arrays/HeapSortVisualization"; -import SelectionSortVisualization from "@site/src/components/DSA/arrays/SelectionSortVisualization"; -import DijkstraVisuzalizations from "@site/src/components/DSA/graphs/DijkstraVisualizations"; -import FloydWarshallVisualizations from "@site/src/components/DSA/graphs/FloydWarshallVisualizations"; -import Highlight from "@site/src/components/Highlight"; -import MDXComponents from "@theme-original/MDXComponents"; -// import Image from "@theme/IdealImage"; -import TabItem from "@theme/TabItem"; -import Tabs from "@theme/Tabs"; -import { FaReact } from "react-icons/fa"; -import LiteYouTubeEmbed from "react-lite-youtube-embed"; -import GiscusComponent from "../components/GiscusComponent"; -import Ads from "@site/src/components/AdsComponent/Ads"; - -export default { - // Re-use the default mapping - ...MDXComponents, - // custom - Tabs, - TabItem, - Highlight, - ArrayVisualizations, - BubbleSortVisualization, - SelectionSortVisualization, - FaReact, - DijkstraVisuzalizations, - FloydWarshallVisualizations, - InsertionSortVisualization, - QuickSortVisualization, - HeapSortVisualization, -// Image, - LiteYouTubeEmbed, -// LinearSearchVisualizer, - AdsComponent, - GiscusComponent, - Ads, -}; diff --git a/src/theme/Mermaid/index.js b/src/theme/Mermaid/index.js deleted file mode 100644 index 543e3848c..000000000 --- a/src/theme/Mermaid/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import Mermaid from '@theme-original/Mermaid'; - -export default function MermaidWrapper(props) { - return ( - <> - - - ); -} diff --git a/src/theme/ReactLiveScope/components.js b/src/theme/ReactLiveScope/components.js deleted file mode 100644 index 98c4bb374..000000000 --- a/src/theme/ReactLiveScope/components.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; - -export const ButtonExample = (props) => ( - + + + + +``` +What happens here? +HTML: Provides the structure (a heading and a button). +JavaScript: Adds interactivity. When the button is clicked, the heading's text is changed to "Hello, JavaScript!". + + + +## 4. Where is JavaScript Used? +JavaScript is everywhere! From simple web pages to complex applications, here are some areas where it's commonly used: + +4.1. Front-End Web Development +JavaScript brings static HTML pages to life by enabling interaction. Popular JavaScript frameworks like React, Vue, and Angular have revolutionized the way we build modern web applications. + +4.2. Back-End Web Development +JavaScript is not limited to the browser. With Node.js, you can run JavaScript on servers, enabling you to build full-stack web applications using a single language! + +4.3. Mobile and Desktop Apps +Frameworks like React Native (for mobile) and Electron (for desktop) allow developers to build apps for multiple platforms using JavaScript. + +4.4. Game Development +Using libraries like Phaser and Three.js, JavaScript can even be used to create 2D and 3D games that run directly in the browser. + +## 5. Adding JavaScript to Your Web Page + +To include JavaScript in a web page, you can embed it directly within the HTML using the tag. + +### 5.1. Inline JavaScript +You can add JavaScript code directly inside your HTML: + +```html + +``` + +### 5.2. External JavaScript +For larger projects, it's better to keep your JavaScript in a separate file: +```html + +``` + +### 5.3. Best Practice + +- **Separation of Concerns**: Keep your HTML, CSS, and JavaScript separate for better organization. +- **Asynchronous Loading**: Use the `defer` attribute to load scripts asynchronously without blocking the page rendering. + +```html + +``` + +## 6. Conclusion + +JavaScript is a powerful language that drives the interactivity of the web. By learning JavaScript, you can create dynamic web applications, interactive games, and much more. Stay tuned for more JavaScript guides and tutorials! \ No newline at end of file diff --git a/docs/languages/javascript/js-1.md b/docs/languages/javascript/js-1.md new file mode 100644 index 000000000..02ff30a26 --- /dev/null +++ b/docs/languages/javascript/js-1.md @@ -0,0 +1,205 @@ +--- +id: variables-in-javascript +sidebar_position: 1 +title: Variables in JavaScript +sidebar_label: Variables in JS +--- + +Hey, everyone! In this guide, we'll explore the concept of variables in JavaScript. Variables are essential in programming, allowing you to store and manipulate data dynamically. Let's dive in! + + + +## 1. What are Variables? + +In the world of programming, variables act as containers. Think of them like labeled boxes that hold various types of information in your program. These containers allow you to store, retrieve, and manipulate data, providing the foundation for dynamic and interactive code. + +### Visualizing Variables + +```mermaid +graph TD + subgraph Variables + style Variables fill:#f57,stroke:#333,stroke-width:2px, stroke:#262626; + A(Variable) + end + + B["Data Type (e.g., Number, String)"] + C["Variable Name (e.g., age, name)"] + + A -->|Stores| B + A -->|Named| C + + B -->|Assigned Value| D["Value (e.g., 25, 'John')"] + C -->|Used in Code| E["Code (e.g., age = 25; console.log(name);)"] +``` + +In JavaScript, we use variables to store and manage data, representing numbers, text, or more complex structures. + +```mermaid +graph TD + subgraph Variables + style Variables fill:#f9f,stroke:#333,stroke-width:2px; + A[Variable] + end + + BoxStyle(e.g., var, let, const) + style BoxStyle fill:#fff,stroke:#333,stroke-width:2px; + + B["Number"] + C["String"] + D["Boolean"] + E["Array"] + F["Object"] + + A -->|=| B["10"] + A -->|=| C["'Hello, World!'"] + A -->|=| D["true"] + A -->|=| E["[1, 2, 3]"] + A -->|=| F["{ key: 'value', age: 25 }"] +``` + + + +:::tip Definition +In JavaScript, variables are containers that hold information, allowing you to reference and manipulate values within your code. Variables are fundamental to programming, enabling you to work with data dynamically. + +In programming, variables are used to store and manage data. They act as symbolic names for values. In JavaScript, you can declare variables using the `var`, `let`, or `const` keywords. + +1. `var`: + + - Historically used for variable declaration, but it has some scoping issues. + - Variables declared with `var` are function-scoped, meaning they are only accessible within the function where they are declared. + +2. `let`: + + - Introduced in ECMAScript 6 (ES6) to address the scoping issues of `var`. + - `let` allows block-scoping, meaning the variable is limited to the block (enclosed by curly braces) where it is defined. + +3. `const`: + + - Also introduced in ES6, `const` is used to declare constants. + - Constants cannot be reassigned after declaration. + - They are block-scoped like variables declared with let. +::: + + + +## 2. Variable Declaration and Types + +Now, let's explore how to declare variables and the different types available in JavaScript. + +### Variable Declaration + +```mermaid +graph TD + subgraph Variables + style Variables fill:#f9f,stroke:#333,stroke-width:2px; + A[let age = 18;] + end + + B["if (age >= 18) {"] + C[" console.log('You are an adult.');"] + D["} else {"] + E[" console.log('You are a minor.');"] + + A -->|Variable Declaration| B + B -->|Condition Check| C + B -->|Alternative Path| D + D -->|Alternative Output| E +``` + +In JavaScript, you can declare variables using 'var,' 'let,' or 'const.' While 'var' has been around for a while, ES6 introduced 'let' and 'const.' + +**Comparison of 'var,' 'let,' and 'const':** + +```javascript +// Using var (function-scoped) +var x = 10; + +// Using let (block-scoped, reassignable) +let y = 'Hello'; + +// Using const (block-scoped, not reassignable) +const pi = 3.14; +``` + +### Variable Assignment and Dynamic Typing + +Once a variable is declared, you can assign values to it. JavaScript's dynamic typing allows the type of a variable to change during runtime. + +**Example of Variable Assignment and Dynamic Typing:** + + + +This flexibility is powerful, but it's crucial to be aware of the data types your variables hold to avoid unexpected behavior. + + + +## 3. Scope and Hoisting + +Understanding the scope of variables is crucial for writing robust and error-free code. JavaScript has function-scoped variables with 'var' and block-scoped variables with 'let' and 'const.' + +### Scope + +Scope defines the context in which variables are accessible. Let's explore function and block scope. + +```javascript +function exampleScope() { + if (true) { + var localVar = "I'm accessible inside the function"; + let blockVar = "I'm accessible only in this block"; + } + console.log(localVar); // Accessible + console.log(blockVar); // Error: blockVar is not defined +} +``` + +### Hoisting + +Variable and function declarations are hoisted to the top of their containing scope during compilation. + +```javascript +console.log(hoistedVar); // Outputs undefined +var hoistedVar = "I am hoisted!"; +``` + +## 4. Save Code + +To organize and reuse code effectively, consider saving reusable portions as functions or modules. This approach promotes maintainability and helps avoid redundancy. + +```javascript +// Example function +function greet(name) { + return `Hello, ${name}!`; +} + +// Using the function +let message = greet("Algo"); +console.log(message); // Outputs: Hello, Algo! +``` + + + +## 5. Best Practices + +Before we wrap up, let's discuss some best practices for working with variables in JavaScript. + +### Use `const` by Default + +In modern JavaScript, it's recommended to use `const` by default. If you know the value will change, then use `let`. + +```js +const maxAttempts = 3; +let currentAttempts = 0; +``` + +### Avoid `var + +The `var` keyword is outdated and can lead to unexpected issues. Prefer `let` and `const` for better-scoped variables. + +```js +var oldWay = "I'm using var."; + +let modernWay = "I'm using let."; +``` + +***Congratulations! You've now gained a comprehensive understanding of variables in JavaScript.*** \ No newline at end of file diff --git a/docs/languages/javascript/js-10.md b/docs/languages/javascript/js-10.md new file mode 100644 index 000000000..229509285 --- /dev/null +++ b/docs/languages/javascript/js-10.md @@ -0,0 +1,243 @@ +--- +id: objects-in-javascript +sidebar_position: 10 +title: "Objects In JavaScript" +sidebar_label: "Objects In JavaScript" +--- + +Hey there! In this guide, we'll explore how to work with objects in JavaScript. Objects are collections of properties, and they play a crucial role in JavaScript programming. Let’s dive into it! + + + +## 1. Creating an Object + +In JavaScript, objects can be created using object literals or constructors. + +### 1.1 Using Object Literals + +This is the most straightforward way to create an object in JavaScript. + +**Example:** + +```javascript +const person = { + firstName: "John", + lastName: "Doe", + age: 30, + greet: function () { + console.log("Hello, " + this.firstName); + }, +}; + +console.log(person.firstName); // Output: John +person.greet(); // Output: Hello, John +``` + + + +### 1.2 Using the `new Object()` Syntax + +Another way to create an object is by using the `new Object()` syntax. + +**Example:** + +```javascript +const person = new Object(); +person.firstName = "Jane"; +person.lastName = "Doe"; +person.age = 25; + +console.log(person.firstName); // Output: Jane +``` + +## 2. Accessing Object Properties + +You can access object properties using either dot notation or bracket notation. + +### 2.1 Dot Notation + +**Example:** + +```javascript +const car = { + make: "Toyota", + model: "Camry", + year: 2020, +}; + +console.log(car.make); // Output: Toyota +``` + +### 2.2 Bracket Notation + +**Example:** + +```javascript +const car = { + make: "Toyota", + model: "Camry", + year: 2020, +}; + +console.log(car["model"]); // Output: Camry +``` + + + +## 3. Modifying Object Properties + +You can modify object properties by assigning a new value to them. + +**Example:** + +```javascript +const book = { + title: "The Great Gatsby", + author: "F. Scott Fitzgerald", + year: 1925, +}; + +book.year = 1926; // Modify the year +console.log(book.year); // Output: 1926 +``` + +## 4. Adding and Deleting Properties + +### 4.1 Adding Properties + +You can add properties to an existing object at any time. + +**Example:** + +```javascript +const student = { + name: "Alice", +}; + +student.age = 22; // Adding a new property +console.log(student.age); // Output: 22 +``` + + + +### 4.2 Deleting Properties + +You can delete a property using the `delete` operator. + +**Example:** + +```javascript +const student = { + name: "Alice", + age: 22, +}; + +delete student.age; // Delete the age property +console.log(student.age); // Output: undefined +``` + + + +## 5. Methods in Objects + +Object methods are functions stored as object properties. + +**Example:** + +```javascript +const person = { + firstName: "John", + lastName: "Doe", + fullName: function () { + return this.firstName + " " + this.lastName; + }, +}; + +console.log(person.fullName()); // Output: John Doe +``` + +--- + +## 6. Looping Through Object Properties + +You can loop through the properties of an object using a `for...in` loop. + +**Example:** + +```javascript +const car = { + make: "Toyota", + model: "Camry", + year: 2020, +}; + +for (let key in car) { + console.log(key + ": " + car[key]); +} +``` + +#### Output: + +``` +make: Toyota +model: Camry +year: 2020 +``` + + + +## 7. Nested Objects + +Objects can contain other objects as properties. + +**Example:** + +```javascript +const employee = { + name: "John", + position: "Developer", + contact: { + email: "john@example.com", + phone: "123-456-7890", + }, +}; + +console.log(employee.contact.email); // Output: john@example.com +``` + +## 8. Checking for Properties + +You can check if an object has a specific property using the `in` operator or `hasOwnProperty()` method. + +**Example:** + +```javascript +const car = { + make: "Toyota", + model: "Camry", +}; + +console.log("make" in car); // Output: true +console.log(car.hasOwnProperty("model")); // Output: true +``` + +## 9. Object Destructuring + +Object destructuring allows you to unpack properties from an object into variables. + +**Example:** + +```javascript +const user = { + name: "John", + age: 30, +}; + +const { name, age } = user; +console.log(name); // Output: John +console.log(age); // Output: 30 +``` + + + +Objects are the backbone of JavaScript, allowing you to model real-world entities and organize your code more effectively. Understanding how to use objects will significantly enhance your JavaScript skills. \ No newline at end of file diff --git a/docs/languages/javascript/js-11.md b/docs/languages/javascript/js-11.md new file mode 100644 index 000000000..c136c9202 --- /dev/null +++ b/docs/languages/javascript/js-11.md @@ -0,0 +1,82 @@ +--- +id: closures-in-javascript +sidebar_position: 11 +title: Closures in JavaScript +sidebar_label: Closures in JavaScript +--- + +Closures are a fundamental concept in JavaScript, enabling functions to retain access to variables from their outer scope even after the outer function has finished execution. This behavior is crucial in many advanced JavaScript patterns like callbacks, event handlers, and function factories. + + + +## What is a Closure? + +A **closure** is created when a function is defined inside another function and that inner function has access to the outer function's variables. The inner function "remembers" the environment in which it was created, even after the outer function has returned. + +## Key Concepts: +1. **Lexical Scope**: Functions can access variables from their parent scope. +2. **Retention of Variables**: Inner functions retain access to variables in the outer function, even after the outer function has completed. + +## Example: Basic Closure + +```javascript +function outer() { + let count = 0; // outer function variable + return function inner() { // inner function + count++; // modifying the outer variable + console.log(count); + }; +} + +const counter = outer(); +counter(); // Output: 1 +counter(); // Output: 2 +``` + +In this example, the inner function inner retains access to the variable count from the outer function outer, even after outer has returned. + + + +## Real-World Use Cases: +- Private Variables: Encapsulating data and exposing only what’s necessary. +- Callback Functions: Retaining state within event handlers or asynchronous operations. +- Function Factories: Creating customized functions. + +## Example: Closure for Private Variables + +```javascript +function createCounter() { + let count = 0; // private variable + return { + increment: function() { + count++; + console.log(count); + }, + reset: function() { + count = 0; + console.log("Counter reset"); + } + }; +} + +const myCounter = createCounter(); +myCounter.increment(); // Output: 1 +myCounter.increment(); // Output: 2 +myCounter.reset(); // Output: Counter reset +``` + +In this example, count remains private to the createCounter function but can be manipulated through the increment and reset methods. + +## Benefits of Closures: + +1. **Encapsulation**: Hiding implementation details and exposing an interface. +2. **Data Privacy**: Protecting variables from external modification. +3. **State Retention**: Preserving state across function calls. +4. **Customization**: Creating specialized functions with shared state. +5. **Memory Efficiency**: Sharing common variables across multiple function calls. +6. **Callback Handling**: Managing asynchronous operations and event listeners. +7. **Function Factories**: Generating functions with pre-configured settings. +8. **Currying**: Partially applying functions for reusability. +9. **Memoization**: Caching results for performance optimization. + +Closures are a powerful feature in JavaScript that enables developers to write more expressive and efficient code. Understanding closures is essential for mastering advanced JavaScript concepts and patterns. \ No newline at end of file diff --git a/docs/languages/javascript/js-12.md b/docs/languages/javascript/js-12.md new file mode 100644 index 000000000..68881c1fb --- /dev/null +++ b/docs/languages/javascript/js-12.md @@ -0,0 +1,261 @@ +--- +id: inheritance-in-javascript +sidebar_position: 12 +title: "Inheritance in JavaScript" +sidebar_label: "Inheritance In JavaScript" +--- + +Hello! In this guide, we'll explore how inheritance works in JavaScript. Inheritance is a core concept in object-oriented programming (OOP) and allows one class to inherit properties and methods from another. JavaScript, being a prototype-based language, implements inheritance through prototypes. Let’s dive in! + + + +## 1. Prototypal Inheritance + +JavaScript objects have a special hidden property called `[[Prototype]]`, which is either `null` or references another object. This object is referred to as the prototype. When trying to access a property on an object, JavaScript will first look for it on the object itself. If it's not found, it will look for the property in the prototype chain. + +**Example:** + +```javascript +let animal = { + eats: true, +}; + +let rabbit = { + jumps: true, +}; + +rabbit.__proto__ = animal; // Set animal as the prototype of rabbit + +console.log(rabbit.eats); // true (inherited from animal) +console.log(rabbit.jumps); // true (own property) +``` + +#### Output: + +``` +true +true +``` + +--- + +## 2. Using `Object.create()` + +The `Object.create()` method creates a new object with the specified prototype object and properties. + +#### Example: + +```javascript +let animal = { + eats: true, +}; + +let rabbit = Object.create(animal); +rabbit.jumps = true; + +console.log(rabbit.eats); // true (inherited from animal) +console.log(rabbit.jumps); // true (own property) +``` + +#### Output: + +``` +true +true +``` + +--- + +## 3. ES6 Classes and Inheritance + +In ES6, JavaScript introduced the `class` syntax, which is a more convenient way to work with inheritance. + +### 3.1 Defining Classes + +Classes are defined using the `class` keyword, and inheritance is established using the `extends` keyword. + +#### Example: + +```javascript +class Animal { + constructor(name) { + this.name = name; + } + + speak() { + console.log(`${this.name} makes a noise.`); + } +} + +class Dog extends Animal { + speak() { + console.log(`${this.name} barks.`); + } +} + +let dog = new Dog("Rex"); +dog.speak(); // Rex barks. +``` + +#### Output: + +``` +Rex barks. +``` + +--- + +### 3.2 Super Keyword + +The `super` keyword is used to call the constructor or methods of the parent class. + +#### Example: + +```javascript +class Animal { + constructor(name) { + this.name = name; + } + + speak() { + console.log(`${this.name} makes a noise.`); + } +} + +class Dog extends Animal { + constructor(name, breed) { + super(name); // Call parent constructor + this.breed = breed; + } + + speak() { + super.speak(); // Call parent method + console.log(`${this.name} barks.`); + } +} + +let dog = new Dog("Rex", "Labrador"); +dog.speak(); +``` + +#### Output: + +``` +Rex makes a noise. +Rex barks. +``` + +--- + +## 4. Checking Inheritance + +You can check if an object inherits from another object using the `instanceof` operator or the `isPrototypeOf()` method. + +### 4.1 Using `instanceof` + +The `instanceof` operator checks if an object is an instance of a class. + +#### Example: + +```javascript +class Animal {} +class Dog extends Animal {} + +let dog = new Dog(); + +console.log(dog instanceof Dog); // true +console.log(dog instanceof Animal); // true +console.log(dog instanceof Object); // true +``` + +#### Output: + +``` +true +true +true +``` + +--- + +### 4.2 Using `isPrototypeOf()` + +The `isPrototypeOf()` method checks if an object exists in another object's prototype chain. + +#### Example: + +```javascript +let animal = {}; +let rabbit = Object.create(animal); + +console.log(animal.isPrototypeOf(rabbit)); // true +``` + +#### Output: + +``` +true +``` + +--- + +## 5. Overriding Methods + +In JavaScript, a subclass can override the methods of its superclass. This is often done to provide specialized behavior. + +#### Example: + +```javascript +class Animal { + speak() { + console.log("Animal speaks"); + } +} + +class Dog extends Animal { + speak() { + console.log("Dog barks"); + } +} + +let dog = new Dog(); +dog.speak(); // Dog barks (method overridden) +``` + +#### Output: + +``` +Dog barks +``` + +--- + +## 6. Static Methods and Properties + +JavaScript classes can also have static methods and properties, which are called on the class itself, not on instances. + +#### Example: + +```javascript +class Animal { + static category = "Mammal"; + + static info() { + console.log("Animals are multicellular organisms."); + } +} + +console.log(Animal.category); // Mammal +Animal.info(); // Animals are multicellular organisms. +``` + +#### Output: + +``` +Mammal +Animals are multicellular organisms. +``` + +--- + +JavaScript inheritance, through prototypes or the `class` syntax, allows for powerful code reuse and logical organization. By mastering inheritance, you can create more flexible and efficient code. Happy coding! diff --git a/docs/languages/javascript/js-13.md b/docs/languages/javascript/js-13.md new file mode 100644 index 000000000..74083dedf --- /dev/null +++ b/docs/languages/javascript/js-13.md @@ -0,0 +1,171 @@ +--- +id: modules-in-javascript +sidebar_position: 13 +title: "Modules in JavaScript" +sidebar_label: "Modules In JavaScript" +--- + +# Modules in JavaScript + +Hello! In this guide, we’ll explore how modules work in JavaScript. Modules are an essential part of modern JavaScript development, allowing developers to break code into reusable pieces and manage dependencies. Let’s get started! + +--- + +## 1. What Are Modules? + +Modules in JavaScript are reusable blocks of code, encapsulated within their own scope. They allow developers to divide the code into smaller, manageable files and export functionality from one module to be used in other modules. + +--- + +## 2. Exporting and Importing Modules + +### 2.1 Exporting + +There are two types of exports in JavaScript modules: + +#### Named Exports + +You can export multiple things from a module using named exports. + +#### Example: + +```javascript +// math.js +export function add(x, y) { + return x + y; +} + +export function subtract(x, y) { + return x - y; +} +``` + +#### Exporting an Object: + +```javascript +// utility.js +const utilities = { + greet: function (name) { + return `Hello, ${name}`; + }, + farewell: function (name) { + return `Goodbye, ${name}`; + }, +}; + +export { utilities }; +``` + +#### Default Export + +You can export a single value, class, or function as the default export from a module. + +#### Example: + +```javascript +// logger.js +export default function log(message) { + console.log(message); +} +``` + +--- + +### 2.2 Importing + +To use exported functions, variables, or classes from a module, you can import them using the `import` statement. + +#### Example: + +```javascript +// main.js +import { add, subtract } from "./math.js"; + +console.log(add(2, 3)); // 5 +console.log(subtract(5, 3)); // 2 +``` + +#### Importing Default Export: + +```javascript +// main.js +import log from "./logger.js"; + +log("This is a log message."); // This is a log message. +``` + +#### Importing Everything from a Module: + +You can import all named exports at once using the `*` syntax. + +#### Example: + +```javascript +// main.js +import * as math from "./math.js"; + +console.log(math.add(2, 3)); // 5 +console.log(math.subtract(5, 3)); // 2 +``` + +--- + +## 3. Dynamic Imports + +Dynamic imports allow you to load modules dynamically as needed using the `import()` function. + +#### Example: + +```javascript +// main.js +import("./math.js").then((math) => { + console.log(math.add(2, 3)); // 5 +}); +``` + +--- + +## 4. Benefits of Using Modules + +- **Encapsulation:** Code is kept in separate files, reducing global scope pollution. +- **Reusability:** Modules can be reused across different projects. +- **Maintainability:** Dividing code into modules makes it easier to maintain and scale. +- **Lazy Loading:** Using dynamic imports, modules can be loaded on demand, improving performance. + +--- + +## 5. CommonJS vs ES Modules + +Before the introduction of ES Modules (ECMAScript modules), JavaScript relied on CommonJS for modularity in Node.js. + +### 5.1 CommonJS + +CommonJS modules use `require()` to import and `module.exports` to export. + +#### Example: + +```javascript +// math.js (CommonJS) +function add(x, y) { + return x + y; +} + +module.exports = { add }; +``` + +#### Importing in CommonJS: + +```javascript +// main.js +const { add } = require("./math.js"); + +console.log(add(2, 3)); // 5 +``` + +### 5.2 ES Modules + +ES Modules use `import` and `export` statements, and they work in both browser and Node.js environments (with Node.js 12+). + +--- + +JavaScript modules make your code cleaner, more maintainable, and reusable. Whether you're using CommonJS or ES Modules, understanding how to work with modules is key to modern JavaScript development. Happy coding! diff --git a/docs/languages/javascript/js-14.md b/docs/languages/javascript/js-14.md new file mode 100644 index 000000000..4a5e66d6e --- /dev/null +++ b/docs/languages/javascript/js-14.md @@ -0,0 +1,195 @@ +--- +id: promises-in-javascript +sidebar_position: 14 +title: "Promises in JavaScript" +sidebar_label: "Promises In JavaScript" +--- + +# Promises in JavaScript + +Hello! In this guide, we’ll explore how **Promises** work in JavaScript. Promises are used to handle asynchronous operations and are an essential part of modern JavaScript programming. Let's dive in! + +--- + +## 1. What is a Promise? + +A Promise in JavaScript is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises can be in one of three states: + +- **Pending:** The initial state, neither fulfilled nor rejected. +- **Fulfilled:** The operation completed successfully. +- **Rejected:** The operation failed. + +--- + +## 2. Creating a Promise + +A Promise is created using the `new Promise()` constructor, which takes a function (known as the executor) that contains two callback functions: `resolve` and `reject`. + +#### Example: + +```javascript +let promise = new Promise(function (resolve, reject) { + // some async operation + let success = true; + + if (success) { + resolve("Operation successful!"); + } else { + reject("Operation failed!"); + } +}); +``` + +In this example, the Promise will call `resolve` if the operation succeeds and `reject` if it fails. + +--- + +## 3. Consuming a Promise + +Once a Promise is created, you can use `.then()`, `.catch()`, and `.finally()` to handle its result. + +### 3.1 `.then()` + +The `.then()` method is used to handle a fulfilled Promise. + +#### Example: + +```javascript +promise.then(function (result) { + console.log(result); // "Operation successful!" +}); +``` + +### 3.2 `.catch()` + +The `.catch()` method is used to handle a rejected Promise. + +#### Example: + +```javascript +promise.catch(function (error) { + console.log(error); // "Operation failed!" +}); +``` + +### 3.3 `.finally()` + +The `.finally()` method is executed once the Promise is settled (either fulfilled or rejected), regardless of the outcome. + +#### Example: + +```javascript +promise.finally(function () { + console.log("Promise is settled."); +}); +``` + +--- + +## 4. Chaining Promises + +You can chain multiple `.then()` calls together. Each `.then()` receives the result of the previous `.then()`. + +#### Example: + +```javascript +let promise = new Promise(function (resolve, reject) { + resolve(10); +}); + +promise + .then(function (result) { + return result * 2; + }) + .then(function (result) { + return result + 5; + }) + .then(function (result) { + console.log(result); // 25 + }); +``` + +--- + +## 5. Promise Methods + +JavaScript provides several built-in methods to work with multiple Promises. + +### 5.1 `Promise.all()` + +The `Promise.all()` method takes an array of Promises and returns a new Promise that resolves when all the input Promises resolve, or rejects if any of the Promises reject. + +#### Example: + +```javascript +let promise1 = Promise.resolve(5); +let promise2 = Promise.resolve(10); + +Promise.all([promise1, promise2]).then(function (results) { + console.log(results); // [5, 10] +}); +``` + +### 5.2 `Promise.race()` + +The `Promise.race()` method returns a Promise that resolves or rejects as soon as one of the input Promises resolves or rejects. + +#### Example: + +```javascript +let promise1 = new Promise(function (resolve) { + setTimeout(() => resolve("First Promise"), 500); +}); + +let promise2 = new Promise(function (resolve) { + setTimeout(() => resolve("Second Promise"), 100); +}); + +Promise.race([promise1, promise2]).then(function (result) { + console.log(result); // "Second Promise" +}); +``` + +### 5.3 `Promise.allSettled()` + +The `Promise.allSettled()` method returns a Promise that resolves when all of the input Promises settle (either fulfilled or rejected). + +#### Example: + +```javascript +let promise1 = Promise.resolve(10); +let promise2 = Promise.reject("Error"); + +Promise.allSettled([promise1, promise2]).then(function (results) { + console.log(results); + // [ + // {status: "fulfilled", value: 10}, + // {status: "rejected", reason: "Error"} + // ] +}); +``` + +--- + +## 6. Async/Await + +The `async` and `await` keywords allow you to work with Promises in a more readable way, avoiding the need for chaining `.then()`. + +#### Example: + +```javascript +async function fetchData() { + try { + let result = await promise; + console.log(result); // "Operation successful!" + } catch (error) { + console.log(error); // "Operation failed!" + } +} + +fetchData(); +``` + +--- + +Promises are essential in managing asynchronous operations in JavaScript, whether you're handling API calls, timers, or other async tasks. By mastering Promises, you can write cleaner and more efficient asynchronous code. Happy coding! diff --git a/docs/languages/javascript/js-15.md b/docs/languages/javascript/js-15.md new file mode 100644 index 000000000..fb00d193e --- /dev/null +++ b/docs/languages/javascript/js-15.md @@ -0,0 +1,195 @@ +--- +id: async-await-in-javascript +sidebar_position: 15 +title: "Async/Await in JavaScript" +sidebar_label: "Async/Await In JavaScript" +--- + +# Async/Await in JavaScript + +Hello! In this guide, we’ll explore how the `async` and `await` keywords work in JavaScript. These features make it easier to work with Promises and asynchronous code. Let’s dive into the details! + +--- + +## 1. What is `async`/`await`? + +`async` and `await` are syntactic sugar built on top of Promises. They make asynchronous code look and behave like synchronous code, improving readability and maintainability. + +### 1.1 `async` Keyword + +The `async` keyword is used to define an asynchronous function. An `async` function always returns a Promise. + +#### Example: + +```javascript +async function fetchData() { + return "Data fetched!"; +} + +fetchData().then((result) => console.log(result)); // Data fetched! +``` + +### 1.2 `await` Keyword + +The `await` keyword can only be used inside an `async` function. It pauses the execution of the function until the Promise resolves. + +#### Example: + +```javascript +async function fetchData() { + let result = await Promise.resolve("Data fetched!"); + console.log(result); // Data fetched! +} + +fetchData(); +``` + +--- + +## 2. Error Handling with `try`/`catch` + +You can use `try`/`catch` blocks to handle errors in `async` functions, making it easier to manage rejected Promises. + +#### Example: + +```javascript +async function fetchData() { + try { + let result = await Promise.reject("Error occurred!"); + } catch (error) { + console.log(error); // Error occurred! + } +} + +fetchData(); +``` + +--- + +## 3. Using `await` with Multiple Promises + +You can use `await` to handle multiple Promises by awaiting each one sequentially, or you can use `Promise.all()` to await all Promises in parallel. + +### 3.1 Sequential Promise Handling + +#### Example: + +```javascript +async function fetchSequential() { + let result1 = await Promise.resolve("First result"); + let result2 = await Promise.resolve("Second result"); + + console.log(result1); // First result + console.log(result2); // Second result +} + +fetchSequential(); +``` + +### 3.2 Parallel Promise Handling with `Promise.all()` + +#### Example: + +```javascript +async function fetchParallel() { + let [result1, result2] = await Promise.all([ + Promise.resolve("First result"), + Promise.resolve("Second result"), + ]); + + console.log(result1); // First result + console.log(result2); // Second result +} + +fetchParallel(); +``` + +--- + +## 4. Async Functions Return Promises + +Even if an `async` function doesn’t explicitly return a Promise, it will still return one implicitly. + +#### Example: + +```javascript +async function fetchData() { + return "Data fetched!"; +} + +console.log(fetchData()); // Promise {: "Data fetched!"} +``` + +--- + +## 5. Handling Timeouts with `await` + +You can simulate a delay or timeout using `await` by combining it with `setTimeout()` wrapped in a Promise. + +#### Example: + +```javascript +function delay(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +async function fetchData() { + console.log("Fetching data..."); + await delay(2000); // Wait for 2 seconds + console.log("Data fetched!"); +} + +fetchData(); +``` + +#### Output: + +``` +Fetching data... +(Data is fetched after 2 seconds) +Data fetched! +``` + +--- + +## 6. Avoiding `await` Pitfalls + +Using `await` inside loops can cause performance issues if not used carefully. To avoid delays, use `Promise.all()` to run Promises in parallel when possible. + +#### Example of Sequential Delay (Not Recommended): + +```javascript +async function fetchItemsSequential() { + const items = [1, 2, 3]; + + for (let item of items) { + await delay(1000); + console.log(`Fetched item ${item}`); + } +} + +fetchItemsSequential(); +// Takes 3 seconds total, 1 second for each item. +``` + +#### Example of Parallel Execution (Recommended): + +```javascript +async function fetchItemsParallel() { + const items = [1, 2, 3]; + + await Promise.all( + items.map(async (item) => { + await delay(1000); + console.log(`Fetched item ${item}`); + }) + ); +} + +fetchItemsParallel(); +// Takes 1 second total, runs all fetches in parallel. +``` + +--- + +`async` and `await` make it easier to write and manage asynchronous JavaScript code. They provide a clean, readable alternative to Promises while still maintaining the same functionality. Mastering these features will help you handle async tasks like API calls, timeouts, and more efficiently. Happy coding! diff --git a/docs/languages/javascript/js-16.md b/docs/languages/javascript/js-16.md new file mode 100644 index 000000000..623da49ac --- /dev/null +++ b/docs/languages/javascript/js-16.md @@ -0,0 +1,182 @@ +--- +id: datetime-in-javascript +sidebar_position: 16 +title: "Date and Time in JavaScript" +sidebar_label: "Date and Time" +--- + +# Date and Time in JavaScript + +Working with date and time in JavaScript is essential for creating applications that involve scheduling, logging events, or simply displaying the current time. JavaScript provides the `Date` object for handling dates and times. This guide will cover how to use the `Date` object, including creating dates, formatting them, and performing date arithmetic. + +--- + +## 1. Creating a `Date` Object + +You can create a `Date` object using various methods: + +### 1.1 Creating a Date for the Current Time + +The simplest way to create a `Date` object is to call the constructor without arguments, which creates a date representing the current date and time. + +```javascript +let currentDate = new Date(); +console.log(currentDate); // Current date and time +``` + +### 1.2 Creating a Date with Specific Values + +You can also create a `Date` object by passing specific values for the year, month, day, hour, minute, second, and millisecond. + +```javascript +let specificDate = new Date(2024, 10, 3, 14, 30, 0); // November 3, 2024, 14:30:00 +console.log(specificDate); +``` + +> **Note**: Months are zero-based, meaning January is `0` and December is `11`. + +### 1.3 Creating a Date from a String + +You can also create a date by passing a date string: + +```javascript +let dateFromString = new Date("2024-11-03T14:30:00"); +console.log(dateFromString); // November 3, 2024, 14:30:00 +``` + +### 1.4 Creating a Date Using Timestamps + +The `Date` constructor can also take a timestamp (milliseconds since January 1, 1970, 00:00:00 UTC). + +```javascript +let dateFromTimestamp = new Date(1709591400000); +console.log(dateFromTimestamp); // Date corresponding to the given timestamp +``` + +--- + +## 2. Getting Date and Time Components + +You can extract different components of a `Date` object using various methods: + +```javascript +let currentDate = new Date(); + +console.log(currentDate.getFullYear()); // Year (e.g., 2024) +console.log(currentDate.getMonth()); // Month (0-11) +console.log(currentDate.getDate()); // Day of the month (1-31) +console.log(currentDate.getDay()); // Day of the week (0-6, where 0 is Sunday) +console.log(currentDate.getHours()); // Hours (0-23) +console.log(currentDate.getMinutes()); // Minutes (0-59) +console.log(currentDate.getSeconds()); // Seconds (0-59) +console.log(currentDate.getMilliseconds()); // Milliseconds (0-999) +``` + +> **Tip**: `getMonth()` returns a zero-based month, so you may need to add `1` for display purposes. + +--- + +## 3. Formatting Dates + +Formatting dates in JavaScript can be done manually or using libraries like `Intl.DateTimeFormat` for internationalization. + +### 3.1 Manual Formatting + +You can create custom date formats by combining the components: + +```javascript +let currentDate = new Date(); +let formattedDate = `${currentDate.getDate()}/${currentDate.getMonth() + 1}/${currentDate.getFullYear()}`; +console.log(formattedDate); // e.g., "3/11/2024" +``` + +### 3.2 Using `Intl.DateTimeFormat` + +The `Intl.DateTimeFormat` object provides an easy way to format dates: + +```javascript +let currentDate = new Date(); +let formatter = new Intl.DateTimeFormat("en-US", { dateStyle: "full", timeStyle: "short" }); +console.log(formatter.format(currentDate)); // e.g., "Sunday, November 3, 2024, 2:30 PM" +``` + +> **Options**: Customize the `dateStyle` and `timeStyle` for different formats (`"short"`, `"medium"`, `"long"`, `"full"`). + +--- + +## 4. Date Arithmetic + +You can perform arithmetic operations like adding or subtracting days, hours, or minutes. + +### 4.1 Adding Days + +```javascript +let currentDate = new Date(); +currentDate.setDate(currentDate.getDate() + 5); // Add 5 days +console.log(currentDate); +``` + +### 4.2 Subtracting Days + +```javascript +let currentDate = new Date(); +currentDate.setDate(currentDate.getDate() - 5); // Subtract 5 days +console.log(currentDate); +``` + +### 4.3 Calculating Time Differences + +You can calculate the difference between two dates in milliseconds and convert it to days or other units. + +```javascript +let date1 = new Date("2024-11-03"); +let date2 = new Date("2024-12-03"); + +let differenceInMs = date2 - date1; +let differenceInDays = differenceInMs / (1000 * 60 * 60 * 24); +console.log(differenceInDays); // Difference in days +``` + +--- + +## 5. Working with Time Zones + +JavaScript `Date` objects are based on the browser's local time zone. You can work with time zones using `toUTCString()` or libraries like `moment-timezone`. + +### 5.1 Converting to UTC + +```javascript +let currentDate = new Date(); +console.log(currentDate.toUTCString()); // Convert to UTC time +``` + +### 5.2 Getting the Time Zone Offset + +```javascript +let currentDate = new Date(); +console.log(currentDate.getTimezoneOffset()); // Time zone difference in minutes +``` + +--- + +## 6. Using Date Libraries + +Libraries like **Moment.js**, **date-fns**, and **Luxon** provide additional functionality and simplify date manipulation. + +### 6.1 Example Using `date-fns` + +```javascript +import { format, addDays } from "date-fns"; + +let currentDate = new Date(); +let newDate = addDays(currentDate, 5); // Add 5 days +console.log(format(newDate, "yyyy-MM-dd")); // Format date as "2024-11-08" +``` + +--- + +## 7. Common Pitfalls and Best Practices + +1. **Month Indexing**: Remember that months are zero-based, so always add `1` when displaying them. +2. **Time Zone Issues**: Be cautious when dealing with dates across different time zones. Use libraries for better handling. +3. **Immutable Operations**: `Date` methods like `setDate` modify the original `Date` object. Make a copy if you need to retain the original date. diff --git a/docs/languages/javascript/js-17.md b/docs/languages/javascript/js-17.md new file mode 100644 index 000000000..67a444d77 --- /dev/null +++ b/docs/languages/javascript/js-17.md @@ -0,0 +1,233 @@ +--- +id: exception-handling-in-javascript +sidebar_position: 17 +title: "Exception Handling in JavaScript" +sidebar_label: "Exception Handling in JavaScript" +--- + + +# Exception Handling in JavaScript + +Exception handling is essential for writing robust JavaScript code that can handle errors gracefully, ensuring your application doesn’t crash unexpectedly. JavaScript provides the `try`, `catch`, `finally`, and `throw` constructs to manage exceptions effectively. + +--- + +## 1. What is Exception Handling? + +Exception handling in JavaScript allows you to manage and respond to runtime errors. Errors can occur for various reasons, such as network failures, invalid input, or unexpected behavior. Using exception handling, you can handle these errors gracefully and continue executing code or log necessary details for debugging. + +--- + +## 2. Using `try` and `catch` + +The `try` block contains code that might throw an error, and the `catch` block contains code to handle the error. + +### Syntax: + +```javascript +try { + // Code that might throw an error +} catch (error) { + // Code to handle the error +} +``` + +### Example: + +```javascript +try { + let result = riskyFunction(); + console.log(result); +} catch (error) { + console.log("An error occurred:", error.message); +} +``` + +In this example, if `riskyFunction()` throws an error, the `catch` block will log the error message. + +--- + +## 3. The `finally` Block + +The `finally` block contains code that will always execute, regardless of whether an error was thrown or not. It is typically used for cleanup operations, such as closing files or releasing resources. + +### Syntax: + +```javascript +try { + // Code that might throw an error +} catch (error) { + // Code to handle the error +} finally { + // Code that will always execute +} +``` + +### Example: + +```javascript +try { + let data = fetchData(); + console.log("Data fetched successfully:", data); +} catch (error) { + console.log("Failed to fetch data:", error.message); +} finally { + console.log("Cleanup operations complete."); +} +``` + +> **Note**: The `finally` block runs even if there’s a `return` statement in the `try` or `catch` block. + +--- + +## 4. Throwing Custom Errors with `throw` + +You can use the `throw` statement to create and throw custom errors. This is useful for validating data or handling specific error conditions. + +### Syntax: + +```javascript +throw new Error("Custom error message"); +``` + +### Example: + +```javascript +function validateAge(age) { + if (age < 18) { + throw new Error("Age must be 18 or older."); + } + return "Age is valid."; +} + +try { + console.log(validateAge(16)); // Throws an error +} catch (error) { + console.log("Validation error:", error.message); +} +``` + +--- + +## 5. Catching Specific Errors + +You can use the `instanceof` operator to differentiate between different types of errors and handle them appropriately. + +### Example: + +```javascript +try { + // Simulate a reference error + let result = nonExistentFunction(); +} catch (error) { + if (error instanceof ReferenceError) { + console.log("Reference error caught:", error.message); + } else if (error instanceof TypeError) { + console.log("Type error caught:", error.message); + } else { + console.log("An unexpected error occurred:", error.message); + } +} +``` + +This approach allows you to handle different types of errors in different ways. + +--- + +## 6. Nested `try`/`catch` Blocks + +You can nest `try`/`catch` blocks to handle errors at different levels of your application. + +### Example: + +```javascript +try { + try { + riskyOperation(); + } catch (error) { + console.log("Handled in inner catch:", error.message); + throw error; // Rethrow the error to the outer catch + } +} catch (error) { + console.log("Handled in outer catch:", error.message); +} +``` + +--- + +## 7. Using `catch` Without an `error` Parameter + +Since ES10 (ECMAScript 2019), you can omit the `error` parameter if you don’t need to use it. + +### Example: + +```javascript +try { + throw new Error("Something went wrong!"); +} catch { + console.log("Error caught without using the error object."); +} +``` + +--- + +## 8. Best Practices for Exception Handling + +1. **Use Specific Error Messages**: Throw errors with descriptive messages to make debugging easier. +2. **Avoid Swallowing Errors**: Make sure to log errors or handle them appropriately, instead of suppressing them silently. +3. **Handle Known Errors**: Use `instanceof` to handle known error types differently if needed. +4. **Graceful Degradation**: Use `try`/`catch` to allow your application to continue running even if an error occurs. +5. **Clean Up Resources**: Use the `finally` block for cleanup operations like closing database connections or releasing file handles. + +--- + +## 9. Common Use Cases for Exception Handling + +### 9.1 Handling Network Errors + +```javascript +async function fetchData(url) { + try { + let response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + let data = await response.json(); + console.log("Data fetched:", data); + } catch (error) { + console.log("Failed to fetch data:", error.message); + } +} + +fetchData("https://api.example.com/data"); +``` + +### 9.2 Validating User Input + +```javascript +function processUserInput(input) { + try { + if (input.trim() === "") { + throw new Error("Input cannot be empty."); + } + console.log("Processing input:", input); + } catch (error) { + console.log("Input error:", error.message); + } +} + +processUserInput(" "); // Input error: Input cannot be empty. +``` + +--- + +## 10. Summary + +- Use `try`/`catch` to handle runtime errors gracefully. +- Use `finally` for cleanup operations that should always run. +- Use `throw` to create custom errors for validation and control flow. +- Always ensure you provide meaningful error messages for easier debugging. + +Exception handling in JavaScript makes your code more robust and easier to maintain. Make sure to use it effectively to build resilient and user-friendly applications! + +Happy coding! \ No newline at end of file diff --git a/docs/languages/javascript/js-2.md b/docs/languages/javascript/js-2.md new file mode 100644 index 000000000..835ccab3f --- /dev/null +++ b/docs/languages/javascript/js-2.md @@ -0,0 +1,150 @@ +--- +id: datatype-in-javascript +sidebar_position: 2 +title: Data Type in JavaScript +sidebar_label: Data Type in JS +--- + +Data types are an essential concept in programming languages like JavaScript. They define the type of data that can be stored and manipulated in a program. Understanding data types is crucial for writing efficient and bug-free code. Let's explore the different data types in JavaScript: + + + +## 1. **Primitive Data Types:** + +These are the basic building blocks of data. + +### String: + +- A sequence of characters. +- Defined with single (' ') or double (" ") quotes. + +```javascript +let greeting = "Hello, World!"; +``` + +- Template Literals / Template strings + + - A special type of strings created using backticks(`) + + ```javascript + let info = `Know more about Template Literals`; + ``` + + - Allows multi-line strings + + ```javascript + let example = `This is an application + of template literals + in JavaScript `; + ``` + + - Allows string interpolation :- Template literals allow embedding variables and expressions directly into strings using '${}' + + ```javascript + let num = 7, + name = "Kim"; + let interpolatedString = `${name}'s lucky number is ${2 * num}`; + //Kim's lucky number is 14 + ``` + +### Number: + +- Represents both integers and floating-point numbers. +- No distinction between integers and floats. + +```javascript +let age = 25; +let price = 19.99; +``` + +### Boolean: + +- Represents either `true` or `false`. + +```javascript +let isStudent = true; +``` + +### Undefined: + +- Variable declared but not assigned. + +```javascript +let undefinedVar; +``` + +### Null: + +- Represents the intentional absence of any object value. + +```javascript +let nullVar = null; +``` + +### Symbol (ES6 and later): + +- Provides a unique value, often used as identifiers. + +```javascript +let id = Symbol("id"); +``` + +## 2. **Composite Data Types:** + +These are used to store collections of data. + +### Array: + +- Ordered list of values, accessed by index. + +```javascript +let colors = ["red", "green", "blue"]; +``` + +### Object: + +- Unordered collection of key-value pairs. + +```javascript +let person = { + name: "John", + age: 30, + isStudent: false, +}; +``` + + + +## 3. **Special Data Types:** + +### Function: + +- A reusable block of code. + +```javascript +function addNumbers(a, b) { + return a + b; +} +``` + +## 4. **Type Coercion:** + +- JavaScript automatically converts one data type to another when needed. + +```javascript +let numString = "10"; +let num = 5; + +console.log(numString + num); // "105" (string concatenation) +``` + +## 5. **Checking Data Types:** + +- Use `typeof` operator to check the data type of a variable. + +```javascript +let name = "John"; +console.log(typeof name); // "string" +``` + +Understanding these data types is crucial for effective programming in JavaScript. They help you organize and manipulate data in your applications. diff --git a/docs/languages/javascript/js-3.md b/docs/languages/javascript/js-3.md new file mode 100644 index 000000000..e4e32d381 --- /dev/null +++ b/docs/languages/javascript/js-3.md @@ -0,0 +1,344 @@ +--- +id: operator-in-javascript +sidebar_position: 3 +title: Operator in JavaScript +sidebar_label: Operator in JS +--- + +Operators are symbols that perform operations on operands. JavaScript supports various types of operators, including arithmetic, assignment, comparison, logical, and more. Let's explore some common operators used in JavaScript: + + + +## 1. **Arithmetic Operators:** + +Arithmetic operators are used to perform mathematical calculations. + +### Addition (`+`): + +The addition operator is used to add two operands. + +```javascript +let sum = 10 + 5; // sum = 15 +``` + +### Subtraction (`-`): + +The subtraction operator is used to subtract the second operand from the first. + +```javascript +let difference = 20 - 8; // difference = 12 +``` + +### Multiplication (`*`): + +The multiplication operator is used to multiply two operands. + +```javascript +let product = 5 * 4; // product = 20 +``` + +### Division (`/`): + +The division operator is used to divide the first operand by the second. + +```javascript +let quotient = 50 / 10; // quotient = 5 +``` + +### Modulus (`%`): + +The modulus operator returns the remainder of the division operation. + +```javascript +let remainder = 15 % 4; // remainder = 3 +``` + + + +## 2. **Assignment Operators:** + +Assignment operators are used to assign values to variables. + +### Assignment (`=`): + +The assignment operator assigns the value on the right to the variable on the left. + +```javascript +let x = 10; // x = 10 +``` + +### Addition Assignment (`+=`): + +The addition assignment operator adds the value on the right to the variable's current value. + +```javascript +let y = 5; +y += 3; // y = 8 +``` + +### Subtraction Assignment (`-=`): + +The subtraction assignment operator subtracts the value on the right from the variable's current value. + +```javascript +let z = 10; +z -= 2; // z = 8 +``` + + + +## 3. **Comparison Operators:** + +Comparison operators are used to compare two values. + +### Equal (`==`): + +The equal operator checks if two values are equal. But it does not consider the data type. + +```javascript +let isEqual = 5 == '5'; // isEqual = true +``` + +### Strict Equal (`===`): + +The strict equal operator checks if two values are equal and of the same data type. + +```javascript +let isStrictEqual = 5 === '5'; // isStrictEqual = false +``` + +### Not Equal (`!=`): + +The not equal operator checks if two values are not equal. + +```javascript +let isNotEqual = 10 != 5; // isNotEqual = true +``` + +### Greater Than (`>`): + +The greater than operator checks if the left operand is greater than the right operand. + +```javascript +let isGreaterThan = 15 > 10; // isGreaterThan = true +``` + +### Less Than (`<`): + +The less than operator checks if the left operand is less than the right operand. + +```javascript +let isLessThan = 5 < 10; // isLessThan = true +``` + + + +## 4. **Logical Operators:** + +Logical operators are used to combine multiple conditions. + +### Logical AND (`&&`): + +The logical AND operator returns `true` if both conditions are `true`. + +```javascript +let condition1 = true; +let condition2 = false; + +let result = condition1 && condition2; // result = false +``` + +### Logical OR (`||`): + +The logical OR operator returns `true` if at least one condition is `true`. + +```javascript +let condition1 = true; +let condition2 = false; + +let result = condition1 || condition2; // result = true +``` + +### Logical NOT (`!`): + +The logical NOT operator returns the opposite of the condition. + +```javascript +let condition = true; + +let result = !condition; // result = false +``` + + + +## 5. **Ternary Operator:** + +The ternary operator is a shorthand for an `if...else` statement. + +```javascript +let age = 20; + +let message = age >= 18 ? 'You can vote' : 'You are too young to vote'; +``` + +## 6. **Typeof Operator:** + +The `typeof` operator is used to determine the data type of a variable. + +```javascript +let num = 10; +let str = 'Hello, World!'; + +console.log(typeof num); // number +console.log(typeof str); // string +``` + +## 7. **Increment and Decrement Operators:** + +Increment (`++`) and decrement (`--`) operators are used to increase or decrease the value of a variable by `1`. + +```javascript +let count = 5; + +count++; // count = 6 +count--; // count = 5 +``` + + + +## 8. **Bitwise Operators:** + +Bitwise operators perform operations on binary representations of numbers. + +### Bitwise AND (`&`): + +Performs a bitwise AND operation on two numbers. + +```javascript +let result = 5 & 3; // result = 1 +``` + +### Bitwise OR (`|`): + +Performs a bitwise OR operation on two numbers. + +```javascript +let result = 5 | 3; // result = 7 +``` + +### Bitwise XOR (`^`): + +Performs a bitwise XOR operation on two numbers. + +```javascript +let result = 5 ^ 3; // result = 6 +``` + +### Bitwise NOT (`~`): + +Performs a bitwise NOT operation on a number. + +```javascript +let result = ~5; // result = -6 +``` + +### Left Shift (`<<`): + +Shifts the bits of a number to the left. + +```javascript +let result = 5 << 1; // result = 10 +``` + +### Right Shift (`>>`): + +Shifts the bits of a number to the right. + +```javascript +let result = 5 >> 1; // result = 2 +``` + +### Zero-fill Right Shift (`>>>`): + +Shifts the bits of a number to the right, filling the leftmost bits with zeros. + +```javascript +let result = 5 >>> 1; // result = 2 +``` + + + +## 9. **Conditional Operator:** + +The conditional operator (`?:`) is a ternary operator that evaluates a condition and returns one of two values based on the result. + +```javascript +let age = 20; + +let message = age >= 18 ? 'You can vote' : 'You are too young to vote'; +``` + + + +## 10. **Comma Operator:** + +The comma operator allows multiple expressions to be evaluated in a single statement. + +```javascript +let x = 1, y = 2, z = 3; +``` + +## 11. **Void Operator:** + +The void operator evaluates an expression and returns `undefined`. + +```javascript +let result = void 0; // result = undefined +``` + +## 12. **Delete Operator:** + +The delete operator is used to delete an object's property. + +```javascript +let person = { + name: 'John', + age: 30 +}; + +delete person.age; // Removes the 'age' property +``` + +## 13. **In Operator:** + +The `in` operator checks if a property exists in an object. + +```javascript +let person = { + name: 'John', + age: 30 +}; + +let hasAge = 'age' in person; // hasAge = true +``` + +## 14. **Instanceof Operator:** + +The `instanceof` operator checks if an object is an instance of a specific class. + +```javascript +let date = new Date(); + +let isDate = date instanceof Date; // isDate = true +``` + + + +## More Resources: + +- [MDN Web Docs: Expressions and Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators) +- [JavaScript Operator Precedence Table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) +- [W3Schools: JavaScript Operators](https://www.w3schools.com/js/js_operators.asp) +- [JavaScript.info: Operators](https://javascript.info/operators) + +Operators are an essential part of JavaScript programming. Understanding how to use them effectively will help you write more efficient and concise code. Experiment with different operators to see how they work and how you can use them in your projects. \ No newline at end of file diff --git a/docs/languages/javascript/js-4.md b/docs/languages/javascript/js-4.md new file mode 100644 index 000000000..a224c7080 --- /dev/null +++ b/docs/languages/javascript/js-4.md @@ -0,0 +1,87 @@ +--- +id: decision-making-in-javascript +sidebar_position: 4 +title: Decision Making in JavaScript +sidebar_label: Decision Making in JavaScript +--- + +Hey everyone! Today, we're going to explore how decision-making works in JavaScript. Whether you're just starting or need a refresher, this guide will help you understand the key decision-making structures in JavaScript. Let's dive right in! + + + + +* JavaScript provides several decision-making structures that allow you to execute code based on certain conditions. + +* The most common decision-making statements are `if`, `if-else`, `else if`, and `switch` statements. + +## 1. If Statements + + +The simplest structure for decision-making is an `if` statement, which executes a block of code if the specified condition is true. +```javascript +let num = 10; // Define a variable 'num' with a value of 10 +if (num > 0) { // Check if 'num' is greater than 0 + console.log('The number is positive.'); // Print a message if the condition is true +} +``` + + + +## 2. If-Else Statements + + +The `if-else` statement allows you to execute an alternate block of code if the `if` condition evaluates to false. +```javascript +let num = 7; // Define a variable 'num' with a value of 7 +if (num % 2 === 0) { // Check if 'num' is even + console.log('The number is even.'); // Print a message if the number is even +} else { // If the condition is false, execute the 'else' block + console.log('The number is odd.'); // Print a message if the number is odd +} +``` +## 3. Else If Statements + + +The `else if` statement allows you to check multiple conditions and execute different blocks of code based on the first condition that is true. +```javascript +let num = 15; // Define a variable 'num' with a value of 15 +if (num > 20) { // Check if 'num' is greater than 20 + console.log('The number is greater than 20.'); // Print this message if the condition is true +} else if (num === 15) { // Check if 'num' is equal to 15 + console.log('The number is 15.'); // Print this message if 'num' is 15 +} else { // If none of the above conditions are true, execute the 'else' block + console.log('The number is less than 20.'); // Print this message if 'num' is less than 20 +} +``` +## 4. Switch Statements + + +The `switch` statement allows you to perform different actions based on different conditions. It's an alternative to using multiple `else if` statements. +```javascript +let day = 3; // Define a variable 'day' with a value of 3 +switch (day) { // Switch based on the value of 'day' + case 1: // Check if 'day' is equal to 1 + console.log('Monday'); // Print 'Monday' if 'day' is 1 + break; // Break out of the switch after this case + case 2: // Check if 'day' is equal to 2 + console.log('Tuesday'); // Print 'Tuesday' if 'day' is 2 + break; // Break out of the switch after this case + case 3: // Check if 'day' is equal to 3 + console.log('Wednesday'); // Print 'Wednesday' if 'day' is 3 + break; // Break out of the switch after this case + default: // If none of the cases match, execute the default block + console.log('Invalid day'); // Print 'Invalid day' if 'day' doesn't match any case +} +``` + + + +## 5. Ternary Operator + + +The ternary operator is a shorthand for the `if-else` statement and is commonly used for simple conditional expressions. +```javascript +let age = 18; // Define a variable 'age' with a value of 18 +let canVote = (age >= 18) ? 'Yes' : 'No'; // Use the ternary operator to check if 'age' is 18 or more +console.log(canVote); // Print 'Yes' if 'age' is 18 or more, otherwise print 'No' +``` diff --git a/docs/languages/javascript/js-5.md b/docs/languages/javascript/js-5.md new file mode 100644 index 000000000..1a48fc930 --- /dev/null +++ b/docs/languages/javascript/js-5.md @@ -0,0 +1,127 @@ +--- +id: loops-in-javascript +sidebar_position: 5 +title: Loops in JavaScript +sidebar_label: Loops in JavaScript +--- + +Hey everyone! Today, we will explore loops in JavaScript, a key concept for automating repetitive tasks. Whether you're just starting or need a quick refresher, this guide will help you understand how loops work in JavaScript. Let's get started! + + + +* Loops allow you to execute a block of code repeatedly while a specified condition is true. + +* JavaScript provides several types of loops, such as `for`, `while`, and `do-while` loops. + +## 1. For Loop + +The `for` loop is the most commonly used loop in JavaScript. It repeats a block of code for a set number of times. +```javascript +for (let i = 0; i < 5; i++) { // Loop from 0 to 4 + console.log(i); // Print the current value of 'i' +} +``` + +## 2. For-In Loop + +The `for-in` loop is used to iterate over the properties of an object. +```javascript +let person = {name: 'John', age: 30}; // Object with 'name' and 'age' properties +for (let key in person) { // Iterate over each property in the 'person' object + console.log(key + ': ' + person[key]); // Print the property and its value +} +``` + + + +## 3. For-Of Loop + +The `for-of` loop is used to iterate over iterable objects like arrays or strings. +```javascript +let numbers = [1, 2, 3, 4, 5]; // Array of numbers +for (let num of numbers) { // Iterate over each number in the 'numbers' array + console.log(num); // Print the current number +} +``` + +## 4. While Loop + +The `while` loop executes a block of code as long as the specified condition is true. +```javascript +let count = 0; // Initialize 'count' to 0 +while (count < 5) { // Continue looping while 'count' is less than 5 + console.log(count); // Print the current value of 'count' + count++; // Increment 'count' by 1 +} +``` + + + +## 5. Do-While Loop + +The `do-while` loop is similar to the `while` loop but ensures the code is executed at least once before checking the condition. +```javascript +let count = 0; // Initialize 'count' to 0 +do { // Execute the loop body at least once + console.log(count); // Print the current value of 'count' + count++; // Increment 'count' by 1 +} while (count < 5); // Continue looping while 'count' is less than 5 +``` + +## 6. Break Statement + +The `break` statement is used to exit a loop prematurely. +```javascript +for (let i = 0; i < 10; i++) { // Loop from 0 to 9 + if (i === 5) { // Check if 'i' equals 5 + break; // Exit the loop when 'i' is 5 + } + console.log(i); // Print numbers from 0 to 4 +} +``` + +## 7. Continue Statement + +The `continue` statement skips the current iteration of the loop and moves to the next iteration. +```javascript +for (let i = 0; i < 5; i++) { // Loop from 0 to 4 + if (i === 3) { // Check if 'i' equals 3 + continue; // Skip the iteration when 'i' is 3 + } + console.log(i); // Print numbers except 3 +} +``` + +## 8. Nested Loops + +In JavaScript, you can use loops inside other loops. These are called nested loops and are useful for iterating over multi-dimensional arrays. +```javascript +for (let i = 1; i <= 3; i++) { // Outer loop from 1 to 3 + for (let j = 1; j <= 2; j++) { // Inner loop from 1 to 2 + console.log(`i: ${i}, j: ${j}`); // Print the values of 'i' and 'j' + } +} +``` + + + +## 9. Loop Control Statements + +Loop control statements allow you to control the flow of loops. Here are some common loop control statements in JavaScript: + +* `break`: Exits the loop immediately. +* `continue`: Skips the current iteration and moves to the next one. +* `return`: Exits the loop and the enclosing function. + +## 10. Infinite Loops + +An infinite loop is a loop that runs indefinitely. It occurs when the loop condition is always true or the loop lacks an exit condition. +```javascript +while (true) { // Infinite loop + console.log('This is an infinite loop!'); +} +``` + +## Conclusion + +Loops are essential for automating repetitive tasks in JavaScript. By using loops effectively, you can iterate over data structures, perform calculations, and execute code based on conditions. Practice writing loops to enhance your programming skills and build efficient applications. \ No newline at end of file diff --git a/docs/languages/javascript/js-6.md b/docs/languages/javascript/js-6.md new file mode 100644 index 000000000..e77d6d7f2 --- /dev/null +++ b/docs/languages/javascript/js-6.md @@ -0,0 +1,100 @@ +--- +id: type-casting-in-javascript +sidebar_position: 6 +title: Type Casting in JavaScript +sidebar_label: Type Casting in JavaScript +--- + +Hey everyone! Today, we will explore Type Casting in JavaScript, an essential concept for converting data types and ensuring smooth operations in your code. Whether you're a beginner or just need a quick refresher, this guide will help you understand how to effectively change between different types in JavaScript. Let's dive in! + + + +## Q. Why do we need Type Casting? + +* **JavaScript** is a loosely-typed language, meaning variables aren't tied to any specific data type. +* However, there are scenarios where you'll need to change the type of a variable to perform certain operations. +* Hence, type casting is essential for accurate, efficient, and error-free handling of data in JavaScript applications. + +## Types of Type Casting - + +JavaScript supports two types of type casting: + 1. Implicit Type Casting (Type Coercion) + 2. Explicit Type Casting + +```mermaid +graph TD + A["Type Conversion"] --> B["Implicit Conversion"] + A --> C["Explicit Conversion"] + + style A fill:#f57,stroke:#333,stroke-width:2px; + style B fill:#fdfd96,stroke:#333,stroke-width:2px; + style C fill:#fdfd96,stroke:#333,stroke-width:2px; +``` + +### 1. Implicit Type Casting : + +- Also known as **Type Coercion** +- In implicit type casting, JavaScript automatically converts one data type to another. +- This happens when you perform operations between values of different types, and JavaScript tries to make them compatible. +- Example: + +```javascript +let result = '5' + 3; // "53" (number 3 is converted to string) +let difference = '10' - 2; // 8 (string "10" is converted to number) +let truthy = '5' == 5; // true (type coercion between string and number) +``` + +- Explanation: + - In the first example, JavaScript converts the `number` `3` to a `string` before concatenating it with `"5"`. + - In the second example, `"10"` (`string`) is automatically converted to a `number` to perform subtraction. + - In the third example, JavaScript compares a `string` and a `number` by converting the `string` to a `number`. + +### 2. Explicit Type Casting : + +Unlike implicit type casting, explicit type casting requires you to manually convert a value from one type to another. JavaScript provides built-in methods to facilitate this process. + +**Common Methods for Explicit Type Casting with Examples:** + +1. `Number()` – Converts a value to a number. + +```javascript +// Converting string to number +let strNum = '42'; +let num = Number(strNum); // 42 +``` + +2. `Boolean()` – Converts a value to a boolean ( true or false ). + +```javascript +// Converting string to boolean +let strBool = ''; +let boolValue = Boolean(strBool); // false (empty string is falsy) +``` + +3. `ParseInt()` – Parse a string and return an integer. + +```javascript +// Converting string to integer +let decimalString = '3.14'; +let intValue = parseInt(decimalString); // 3 (truncates decimal part) +``` + +4. `ParseFloat()` – Parse a string and return a float + +```javascript +// Converting string to integer +let decimalString = '4.48'; +let floatValue = parseFloat(decimalString); // 4.48 +``` + +5. `String()` – Converts a value to a string. + +```javascript +// Converting number to string +let numberValue = 100; +let str = String(numberValue); // "100" +``` + +## Conclusion + +Type casting is a crucial aspect of JavaScript programming, allowing you to convert data types for seamless operations. By understanding implicit and explicit type casting, you can handle data effectively and ensure your code runs smoothly. Practice these concepts to enhance your programming skills and build robust applications. \ No newline at end of file diff --git a/docs/languages/javascript/js-7.md b/docs/languages/javascript/js-7.md new file mode 100644 index 000000000..bc55ee4b5 --- /dev/null +++ b/docs/languages/javascript/js-7.md @@ -0,0 +1,141 @@ +--- +id: arrays-in-javascript +sidebar_position: 7 +title: Arrays in JavaScript +sidebar_label: Arrays in JavaScript +--- + +Hey everyone! Today, we're diving into Arrays in JavaScript, one of the most fundamental and powerful data structures. Let's jump in and explore the different ways arrays can be used to store, manipulate, and access data! + + + +## What is an Array? + +- An `array` in JavaScript is a special type of `object` used to store multiple values in a single variable. +- Arrays can hold a collection of items, such as *numbers*, *strings*, *objects*, or even *other arrays*. +- Each element in an array is stored at a specific `index`, starting from `0`, which allows for easy access and manipulation of the data. + +## Key Features of Arrays: + +- Arrays can hold values of different data types. +- They have a *dynamic size*, meaning elements can be added or removed. +- Elements are accessed via their `index`, starting from `0`. + +## Example of an Array: + +```javascript +let fruits = ['apple', 'banana', 'cherry']; // array of fruits +console.log(fruits[0]); // Output: 'apple' +console.log(fruits[2]); // Output: 'cherry' +``` +In this example, the array `fruits` contains three string elements, and we access the first and third items using their indices. + + + +## Visual representation: + +![image](https://github.com/user-attachments/assets/01a5cd05-4975-4ee4-af4b-2e16741d5a54) + + +## Array methods: + +1. `Push()`: add item to end +2. `Pop()`: delete item from start and return +3. `toString()`: converts array to `String` +4. `Concat()` : joins multiple arrays & returns result +5. `Unshift()` : add item to start +6. `shift()` : delete item from start & return +7. `Slice()` : returns a piece of the array slice( startldx, endldx ) +8. `Splice()` : change original array (add, remove, replace) splice( startldx, delCount, newE11... ) + +## Array Iteration Methods: + +### 1. `forEach()`: +- The `forEach()` method calls a function (a callback function) once for each array element. +- Example: +```javascript +const numbers = [45, 4, 9, 16, 25]; +numbers.forEach((element)=>{ + console.log(element); +}); +``` +- Note: the function takes 3 arguments: + - The item value + - The item index + - The array itself + +### 2. `map()`: + +- The `map()` method creates a new array by performing a function on each array element. +- The `map()` method does not execute the function for array elements without values. +- The `map()` method does not change the original array. + +- **Example:** +```javascript +const numbers = [45, 4, 9, 16, 25]; +numbers.map((element)=>{ + console.log(element); +}); +``` + +### 3. `filter()`: + +- The `filter()` method creates a new array with array elements that pass a test. +- Example: +```javascript +const numbers = [45, 4, 9, 16, 25]; +const over18 = numbers.filter(myFunction); + +function myFunction(value, index, array) { + return value > 18; +} +``` + +### 4. `reduce()`: + +- The `reduce()` method reduces the array to a single value. +- The `reduce()` method executes a provided function for each value of the array (from left-to-right). + +- **Example:** +```javascript +const numbers = [45, 4, 9, 16, 25]; +const sum = numbers.reduce(myFunction); + +function myFunction(total, value, index, array) { + return total + value; +} +``` + +### 5. `find()`: + +- The `find()` method returns the value of the first array element that passes a test function. +- The `find()` method returns `undefined` if no elements pass the test. +- Example: +```javascript +const numbers = [45, 4, 9, 16, 25]; +const first = numbers.find(myFunction); + +function myFunction(value, index, array) { + return value > 18; +} +``` + + + +### 6. `findIndex()`: + +- The `findIndex()` method returns the index of the first array element that passes a test function. +- The `findIndex()` method returns `-1` if no elements pass the test. +- Example: +```javascript +const numbers = [45, 4, 9, 16, 25]; +const first = numbers.findIndex(myFunction); + +function myFunction(value, index, array) { + return value > 18; +} +``` + +## Conclusion: + +Arrays are a versatile and powerful data structure in JavaScript, allowing you to store, manipulate, and access multiple values efficiently. By understanding the key features and methods of arrays, you can leverage them to build complex applications and solve a wide range of problems. \ No newline at end of file diff --git a/docs/languages/javascript/js-8.md b/docs/languages/javascript/js-8.md new file mode 100644 index 000000000..5cb1b9b23 --- /dev/null +++ b/docs/languages/javascript/js-8.md @@ -0,0 +1,103 @@ +--- +id: functions-in-javascript +sidebar_position: 8 +title: Functions in JavaScript +sidebar_label: Functions in JS +--- + +A function in JavaScript is similar to a procedure—a set of statements that performs a task or calculates a value, but for a procedure to qualify as a function, it should take some input and return an output where there is some obvious relationship between the input and the output. + + + +## **Functions Declaration** + +Function Declarations also known as function statement or function definition consists of function keyword, function name, parameters separated by commas and function body enclosed by curly braces ```{ /*function body*/ }``` + + +```javascript +function printName(name) { + return name; +} +``` + +In the example above, the function ```printName``` takes one parameter called ```name```. The function body consist of one statement that returns the name. + + + +## **Function Expressions** + +Function expressions are a way to define a function as part of an expression. Unlike function declarations, which define a function with a name, function expressions can be anonymous (without a name) or named. + +## 1. **Anonymous Function Expression** +An anonymous function expression is a function that doesn't have a name. It can be assigned to a variable, passed as an argument to another function, or returned from another function. + +```javascript +const greet = function() { + console.log("Hello!"); +}; + +greet(); +``` + +## 2. **Named Function Expression** +A named function expression includes a name. This can be useful for recursion or for better debugging. + +```javascript +const greet = function sayHello() { + console.log("Hello!"); +}; + +greet(); +``` + +## 3. **IIFE (Immediately Invoked Function Expression)** +An IIFE is a function that runs as soon as it is defined. It’s often used to create a local scope. + +```javascript +(function() { + console.log("This runs immediately!"); +})(); +``` + + + +## **Function Call** + +Calling a function means executing the code defined within it. There are various ways to call a function. + +```javascript +const greet = function(name) { + console.log("Hello ", name); +}; + +greet("World!"); //Output: Hello World! +``` + +The above example is calling a function with argument + + +```javascript +const obj = { + greet: function() { + console.log("Hello from an object!"); + } +}; + +obj.greet(); // Output: Hello from an object! +``` + +The above example is calling a method of an object + +```javascript +const multiply = (x, y) => x * y; + +console.log(multiply(2, 3)); // Output: 6 +``` + +The above example is of calling an arrow function + + +## More Resources: + +- [MDN Web Docs: Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions) +- [W3Schools: JavaScript Functions](https://www.w3schools.com/js/js_functions.asp) diff --git a/docs/languages/javascript/js-9.md b/docs/languages/javascript/js-9.md new file mode 100644 index 000000000..3e1e1eb87 --- /dev/null +++ b/docs/languages/javascript/js-9.md @@ -0,0 +1,83 @@ +--- +id: recursion-in-javascript +sidebar_position: 9 +title: Recursion in JavaScript +sidebar_label: Recursion in JavaScript +--- + +Recursion is a powerful concept in programming where a function calls itself to solve smaller instances of the same problem. This approach is especially useful for tasks that can be broken down into similar sub-tasks, such as traversing trees, calculating factorials, or working with recursive data structures like nested arrays. + + + +## What is Recursion? + +In JavaScript, recursion occurs when a function calls itself until it reaches a base condition, at which point it stops calling itself and returns a value. + +## Key Concepts: +1. **Base Case**: The condition under which the recursion stops. +2. **Recursive Case**: The function calls itself with a modified argument, moving toward the base case. + +## Example: Factorial Function + +```javascript +function factorial(n) { + if (n === 0) { // Base case + return 1; + } + return n * factorial(n - 1); // Recursive case +} + +console.log(factorial(5)); // Output: 120 +``` + + + +## Visualizing Recursion + +Recursion can be visualized as a series of function calls, each building on the previous one until the base case is reached. + +```mermaid +graph TD + subgraph Recursion + style Recursion fill:#f57,stroke:#333,stroke-width:2px, stroke:#262626; + A(Recursion) + end + + B["Base Case"] + C["Recursive Case"] + + A -->|Stops| B + A -->|Calls Itself| C +``` + +In the example above, the `factorial` function calculates the factorial of a number by calling itself with a modified argument until it reaches the base case (`n === 0`). + +## Benefits of Recursion: + +1. **Simplicity**: Recursion can simplify complex problems by breaking them down into smaller, more manageable sub-problems. +2. **Readability**: Recursive solutions often mirror the problem's description, making the code easier to understand. +3. **Versatility**: Recursion can be applied to a wide range of problems, from mathematical calculations to tree traversal. +4. **Efficiency**: In some cases, recursive solutions can be more efficient than iterative ones. + +## Considerations: + +1. **Base Case**: Ensure that the base case is well-defined and reachable to prevent infinite recursion. +2. **Stack Usage**: Recursion consumes stack space for each function call, which can lead to stack overflow errors for deeply nested calls. +3. **Performance**: Recursive solutions may not always be the most performant due to the overhead of function calls. + +By understanding recursion and its applications, you can leverage this powerful technique to solve a variety of problems in JavaScript and other programming languages. + +```javascript +function factorial(n) { + if (n === 0) { // Base case + return 1; + } + return n * factorial(n - 1); // Recursive case +} + +console.log(factorial(5)); // Output: 120 +``` + +## Conclusion + +Recursion is a fundamental concept in programming that enables elegant solutions to complex problems. By mastering recursion, you can write concise, efficient code that leverages the power of self-referential functions to solve a wide range of tasks. Practice implementing recursive solutions to enhance your problem-solving skills and deepen your understanding of JavaScript. \ No newline at end of file diff --git a/docs/languages/python/_category_.json b/docs/languages/python/_category_.json new file mode 100644 index 000000000..7eb205535 --- /dev/null +++ b/docs/languages/python/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Python", + "position": 3, + "link": { + "type": "generated-index", + "description": "Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991, Python's design philosophy emphasizes code readability with its notable use of significant whitespace." + } + } \ No newline at end of file diff --git a/docs/languages/python/py-1.md b/docs/languages/python/py-1.md new file mode 100644 index 000000000..5efae6cb2 --- /dev/null +++ b/docs/languages/python/py-1.md @@ -0,0 +1,179 @@ +--- +id: datatypes-in-python +sidebar_position: 2 +title: Datatypes in Python +sidebar_label: Datatypes in Python +--- + +Hey there! In this guide, we'll explore the different data types available in Python. Understanding data types is crucial for writing efficient and clear Python code. Let's dive in! + +# Python Data Types + +* Python provides several built-in data types that allow you to work with different kinds of data. +* These data types can be categorized as primitive or non-primitive. + +## 1. Primitive Data Types + +### a. Integers (`int`) +- Represents whole numbers, both positive and negative. +```python +x = 4 +y = -21 +``` + +### b. Floating-Point Numbers (`float`) +- Represents real numbers with a decimal point. +```python +x = 6.3 +y = -5.2 +``` + +### c. Complex Numbers (`complex`) +- Represents complex numbers with a real and imaginary part. +```python +x = 1 + 2j +y = 3 - 4j +``` + +### d. Boolean (`bool`) +- Represents truth values, either `True` or `False`. +```python +is_python_fun = True +is_sky_green = False +``` + +### e. Strings (`str`) +- Represents a sequence of characters enclosed in quotes. +```python +name = "Python" +greeting = 'Hello, World!' +``` + +## 2. Non-Primitive Data Types + +### a. Lists (`list`) +- Ordered, mutable collections of elements. +```python +numbers = [1, 2, 3, 4, 5] +mixed = [1, "orange", True, 4.5] +``` + +### b. Tuples (`tuple`) +- Ordered, immutable collections of elements. +```python +coordinates = (30, 20) +empty_tuple = () +``` + +### c. Sets (`set`) +- Unordered, mutable collections of unique elements. +```python +unique_numbers = {1, 2, 3, 4, 5} +``` + +### d. Dictionaries (`dict`) +- Unordered collections of key-value pairs. +```python +person = {"name": "John Wick", "age": 60, "city": "New York"} +``` + +## 3. Type Conversion +You can convert between data types using built-in functions: +- `int()` +- `float()` +- `str()` +- `bool()` +- `list()` +- `tuple()` +- `set()` + +### a.Integer to String : + +```python +# Example +num = 10 +num_str = str(num) +print(num_str) # Output: '10' +print(type(num_str)) # Output: +``` + +### b.String to Integer : + +```python +num_str = "123" +num = int(num_str) +print(num) # Output: 123 +print(type(num)) # Output: +``` +### c.String to Float : + +```python +num_str = "12.34" +num = float(num_str) +print(num) # Output: 12.34 +print(type(num)) # Output: +``` + +### d.Float to Integer : + +```python +num = 12.56 +num_int = int(num) +print(num_int) # Output: 12 +print(type(num_int)) # Output: +``` +### e.List to Tuple : + +```python +my_list = [1, 2, 3] +my_tuple = tuple(my_list) +print(my_tuple) # Output: (1, 2, 3) +print(type(my_tuple)) # Output: +``` + +### f.Tuple to List : + +```python +my_tuple = (4, 5, 6) +my_list = list(my_tuple) +print(my_list) # Output: [4, 5, 6] +print(type(my_list)) # Output: +``` +### g.List to Set : + +```python +my_list = [1, 2, 2, 3] +my_set = set(my_list) +print(my_set) # Output: {1, 2, 3} +print(type(my_set)) # Output: +``` + +### h.Set to List : + +```python +my_set = {4, 5, 6} +my_list = list(my_set) +print(my_list) # Output: [4, 5, 6] +print(type(my_list)) # Output: +``` + +### i.Boolean to Integer : + +```python +val = True +val_int = int(val) +print(val_int) # Output: 1 +print(type(val_int)) # Output: +``` + +### j.Integer to Boolean : + +```python +num = 0 +bool_val = bool(num) +print(bool_val) # Output: False +print(type(bool_val)) # Output: +``` +--- + +These data types are the foundation of Python, and understanding them is key to writing efficient and clear Python code. diff --git a/docs/languages/python/py-10.md b/docs/languages/python/py-10.md new file mode 100644 index 000000000..4fc3c4195 --- /dev/null +++ b/docs/languages/python/py-10.md @@ -0,0 +1,86 @@ +--- +id: defaultdict-and-counter-in-python +sidebar_position: 10 +title: defaultdict and Counter in Python +sidebar_label: defaultdict & Counter in Python +--- + +Hey everyone! Today we are going to dive into two powerful utilities in Python's `collections` module – `defaultdict` and `Counter`. These data structures can significantly simplify certain tasks, especially when working with dictionaries and counting elements. Let's explore how they work and their advantages. +# defaultdict in Python + + +* `defaultdict` is a subclass of Python's built-in `dict` class. + +* It overrides the default behavior of the `dict` class by providing a default value for a nonexistent key. + +This is particularly useful when you want to avoid `KeyError` exceptions. +## 1. Using defaultdict + + +To use `defaultdict`, you must import it from the `collections` module: +```python +from collections import defaultdict # Importing defaultdict from collections module + +# Example: Counting occurrences of letters in a word +word = 'programming' # Define a word +letter_count = defaultdict(int) # Create defaultdict with default value as int (0) + +for letter in word: # Iterate over each letter in the word + letter_count[letter] += 1 # Increment the count of each letter + +print(letter_count) # Output: defaultdict(, {'p': 1, 'r': 2, 'o': 1, 'g': 2, 'a': 1, 'm': 2, 'i': 1, 'n': 1}) +``` +## 2. Advantages of defaultdict + + +Here are some of the key advantages of using `defaultdict`: +- **Avoids KeyError**: You don't have to check whether a key exists before using it. +- **Simplifies code**: Reduces the need for conditional logic to handle missing keys. +- **Customizable defaults**: You can define any default factory function (like `int`, `list`, `str`, etc.). +# Counter in Python + + +* `Counter` is a subclass of `dict` designed to count hashable objects like elements in a list or characters in a string. + +* It makes it easy to tally occurrences without writing manual loops. +## 1. Using Counter + + +To use `Counter`, you must also import it from the `collections` module: +```python +from collections import Counter # Importing Counter from collections module + +# Example: Counting the frequency of characters in a word +word = 'banana' # Define a word +char_count = Counter(word) # Create Counter to count characters in the word + +print(char_count) # Output: Counter({'a': 3, 'n': 2, 'b': 1}) +``` +## 2. Advantages of Counter + + +Here are some of the key advantages of using `Counter`: +- **Efficient counting**: Automatically counts elements without explicit loops. +- **Built-in operations**: Supports common tasks like finding the most common elements (`most_common()`). +- **Works with all iterables**: Can be used with strings, lists, tuples, and more. +## 3. Common Counter Methods + + +Here are a few useful methods provided by the `Counter` class: +```python +# Example: Using the most_common() method +from collections import Counter # Importing Counter + +word = 'mississippi' # Define a word +char_count = Counter(word) # Create Counter for character count + +# Get the two most common characters +print(char_count.most_common(2)) # Output: [('i', 4), ('s', 4)] + +# Example: Subtracting counts using subtract() +other_word = 'issippi' # Define another word +other_count = Counter(other_word) # Create Counter for second word + +char_count.subtract(other_count) # Subtract counts from the second Counter +print(char_count) # Output: Counter({'m': 1, 'i': 1, 's': 0, 'p': 0}) +``` \ No newline at end of file diff --git a/docs/languages/python/py-11.md b/docs/languages/python/py-11.md new file mode 100644 index 000000000..953a8815d --- /dev/null +++ b/docs/languages/python/py-11.md @@ -0,0 +1,96 @@ +--- +id: usage-of-lists-in-python +sidebar_position: 11 +title: Lists in Python +sidebar_label: Lists in Python +--- + +Hey there! In this guide, we'll explore lists in Python. Lists are ordered, mutable collections of elements that allow you to store and manipulate data efficiently. Let's dive in! + +--- + +## Python Lists + +- **Ordered**: Elements have a defined order and can be accessed via indices. +- **Mutable**: Lists can be modified after creation (add, remove, or change elements). + +- **Heterogeneous**: Lists can store elements of different data types (e.g., integers, strings, booleans). + +- **Supports nesting**: Lists can contain other lists as elements (nested lists). +- **Dynamic sizing**: Lists can grow or shrink as you add or remove elements. + +- **Common methods**: Includes methods like `append()`, `extend()`, `insert()`, `pop()`, `remove()`, `sort()`, and `reverse()`. + +--- + +## 1. Creating a List + +You can create a list using square brackets `[]` or the `list()` function. + +```python +my_list = [1, 2, 3, 4, 5] # Create a list using square brackets +another_list = list(('apple', 'banana', 'cherry')) # Create a list using the list() function +print(my_list) # Output: [1, 2, 3, 4, 5] +print(another_list) # Output: ['apple', 'banana', 'cherry'] +``` + +## 2. Accessing Elements + +You can access elements in a list using their index. Python uses zero-based indexing. + +```python +my_list = [10, 20, 30, 40, 50] +print(my_list[0]) # Access the first element, Output: 10 +print(my_list[3]) # Access the fourth element, Output: 40 +``` + +## 3. Adding Elements + +You can add new elements to a list using methods like `append()`, `insert()`, or `extend()`. + +```python +my_list = [1, 2, 3] +my_list.append(4) # Add an element to the end of the list +print(my_list) # Output: [1, 2, 3, 4] + +my_list.insert(1, 5) # Insert an element at index 1 +print(my_list) # Output: [1, 5, 2, 3, 4] + +another_list = [6, 7] +my_list.extend(another_list) # Extend the list by adding elements from another list +print(my_list) # Output: [1, 5, 2, 3, 4, 6, 7] +``` + +## 4. Removing Elements + +You can remove elements from a list using `remove()`, `pop()`, or `del`. + +```python +my_list = [1, 2, 3, 4, 5] +my_list.remove(3) # Remove the first occurrence of a value +print(my_list) # Output: [1, 2, 4, 5] + +popped_element = my_list.pop(1) # Remove and return the element at index 1 +print(popped_element) # Output: 2 +print(my_list) # Output: [1, 4, 5] + +del my_list[0] # Delete the element at index 0 +print(my_list) # Output: [4, 5] +``` + +## 5. List Methods + +Lists have several built-in methods for manipulation. + +```python +my_list = [3, 1, 4, 2, 5] + +my_list.sort() # Sort the list in ascending order +print(my_list) # Output: [1, 2, 3, 4, 5] + +my_list.reverse() # Reverse the order of the list +print(my_list) # Output: [5, 4, 3, 2, 1] + +length = len(my_list) # Get the length of the list +print(length) # Output: 5 +``` diff --git a/docs/languages/python/py-12.md b/docs/languages/python/py-12.md new file mode 100644 index 000000000..e548c5926 --- /dev/null +++ b/docs/languages/python/py-12.md @@ -0,0 +1,75 @@ +--- +id: usage-of-tuples-in-python +sidebar_position: 12 +title: Tuples in Python +sidebar_label: Tuples in Python +--- + +Hey there! In this guide, we'll explore tuples in Python. Tuples are ordered, immutable collections of elements that allow you to store and manipulate data efficiently. Let's dive in! + +--- + +## Python Tuples + +- **Ordered**: Elements have a defined order and can be accessed via indices. +- **Immutable**: Once created, elements in a tuple cannot be changed. +- **Heterogeneous**: Tuples can store elements of different data types (e.g., integers, strings, booleans). +- **Supports nesting**: Tuples can contain other tuples or lists as elements. + +--- + +## 1. Creating a Tuple + +You can create a tuple using parentheses `()` or the `tuple()` function. + +```python +my_tuple = (1, 2, 3, 4, 5) # Create a tuple using parentheses +another_tuple = tuple(('apple', 'banana', 'cherry')) # Create a tuple using the tuple() function +print(my_tuple) # Output: (1, 2, 3, 4, 5) +print(another_tuple) # Output: ('apple', 'banana', 'cherry') +``` + +## 2. Accessing Elements + +You can access elements in a tuple using their index. Python uses zero-based indexing. + +```python +my_tuple = (10, 20, 30, 40, 50) +print(my_tuple[0]) # Access the first element, Output: 10 +print(my_tuple[3]) # Access the fourth element, Output: 40 +``` + +## 3. Unpacking Tuples + +You can unpack a tuple by assigning its elements to multiple variables. + +```python +my_tuple = (1, 2, 3) +a, b, c = my_tuple # Unpacking tuple elements +print(a) # Output: 1 +print(b) # Output: 2 +print(c) # Output: 3 +``` + +## 4. Tuple Methods + +Tuples have only two built-in methods: `count()` and `index()`. + +```python +my_tuple = (1, 2, 2, 3, 4, 2) + +count_of_twos = my_tuple.count(2) # Count the number of occurrences of a value +print(count_of_twos) # Output: 3 + +index_of_three = my_tuple.index(3) # Get the index of the first occurrence of a value +print(index_of_three) # Output: 3 +``` + +## 5. Nested Tuples + +Tuples can contain other tuples or lists as elements. + +```python +nested_tuple = (1, (2, 3), [4, 5]) # A tuple with a nested tuple and a list +print(nested_tuple) # Output: (1, (2, 3), [4, 5]) +``` diff --git a/docs/languages/python/py-13.md b/docs/languages/python/py-13.md new file mode 100644 index 000000000..f074f4fb2 --- /dev/null +++ b/docs/languages/python/py-13.md @@ -0,0 +1,89 @@ +--- +id: usage-of-strings-in-python +sidebar_position: 13 +title: Strings in Python +sidebar_label: Strings in Python +--- + +Hey there! In this guide, we'll explore strings in Python. Strings are sequences of characters that allow you to store and manipulate text efficiently. Let's dive in! + +--- + +## Python Strings + +- **Immutable**: Strings are immutable, meaning that once created, their contents cannot be changed. +- **Indexed**: Strings are ordered collections of characters, and you can access individual characters using their index. +- **Supports concatenation**: You can concatenate strings using the `+` operator. +- **Supports various methods**: Python provides many built-in methods to manipulate strings. + +--- + +## 1. Creating a String + +You can create a string using single quotes `'`, double quotes `"`, or triple quotes `'''` or `"""` for multi-line strings. + +```python +my_string = 'Hello, World!' # Create a string using single quotes +another_string = "Python is awesome!" # Create a string using double quotes +multi_line_string = '''This is a +multi-line string.''' # Create a string using triple quotes + +print(my_string) # Output: Hello, World! +print(another_string) # Output: Python is awesome! +print(multi_line_string) # Output: This is a + # multi-line string. +``` + +## 2. Accessing Characters + +You can access characters in a string using their index. Python uses zero-based indexing. + +```python +my_string = "Hello, World!" +print(my_string[0]) # Access the first character, Output: H +print(my_string[7]) # Access the eighth character, Output: W +``` + +## 3. String Methods + +Python provides various built-in methods to manipulate strings. + +```python +my_string = "Python" + +length = len(my_string) # Get the length of the string +print(length) # Output: 6 + +upper_string = my_string.upper() # Convert to uppercase +print(upper_string) # Output: PYTHON + +lower_string = my_string.lower() # Convert to lowercase +print(lower_string) # Output: python + +replaced_string = my_string.replace("P", "J") # Replace a substring +print(replaced_string) # Output: Jython +``` + +## 4. String Concatenation + +You can concatenate strings using the `+` operator. + +```python +string1 = "Hello" +string2 = "World" +combined_string = string1 + ", " + string2 + "!" # Concatenate strings +print(combined_string) # Output: Hello, World! +``` + +## 5. String Slicing + +You can slice a string to get a substring. + +```python +my_string = "Hello, World!" +substring = my_string[0:5] # Get a substring +print(substring) # Output: Hello + +substring2 = my_string[7:] # Get substring from index 7 to end +print(substring2) # Output: World! +``` diff --git a/docs/languages/python/py-14.md b/docs/languages/python/py-14.md new file mode 100644 index 000000000..9a4882b71 --- /dev/null +++ b/docs/languages/python/py-14.md @@ -0,0 +1,77 @@ +--- +id: usage-of-modules-in-python +sidebar_position: 14 +title: Modules in Python +sidebar_label: Modules in Python +--- + +Hey there! In this guide, we'll explore modules in Python. Modules are files containing Python code that can define functions, classes, and variables. They allow you to organize your code logically and reuse code across different programs. Let's dive in! + +--- + +## Python Modules + +- **Code Organization**: Modules help organize code into manageable sections, making it easier to maintain. +- **Reusability**: You can reuse code in multiple programs without rewriting it. +- **Standard Library**: Python comes with a standard library of modules that provide useful functions and tools. + +--- + +## 1. Creating a Module + +You can create a module by simply creating a new Python file (with a `.py` extension) and defining functions or variables in it. + +```python +# my_module.py +def greet(name): + return f"Hello, {name}!" + +PI = 3.14159 +``` + +## 2. Importing a Module + +You can import a module using the `import` statement. You can import the entire module or specific functions or variables. + +```python +import my_module # Import the entire module +from my_module import greet # Import specific function + +print(my_module.PI) # Output: 3.14159 +print(greet("Alice")) # Output: Hello, Alice! +``` + +## 3. Importing with Aliases + +You can give a module or function an alias using the `as` keyword to simplify its usage. + +```python +import my_module as mm + +print(mm.PI) # Output: 3.14159 +print(mm.greet("Bob")) # Output: Hello, Bob! +``` + +## 4. The `__name__` Variable + +The `__name__` variable allows you to check if a module is being run as the main program or if it is being imported. + +```python +# my_module.py +def greet(name): + return f"Hello, {name}!" + +if __name__ == "__main__": + print(greet("Main")) # This code runs only if the module is executed directly +``` + +## 5. Using Standard Library Modules + +Python's standard library provides many built-in modules you can use in your programs. + +```python +import math + +print(math.sqrt(16)) # Output: 4.0 +print(math.pi) # Output: 3.141592653589793 +``` diff --git a/docs/languages/python/py-15.md b/docs/languages/python/py-15.md new file mode 100644 index 000000000..b1f1689ff --- /dev/null +++ b/docs/languages/python/py-15.md @@ -0,0 +1,119 @@ +--- +id: usage-of-decorators-in-python +sidebar_position: 15 +title: Decorators in Python +sidebar_label: Decorators in Python +--- + +Hey there! In this guide, we'll explore decorators in Python. Decorators are a powerful and flexible way to modify the behavior of functions or methods. They allow you to add functionality to existing code in a clean and readable way. Let's dive in! + +--- + +## Python Decorators + +- **Function Modification**: Decorators allow you to extend or modify the behavior of functions or methods without changing their code. +- **Higher-Order Functions**: Decorators are often implemented as higher-order functions, meaning they take another function as an argument. + +--- + +## 1. Defining a Simple Decorator + +You can define a simple decorator by creating a function that takes another function as an argument and returns a new function. + +```python +def my_decorator(func): + def wrapper(): + print("Something is happening before the function is called.") + func() + print("Something is happening after the function is called.") + return wrapper +``` + +## 2. Applying a Decorator + +You can apply a decorator to a function using the `@decorator_name` syntax above the function definition. + +```python +@my_decorator +def say_hello(): + print("Hello!") + +say_hello() # Output: +# Something is happening before the function is called. +# Hello! +# Something is happening after the function is called. +``` + +## 3. Decorators with Arguments + +You can create decorators that accept arguments by defining another level of nested functions. + +```python +def repeat(num_times): + def decorator_repeat(func): + def wrapper(*args, **kwargs): + for _ in range(num_times): + func(*args, **kwargs) + return wrapper + return decorator_repeat + +@repeat(3) +def greet(name): + print(f"Hello, {name}!") + +greet("Alice") # Output: +# Hello, Alice! +# Hello, Alice! +# Hello, Alice! +``` + +## 4. Using `functools.wraps` + +When creating decorators, it's a good practice to use `functools.wraps` to preserve the original function's metadata. + +```python +from functools import wraps + +def my_decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + print("Something is happening before the function is called.") + return func(*args, **kwargs) + return wrapper + +@my_decorator +def say_hello(): + """This function says hello.""" + print("Hello!") + +print(say_hello.__name__) # Output: say_hello +print(say_hello.__doc__) # Output: This function says hello. +``` + +## 5. Chaining Decorators + +You can apply multiple decorators to a single function by stacking them. + +```python +def decorator_one(func): + def wrapper(): + print("Decorator One") + func() + return wrapper + +def decorator_two(func): + def wrapper(): + print("Decorator Two") + func() + return wrapper + +@decorator_one +@decorator_two +def say_hello(): + print("Hello!") + +say_hello() # Output: +# Decorator One +# Decorator Two +# Hello! +``` diff --git a/docs/languages/python/py-16.md b/docs/languages/python/py-16.md new file mode 100644 index 000000000..c8a5f4145 --- /dev/null +++ b/docs/languages/python/py-16.md @@ -0,0 +1,79 @@ +--- +id: usage-of-generators-in-python +sidebar_position: 16 +title: Generators in Python +sidebar_label: Generators in Python +--- + +Hey there! In this guide, we'll explore generators in Python. Generators are a special type of iterable that allow you to create iterators in a very concise and efficient way. They are useful for managing large datasets and for situations where you want to yield results incrementally. Let's dive in! + +--- + +## Python Generators + +- **Iterators**: Generators are a type of iterator that generate values on the fly and do not store them in memory. +- **Yield Statement**: Generators use the `yield` statement to produce a value and pause the function’s state, allowing it to resume later. + +--- + +## 1. Defining a Simple Generator + +You can define a generator function using the `yield` keyword. + +```python +def simple_generator(): + yield 1 + yield 2 + yield 3 + +gen = simple_generator() # Create a generator object +print(next(gen)) # Output: 1 +print(next(gen)) # Output: 2 +print(next(gen)) # Output: 3 +# print(next(gen)) # Raises StopIteration error +``` + +## 2. Using a Generator in a Loop + +Generators can be used in a loop to retrieve values until the generator is exhausted. + +```python +def countdown(n): + while n > 0: + yield n + n -= 1 + +for number in countdown(5): + print(number) # Output: 5, 4, 3, 2, 1 +``` + +## 3. Generator Expressions + +You can create generators using a generator expression, which is similar to list comprehensions but uses parentheses instead of brackets. + +```python +squared_numbers = (x**2 for x in range(5)) + +for square in squared_numbers: + print(square) # Output: 0, 1, 4, 9, 16 +``` + +## 4. Advantages of Generators + +- **Memory Efficiency**: Generators do not store the entire list in memory, making them more memory-efficient than lists. +- **Lazy Evaluation**: Values are computed on-the-fly, allowing for more efficient use of resources. + +## 5. Practical Use Case: Fibonacci Sequence + +Here’s an example of a generator that produces Fibonacci numbers. + +```python +def fibonacci(n): + a, b = 0, 1 + for _ in range(n): + yield a + a, b = b, a + b + +for num in fibonacci(10): + print(num) # Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 +``` diff --git a/docs/languages/python/py-17.md b/docs/languages/python/py-17.md new file mode 100644 index 000000000..d62b5f25a --- /dev/null +++ b/docs/languages/python/py-17.md @@ -0,0 +1,122 @@ +--- +id: regular-expression-in-python +sidebar_position: 17 +title: RegEx(Regular Expression) in Python +sidebar_label: RegEx(Regular Expression) in Python +--- + +Hey there! In this guide, we'll explore RegEx or Regular Expression in Python. A Regular Expression or RegEx is a special sequence of characters that uses a search pattern to find a string or set of strings. Let's dive in! + +--- + +## Regular Expression + +Regular expressions (regex) are a powerful tool for working with text by allowing you to define patterns that match specific character sequences.Regex is commonly used for tasks like: + +- Searching for specific patterns within a string +- Validating inputs (e.g., email addresses, phone numbers) +- Extracting or replacing parts of text + +--- + +## 1. RegEx Module in Python + +Python has a built-in module named `re` that is used for regular expressions in Python. We can import this module by using the import statement. + +Example: + +```python +# importing re module +import re +``` + +After importing the module you can start using the various function provided . + + +### 2. Metacharaters +Metacharacters are the characters with special meaning.These are used for pattern making. Below is a list of few Metacharacters with their descriptions + +| Metacharacter | Description | +|---------------|----------------------------------------------------------------------------------------------------------| +| `.` | Matches any character except a newline. | +| `^` | Matches the start of a string. | +| `$` | Matches the end of a string. | +| `*` | Matches 0 or more repetitions of the preceding character or group. | +| `+` | Matches 1 or more repetitions of the preceding character or group. | +| `?` | Matches 0 or 1 occurrence of the preceding character or group (makes it optional). | +| `{}` | Specifies the exact number of repetitions `{n}`, a range `{n,m}`, or a minimum `{n,}`. | +| `[]` | Matches any single character inside the brackets. | +| `\|` | Acts as an OR operator between expressions (e.g., `a|b` matches `a` or `b`). | +| `()` | Groups multiple expressions together and captures the matched text. | +| `\` | Escapes special characters (e.g., `\.` matches a literal `.`) or introduces special sequences like `\d`(We will learn `Special Sequences` in the next section). | + + + + +## 3. Special Sequences +Special Sequence in regex are shorthand notations that match specific types of characters, like digits, whitespace, or word characters, making patterns more concise and readable. +Table below shows various examples Special Sequence, their description and examples + +| Special Sequence | Description | Example | +|------------------|-------------------------------------------------------|----------------------------------| +| `\d` | Matches any digit (equivalent to `[0-9]`). | `\d{3}` matches `123` in `abc123`| +| `\D` | Matches any non-digit character. | `\D+` matches `abc` in `abc123` | +| `\w` | Matches any alphanumeric character or underscore. | `\w+` matches `abc123` in `abc123` | +| `\W` | Matches any non-alphanumeric character. | `\W+` matches `!@#` in `abc!@#` | +| `\s` | Matches any whitespace character (space, tab, newline).| `\s+` matches spaces in `a b c` | +| `\S` | Matches any non-whitespace character. | `\S+` matches `abc123` in `abc123` | +| `\b` | Matches a word boundary. | `\bword\b` matches `word` in `word!` but not in `sword` | +| `\B` | Matches a non-word boundary. | `\Bword\B` matches `word` in `swordplay` but not `word` alone | +| `\A` | Matches the start of the string. | `\Aabc` matches `abc` in `abc123` | +| `\Z` | Matches the end of the string. | `123\Z` matches `123` in `abc123` | +| `\` | Escapes special characters. | `\.` matches a literal `.` in `3.14` | +| `\t` | Matches a tab character. | `a\tb` matches `a b` (tab) | +| `\n` | Matches a newline character. | `a\nb` matches `a b` with newline | + + +## 3. RegEx Functions + +Regex functions in Python, available through the re module, provide powerful tools to search, match, split, replace, and manipulate text based on specified patterns, making it easy to handle complex text processing tasks. + +| Function | Description | Example Usage | +|----------------|-----------------------------------------------------------------------------------------------|---------------------------------------------| +| `re.search()` | Searches for the first occurrence of the pattern within the string and returns a match object if found. | `re.search(r"\d+", "Age: 25")` finds `25`. | +| `re.match()` | Checks if the pattern matches only at the beginning of the string. Returns a match object if found. | `re.match(r"Hello", "Hello World")` matches `Hello`. | +| `re.findall()` | Finds all non-overlapping matches of the pattern in the string and returns them as a list. | `re.findall(r"\w+", "Hello World")` returns `['Hello', 'World']`. | +| `re.split()` | Splits the string by occurrences of the pattern and returns a list of substrings. | `re.split(r"\s", "Split this sentence")` returns `['Split', 'this', 'sentence']`. | +| `re.sub()` | Replaces occurrences of the pattern in the string with a specified replacement. | `re.sub(r"\d", "#", "Phone: 123-456")` returns `Phone: ###-###`. | +| `re.compile()` | Compiles a regex pattern into a regex object for reuse, which can then use `search()`, `match()`, etc. | `pattern = re.compile(r"\d+"); pattern.search("ID: 789")` finds `789`. | + +Example: +```python +import re + +pattern = r"\b[A-Za-z]+\b" # matches any word consisting of letters only +text = "Hello, Algo world!" +matches = re.findall(pattern, text) +print(matches) # Output: ['Hello', 'Algo', 'world'] + +``` + +## 4. Practical Use Case: Password Validator + +Here’s an example of a Python Program to check the validity of password input by the user. + +```python +import re + +def validate_password(password): + # Define the regex pattern for password validation + pattern = r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$" + + # Check if the password matches the pattern + if re.match(pattern, password): + return "Password is valid" + else: + return "Password is invalid" + +# Test the function +print(validate_password("Password123!")) # Output: Password is valid +print(validate_password("Pass123")) # Output: Password is invalid (too short, no special character) + +``` diff --git a/docs/languages/python/py-18.md b/docs/languages/python/py-18.md new file mode 100644 index 000000000..138128d3e --- /dev/null +++ b/docs/languages/python/py-18.md @@ -0,0 +1,184 @@ +--- +id: lambda-function-in-python +sidebar_position: 18 +title: Lambda Function in Python +sidebar_label: Lambda Function in Python +--- + +Hey there! In this guide, we'll explore Lambda Function in Python.A lambda function can take n number of arguments at a time. But it returns only one argument at a time. Its useful for simple, quick operations and can replace small function definitions where full def functions might feel excessive. Let's dive it! + +--- + +## Lambda Function + +Lambda functions in Python, also known as `anonymous` functions, are small, one-line functions defined with the `lambda` keyword. + +--- + +## 1. Syntax + +```python +lambda arguments: expression +``` + +This function accepts any count of inputs but only evaluates and returns one expression. That means it takes many inputs but returns only one +output. + +## 2. Why Use Lambda Instead of Def? + +Using lambda instead of def can be beneficial in certain situations where brevity and inline functionality are preferred. + +The code defines a Square function using both the `def` keyword and a `lambda` function. +Example: + +```python +#using def +def square(num): + return num*num + +num1=2 +print(square(num1)) #Output:4 + + +#using lambda +lambda_square=lambda x:x*x +print(lambda_square(3)) #Output:9 + +``` + +Both of these give the correct output for the square of a +given number without employing Lambda. However, while +using `def` we were also required to use the return +keyword to provide the output from wherever the function +was invoked after being executed.Instead of a "return" +statement, Lambda definitions always include a statement +given at output. + +The convenience of lambda functions lies in their +flexibility.We dont need to allocate a lambda expression to a variable because we can put it at any place a function is required. + +## 3. Practical Use cases of Lambda Function + +- #### Using Lambda Function with filter() + +A program to filter a list of integers that are divisible by 3 +using Lambda function from given list of integers. + +```python + +numbers = [10, 15, 22, 33, 42, 55, 60, 71, 81] + +divisible_by_3 = list(filter(lambda x: x % 3 == 0, numbers)) + +print("Numbers divisible by 3:", divisible_by_3) + +#Output: Numbers divisible by 3: [15, 33, 42, 60, 81] + +``` + +--- + +- #### Using Lambda Function with map() + +A program to cube every number in a given list of +integers using Lambda function. + +```python + +input=[ 1, 2, 3, 4, 5] + +cube=list(map(lambda n:n**3,input)) + +print("Cube every number of the input is",cube) + +#Output: Cube every number of the input is [1, 8, 27, 64, 125] + +``` + +--- + +- #### Using Lambda Function with reduce() + +A program to calculate the product of all numbers in a list + +```python +from functools import reduce + +numbers = [1, 2, 3, 4] + +product = reduce(lambda x, y: x * y, numbers) + +print(product) # Output: 24 + + +``` + +--- + +- #### Using Lambda Function in List Comprehension + A program to filter a list of integers that are divisible by 3 + using Lambda function from given list of integers. + +```python + +numbers = [10, 15, 22, 33, 42, 55, 60, 71, 81] + +divisible_by_3 = [x for x in numbers if (lambda x: x % 3 == 0)(x)] + +print("Numbers divisible by 3:", divisible_by_3) + +#Output: Numbers divisible by 3: [15, 33, 42, 60, 81] + + +``` + +--- + +- #### Using Lambda Function with if-else + +A Program using lambda function to check if a number is even or odd + +```python + +even_or_odd = lambda x: "Even" if x % 2 == 0 else "Odd" + +print(even_or_odd(10)) # Output: Even +print(even_or_odd(7)) # Output: Odd + +``` + +--- + +- #### Using Lambda Function with Multiple Statements + +A Program using lambda function to for sorting the sublists and find the third largest number from every sublist + +```python + +my_List = [ [3, 5, 8, 6], [23, 54, 12, 87], [1, 2, 4, 12, 5] ] + +sort_List = lambda num: [sorted(n) for n in num] + +#sorted list : [[3, 5, 6, 8],[12, 23, 54, 87],[1, 2, 4, 5, 12]] + +third_Largest = lambda num, func: [l[-3] for l in func(num) if len(l) >= 3] + +result = third_Largest(my_List, sort_List) + +print('The third largest number from every sublist is:', result) + +#Output:The third largest number from every sublist is: [5, 23, 4] + +``` + +--- + +## 4. Conclusion + +Lambda functions in Python provide a concise way to create small, anonymous functions for temporary use, enhancing readability and enabling +functional programming. While more intricate logic, traditional `def` functions are preferred for better maintainability, `lambda` is ideal +for simple tasks, they should be used judiciously, as complex expressions can reduce clarity. Undersatnding corret usage of both the function +can make your code clean and effective. + +Happy Learning! + diff --git a/docs/languages/python/py-2.md b/docs/languages/python/py-2.md new file mode 100644 index 000000000..4b33a1c0d --- /dev/null +++ b/docs/languages/python/py-2.md @@ -0,0 +1,141 @@ +--- +id: variables-in-python +sidebar_position: 1 +title: Variables in Python +sidebar_label: Variables in Python +--- + + +Hey there! In this guide, we'll explore the concept of variables in Python. Variables are essential in programming, allowing you to store and manipulate data dynamically. Let's dive in! + +# Variables in Python + +## Introduction + +* Variables in Python are containers that hold data. +* They are used to store values that can be referenced and manipulated throughout a program. +* Python is dynamically typed, which means you do not need to declare the type of a variable when creating one. + +## Variable Declaration +In Python, variables are created when you assign a value to them. No explicit declaration is required. + +```python +x = 7 # Integer variable +y = 3.14 # Float variable +name = "Ben" # String variable +is_active = True # Boolean variable +``` + +## Naming Conventions + +* Variable names can contain letters, digits, and underscores. +* They must start with a letter or an underscore (_). +* They cannot start with a number. +* Python is case-sensitive, so age and Age are different variables. + +## Valid variable names + +```python +my_var = 25 +_name = "Mike" +age2 = 22 +``` + +## Invalid variable names + +```python +2name = "Rohan" # Cannot start with a number +my-var = 21 # Hyphen (-) is not allowed +``` +## Variable Types +Python supports several data types that can be assigned to variables: + +* Integers (int): Whole numbers +* Floating-Point Numbers (float): Numbers with decimals +* Strings (str): Text enclosed in single or double quotes +* Booleans (bool): True or False +* Lists (list): Ordered collections of items +* Tuples (tuple): Immutable ordered collections +* Dictionaries (dict): Key-value pairs + +Example: + +```python +age = 50 # Integer +height = 5.11 # Float +name = "John Doe" # String +is_student = False # Boolean +fruits = ["cherry", "orange"] # List +coordinates = (10.0, 20.0) # Tuple +person = {"name": "John", "age": 30} # Dictionary + +``` +## Dynamic Typing +Python is dynamically typed, meaning the same variable can hold values of different types at different points in the program. + +```python +x = 5 # Initially an integer +x = "Hello" # Now a string +``` +## Multiple Variable Assignment +You can assign multiple variables at once in a single line + +```python +a, b, c = 5, 10, 15 +``` +You can also assign same value to multiple variables + +```python +x = y = z = 0 +``` +## Variable Scope + +* Local Variables: Defined inside a function and can only be used within that function. +* Global Variables: Defined outside all functions and can be accessed throughout the program. + +```python +x = "global variable" + +def my_function(): + x = "local variable" + print(x) # Output: local variable + +my_function() +print(x) # Output: global variable +``` + +## Swapping Variables +In Python you can easily swap the values of two variables without needing any temporary variable + +```python +a = 5 +b = 10 +a, b = b, a +print(a) # Output: 10 +print(b) # Output: 5 +``` +## Constants in Python + +By convention, variables that should not change are written in uppercase. +However, Python does not have built-in support for constants, so it's up to the programmer to treat such variables as constant. + +```python +PI = 3.14159 +MAX_SPEED = 120 +``` +## Deleting Variables +You can delete a variable using `del` statement + +```python +x = 12 +del x # Deletes the variable 'x' +``` + +## Best Practices +- Use descriptive names that make it clear what the variable represents. +- Follow standard naming conventions (snake_case for variable names). +- Keep variable scope as limited as possible to avoid conflicts. + + + + diff --git a/docs/languages/python/py-3.md b/docs/languages/python/py-3.md new file mode 100644 index 000000000..9eaf504f8 --- /dev/null +++ b/docs/languages/python/py-3.md @@ -0,0 +1,80 @@ +--- +id: loops-in-python +sidebar_position: 4 +title: Loops in Python +sidebar_label: Loops in Python +--- + +Hey there! In this guide, we'll explore loops in Python. Loops are used to execute a block of code repeatedly based on a condition. Let's dive in! + +# Python Loops + +* Loops allow you to repeatedly execute a block of code while certain conditions are true. + +* Python provides two primary types of loops: `for` loops and `while` loops. +## 1. For Loop + + +The `for` loop in Python is used to iterate over a sequence (like a list, tuple, or string) and execute a block of code for each element. +```python +numbers = [1, 2, 3, 4, 5] # List of numbers to iterate over +for num in numbers: # Begin a 'for' loop over the 'numbers' list + print(num) # Print each number in the list +``` +## 2. For Loop with Range + + +You can also use the `range()` function to iterate over a sequence of numbers, especially when you want to loop for a specific number of times. +```python +for i in range(1, 6): # Loop through numbers from 1 to 5 (range excludes 6) + print(i) # Print each number in the range +``` +## 3. While Loop + + +The `while` loop in Python allows you to execute a block of code as long as a condition is true. +```python +count = 1 # Initialize a variable 'count' with value 1 +while count <= 5: # Continue looping while 'count' is less than or equal to 5 + print(count) # Print the current value of 'count' + count += 1 # Increment 'count' by 1 in each iteration +``` +## 4. Break Statement + + +The `break` statement is used to exit a loop prematurely, even if the loop condition is still true. +```python +for num in range(1, 11): # Loop through numbers 1 to 10 + if num == 5: # Check if 'num' equals 5 + break # Exit the loop when 'num' is 5 + print(num) # Print numbers from 1 to 4 +``` +## 5. Continue Statement + + +The `continue` statement skips the current iteration of the loop and moves to the next iteration. +```python +for num in range(1, 6): # Loop through numbers from 1 to 5 + if num == 3: # Check if 'num' equals 3 + continue # Skip the current iteration when 'num' is 3 + print(num) # Print numbers except 3 +``` +## 6. Nested Loops + + +In Python, you can use loops inside other loops. These are called nested loops and are useful for iterating over multi-dimensional data structures. +```python +for i in range(1, 4): # Outer loop from 1 to 3 + for j in range(1, 3): # Inner loop from 1 to 2 + print(f'Outer: {i}, Inner: {j}') # Print values of outer and inner loops +``` +## 7. Loop Else Clause + + +Python also provides an `else` clause that can be used with loops. The block under `else` is executed if the loop completes without hitting a `break` statement. +```python +for num in range(1, 4): # Loop through numbers from 1 to 3 + print(num) # Print the current value of 'num' +else: # Execute after the loop ends + print('Loop completed successfully.') # Print a success message +``` \ No newline at end of file diff --git a/docs/languages/python/py-4.md b/docs/languages/python/py-4.md new file mode 100644 index 000000000..e2a3e9e4a --- /dev/null +++ b/docs/languages/python/py-4.md @@ -0,0 +1,82 @@ +--- +id: decision-making-in-python +sidebar_position: 3 +title: Decision Making in Python +sidebar_label: Decision Making in Python +--- + +Hey there! In this guide, we'll explore decision-making in Python. Decision-making constructs allow you to execute code based on certain conditions. Let's dive in! + +## Decision Making + +* Python supports several decision-making constructs that allow you to execute code based on conditions. + +* We will go over the different decision-making options available in Python. +## 1. If Statements + + +The simplest decision-making structure in Python is the if statement, which executes a block of code if a certain condition is met. +```python +num = 8 # Initialize variable 'num' with a value of 8 +if num > 0: # Check if the value of 'num' is greater than 0 + print('The number is positive.') # Print a message if the condition is true +``` +## 2. If-Else Statements + + +The if-else statement allows you to execute one block of code if the condition is true, and another if the condition is false. +```python +num = 11 # Initialize variable 'num' with a value of 11 +if num % 2 == 0: # Check if 'num' is even + print('The number is even.') # Print this message if 'num' is even +else: # Otherwise, execute this block + print('The number is odd.') # Print this message if 'num' is odd +``` +## 3. Else If (Elif) Statements + + +The elif statement (short for else if) allows you to check multiple conditions in sequence and execute the first block of code where the condition is true. +```python +num = 15 # Initialize variable 'num' with a value of 15 +if num > 20: # Check if 'num' is greater than 20 + print('The number is greater than 20.') # Print this message if 'num' is greater than 20 +elif num == 15: # Check if 'num' is equal to 15 + print('The number is 15.') # Print this message if 'num' is equal to 15 +else: # Otherwise, execute this block + print('The number is less than 20.') # Print this message if 'num' is less than 20 +``` +## 4. Nested If Statements + + +You can use if statements inside other if statements, known as nested if statements, to evaluate more complex conditions. +```python +num = 7 # Initialize variable 'num' with a value of 7 +if num > 0: # Check if 'num' is positive + if num < 10: # Check if 'num' is less than 10 + print('The number is positive and less than 10.') # Print this message if both conditions are true +``` +## 5. Ternary Operator + + +Python also supports a shorthand for the if-else statement, called the ternary operator. +```python +age = 18 # Initialize variable 'age' with a value of 18 +can_vote = 'Yes' if age >= 18 else 'No' # Use the ternary operator to check if 'age' is 18 or older +print(can_vote) # Output: 'Yes' +``` +## 6. Switch Statements (Python 3.10+) + + +From Python 3.10, the match-case statement is introduced, which works similarly to a switch statement in other languages. +```python +day = 2 # Initialize variable 'day' with a value of 2 +match day: # Use match-case to determine the day of the week + case 1: + print('Monday') # Execute if 'day' is 1 + case 2: + print('Tuesday') # Execute if 'day' is 2 + case 3: + print('Wednesday') # Execute if 'day' is 3 + case _: # Default case + print('Invalid day') # Execute if none of the above cases match +``` \ No newline at end of file diff --git a/docs/languages/python/py-5.md b/docs/languages/python/py-5.md new file mode 100644 index 000000000..36a9bfb63 --- /dev/null +++ b/docs/languages/python/py-5.md @@ -0,0 +1,66 @@ +--- +id: usage-of-sets-in-python +sidebar_position: 5 +title: Sets in Python +sidebar_label: Sets in Python +--- + +Hey there! In this guide, we'll explore sets in Python. Sets are unordered collections of unique elements that allow you to perform various operations like union, intersection, and difference. Let's dive in! + +# Python Sets + + +* Sets are unordered collections of unique elements. + +* They are mutable, which means you can change their contents after creation. +## 1. Creating a Set + + +You can create a set using curly braces `{}` or the `set()` function. +```python +my_set = {1, 2, 3, 4} # Create a set using curly braces +another_set = set([3, 4, 5, 6]) # Create a set using the set() function +print(my_set) # Output: {1, 2, 3, 4} +print(another_set) # Output: {3, 4, 5, 6} +``` +## 2. Accessing Elements + + +Sets do not support indexing, but you can check for the existence of an element using the `in` keyword. +```python +my_set = {1, 2, 3, 4} # Define a set +print(2 in my_set) # Check if 2 is in the set, Output: True +print(5 in my_set) # Check if 5 is in the set, Output: False +``` +## 3. Adding Elements + + +You can add elements to a set using the `add()` method. +```python +my_set.add(5) # Add an element to the set +print(my_set) # Output: {1, 2, 3, 4, 5} +``` +## 4. Removing Elements + + +To remove elements, you can use the `remove()` method or the `discard()` method. +```python +my_set.remove(3) # Remove an element (raises error if not found) +print(my_set) # Output: {1, 2, 4, 5} +my_set.discard(2) # Remove an element (does not raise error if not found) +print(my_set) # Output: {1, 4, 5} +``` +## 5. Set Operations + + +Sets support various mathematical operations like union, intersection, and difference. +```python +set1 = {1, 2, 3} # Define the first set +set2 = {3, 4, 5} # Define the second set +union_set = set1 | set2 # Union operation +intersection_set = set1 & set2 # Intersection operation +difference_set = set1 - set2 # Difference operation +print(union_set) # Output: {1, 2, 3, 4, 5} +print(intersection_set) # Output: {3} +print(difference_set) # Output: {1, 2} +``` \ No newline at end of file diff --git a/docs/languages/python/py-6.md b/docs/languages/python/py-6.md new file mode 100644 index 000000000..d1216154f --- /dev/null +++ b/docs/languages/python/py-6.md @@ -0,0 +1,66 @@ +--- +id: usage-of-dictionaries-in-python +sidebar_position: 6 +title: Dictionaries in Python +sidebar_label: Dictionaries in Python +--- + +Hey there! In this guide, we'll explore dictionaries in Python. Dictionaries are unordered collections of key-value pairs that allow you to store and manipulate data efficiently. Let's dive in! + +# Python Dictionaries + + +* Dictionaries are unordered collections of key-value pairs. + +* They are mutable, allowing you to change their contents after creation. +## 1. Creating a Dictionary + + +You can create a dictionary using curly braces `{}` or the `dict()` function. +```python +my_dict = {'name': 'John', 'age': 30} # Create a dictionary using curly braces +another_dict = dict(name='Jane', age=25) # Create a dictionary using the dict() function +print(my_dict) # Output: {'name': 'John', 'age': 30} +print(another_dict) # Output: {'name': 'Jane', 'age': 25} +``` +## 2. Accessing Elements + + +You can access values in a dictionary using their keys. +```python +my_dict = {'name': 'John', 'age': 30} # Define a dictionary +print(my_dict['name']) # Access value using key, Output: 'John' +print(my_dict['age']) # Access value using key, Output: 30 +``` +## 3. Adding Elements + + +You can add new key-value pairs to a dictionary using assignment. +```python +my_dict['city'] = 'New York' # Add a new key-value pair +print(my_dict) # Output: {'name': 'John', 'age': 30, 'city': 'New York'} +``` +## 4. Removing Elements + + +You can remove key-value pairs using the `del` statement or the `pop()` method. +```python +del my_dict['age'] # Remove an element using del +print(my_dict) # Output: {'name': 'John', 'city': 'New York'} +age = my_dict.pop('city') # Remove and return an element using pop() +print(age) # Output: 'New York' +print(my_dict) # Output: {'name': 'John'} +``` +## 5. Dictionary Methods + + +Dictionaries have several built-in methods for manipulation. +```python +my_dict = {'name': 'John', 'age': 30} # Define a dictionary +keys = my_dict.keys() # Get all keys +values = my_dict.values() # Get all values +items = my_dict.items() # Get all key-value pairs +print(keys) # Output: dict_keys(['name', 'age']) +print(values) # Output: dict_values(['John', 30]) +print(items) # Output: dict_items([('name', 'John'), ('age', 30)]) +``` \ No newline at end of file diff --git a/docs/languages/python/py-7.md b/docs/languages/python/py-7.md new file mode 100644 index 000000000..1bf51270c --- /dev/null +++ b/docs/languages/python/py-7.md @@ -0,0 +1,102 @@ +--- +id: usage-of-operators-in-python +sidebar_position: 7 +title: Operators in Python +sidebar_label: Operators in Python +--- + +Hey there! In this guide, we'll explore operators in Python. Operators are special symbols that perform operations on variables and values. Let's dive in! + +# Python Operators + + +* Python supports various types of operators to perform different kinds of operations on variables and values. + +* These operators are grouped into several categories. +## 1. Arithmetic Operators + + +These operators are used to perform basic mathematical operations. +```python +x = 10 # Initialize x +y = 5 # Initialize y +add = x + y # Addition: 10 + 5 = 15 +sub = x - y # Subtraction: 10 - 5 = 5 +mul = x * y # Multiplication: 10 * 5 = 50 +div = x / y # Division: 10 / 5 = 2.0 +mod = x % y # Modulus: 10 % 5 = 0 +exp = x ** y # Exponentiation: 10 ** 5 = 100000 +floordiv = x // y # Floor division: 10 // 5 = 2 +``` +## 2. Comparison Operators + + +These operators are used to compare two values, and they return a Boolean result. +```python +x = 10 # Initialize x +y = 5 # Initialize y +eq = (x == y) # Equal to: False +ne = (x != y) # Not equal to: True +gt = (x > y) # Greater than: True +lt = (x < y) # Less than: False +ge = (x >= y) # Greater than or equal to: True +le = (x <= y) # Less than or equal to: False +``` +## 3. Logical Operators + + +These operators are used to combine conditional statements. +```python +a = True # Initialize a +b = False # Initialize b +logical_and = (a and b) # Logical AND: False +logical_or = (a or b) # Logical OR: True +logical_not = not a # Logical NOT: False +``` +## 4. Assignment Operators + + +These operators are used to assign values to variables. +```python +x = 10 # Assign 10 to x +x += 5 # Add and assign: x = x + 5 -> 15 +x -= 3 # Subtract and assign: x = x - 3 -> 12 +x *= 2 # Multiply and assign: x = x * 2 -> 24 +x /= 4 # Divide and assign: x = x / 4 -> 6.0 +x %= 3 # Modulus and assign: x = x % 3 -> 0 +x //= 2 # Floor divide and assign: x = x // 2 -> 0 +x **= 3 # Exponentiation and assign: x = x ** 3 -> 0 +``` +## 5. Bitwise Operators + + +These operators work on bits and perform bit-level operations. +```python +x = 6 # Binary: 110 +y = 3 # Binary: 011 +bitwise_and = x & y # Bitwise AND: 010 -> 2 +bitwise_or = x | y # Bitwise OR: 111 -> 7 +bitwise_xor = x ^ y # Bitwise XOR: 101 -> 5 +bitwise_not = ~x # Bitwise NOT: 001 -> -7 (two's complement) +shift_left = x << 2 # Left shift: 110 << 2 -> 11000 -> 24 +shift_right = x >> 2 # Right shift: 110 >> 2 -> 001 -> 1 +``` +## 6. Membership Operators + + +These operators test for membership in a sequence, such as strings, lists, or tuples. +```python +my_list = [1, 2, 3, 4] # Define a list +is_in = 2 in my_list # Check if 2 is in the list: True +is_not_in = 5 not in my_list # Check if 5 is not in the list: True +``` +## 7. Identity Operators + + +These operators compare the memory locations of two objects. +```python +x = 5 # Initialize x +y = 5 # Initialize y +is_identical = (x is y) # Check if x and y refer to the same object: True +is_not_identical = (x is not y) # Check if x and y refer to different objects: False +``` \ No newline at end of file diff --git a/docs/languages/python/py-8.md b/docs/languages/python/py-8.md new file mode 100644 index 000000000..e7ebdbde2 --- /dev/null +++ b/docs/languages/python/py-8.md @@ -0,0 +1,86 @@ +--- +id: usage-of-python-classes +sidebar_position: 8 +title: Classes in Python +sidebar_label: Classes in Python +--- + +Hey there! In this guide, we'll explore classes in Python. Classes are a fundamental part of object-oriented programming in Python. Let's dive in! + +# Python Classes + + +* Python supports object-oriented programming, and classes are a fundamental part of this paradigm. + +* A class is a blueprint for creating objects, defining their attributes and methods. +## 1. Creating a Simple Class + + +Here's how to define a simple class with attributes and methods. +```python +class Dog: # Define a class named Dog + def __init__(self, name, age): # Constructor method to initialize attributes + self.name = name # Assign name to the instance + self.age = age # Assign age to the instance + def bark(self): # Method to make the dog bark + return 'Woof!' # Return barking sound +``` +## 2. Creating an Object + + +You can create an object (instance) of the class like this: +```python +my_dog = Dog('Buddy', 3) # Create an instance of Dog class +print(my_dog.name) # Access the name attribute: Buddy +print(my_dog.age) # Access the age attribute: 3 +print(my_dog.bark()) # Call the bark method: Woof! +``` +## 3. Class Inheritance + + +Classes can inherit attributes and methods from other classes. +```python +class Animal: # Base class + def __init__(self, species): # Constructor for species + self.species = species # Assign species to the instance +class Cat(Animal): # Cat class inherits from Animal + def __init__(self, name, age): # Constructor method for Cat + super().__init__('Cat') # Call the base class constructor + self.name = name # Assign name to the instance + self.age = age # Assign age to the instance + def meow(self): # Method to make the cat meow + return 'Meow!' # Return meowing sound +``` +## 4. Creating an Inherited Object + + +You can create an object of the inherited class like this: +```python +my_cat = Cat('Whiskers', 2) # Create an instance of Cat class +print(my_cat.species) # Access inherited species attribute: Cat +print(my_cat.name) # Access name attribute: Whiskers +print(my_cat.meow()) # Call the meow method: Meow! +``` +## 5. Class Methods and Static Methods + + +You can define class methods and static methods in a class. +```python +class MathOperations: # Define a class for math operations + @staticmethod # Static method decorator + def add(x, y): # Static method to add two numbers + return x + y # Return the sum + @classmethod # Class method decorator + def multiply(cls, x, y): # Class method to multiply two numbers + return x * y # Return the product +``` +## 6. Using Class and Static Methods + + +Here's how to use the class and static methods: +```python +sum_result = MathOperations.add(5, 10) # Call the static method: 15 +product_result = MathOperations.multiply(5, 10) # Call the class method: 50 +print(sum_result) # Output the sum result +print(product_result) # Output the product result +``` \ No newline at end of file diff --git a/docs/languages/python/py-9.md b/docs/languages/python/py-9.md new file mode 100644 index 000000000..383f37244 --- /dev/null +++ b/docs/languages/python/py-9.md @@ -0,0 +1,88 @@ +--- +id: strings-in-python +sidebar_position: 9 +title: Strings in Python +sidebar_label: Strings in Python +--- + +Hey everyone! Today we're going to explore one of the most commonly used data types in Python – strings. If you're just starting with Python or need a quick refresher, this guide will help you understand how strings work in Python. Let's get started! +# Python Strings + + +* A string in Python is a sequence of characters enclosed within single quotes, double quotes, or triple quotes. + +* Strings are immutable, meaning once created, they cannot be changed. +## 1. Defining a String + + +Let's see how you can define a string in Python: +```python +name = 'Python' # Define a string with single quotes +greeting = "Hello, World!" # Define a string with double quotes +long_string = '''This is a long string # Define a multi-line string with triple quotes +that spans multiple lines.''' # Continuing the multi-line string +``` +## 2. Accessing Characters in a String + + +You can access individual characters in a string using indexing: +```python +name = 'Python' # Define a string +first_char = name[0] # Access the first character: 'P' +last_char = name[-1] # Access the last character: 'n' +print(first_char) # Output: 'P' +print(last_char) # Output: 'n' +``` +## 3. Slicing a String + + +You can slice a string to get a substring: +```python +name = 'Python' # Define a string +sub_str = name[0:3] # Slice from index 0 to 2: 'Pyt' +print(sub_str) # Output: 'Pyt' +``` +## 4. String Concatenation + + +You can combine two or more strings using the `+` operator: +```python +first_name = 'John' # Define a first name string +last_name = 'Doe' # Define a last name string +full_name = first_name + ' ' + last_name # Concatenate strings with a space +print(full_name) # Output: 'John Doe' +``` +## 5. String Formatting + + +You can format strings using f-strings, which is an efficient and readable way to include variables in a string: +```python +name = 'Alice' # Define a name string +age = 30 # Define an age variable +message = f'{name} is {age} years old.' # Format string with variables +print(message) # Output: 'Alice is 30 years old.' +``` +## 6. Common String Methods + + +Python provides several built-in methods to work with strings. Here are a few commonly used ones: +```python +text = ' Hello, Python! ' # Define a string with leading and trailing spaces +trimmed_text = text.strip() # Remove leading and trailing spaces: 'Hello, Python!' +uppercase_text = text.upper() # Convert the string to uppercase: ' HELLO, PYTHON! ' +lowercase_text = text.lower() # Convert the string to lowercase: ' hello, python! ' +replaced_text = text.replace('Python', 'World') # Replace 'Python' with 'World': ' Hello, World! ' +print(trimmed_text) # Output: 'Hello, Python!' +print(uppercase_text) # Output: ' HELLO, PYTHON! ' +print(lowercase_text) # Output: ' hello, python! ' +print(replaced_text) # Output: ' Hello, World! ' +``` +## 7. String Length + + +You can get the length of a string using the `len()` function: +```python +text = 'Hello, Python!' # Define a string +length = len(text) # Get the length of the string: 13 +print(length) # Output: 13 +``` \ No newline at end of file diff --git a/docs/linked-list/CircularDoubly.png b/docs/linked-list/CircularDoubly.png new file mode 100644 index 0000000000000000000000000000000000000000..08652ba8c9642c90323ffb6941a054e2ab72cc54 GIT binary patch literal 3213 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 literal 0 HcmV?d00001 diff --git a/docs/linked-list/CircularLinkedList.png b/docs/linked-list/CircularLinkedList.png new file mode 100644 index 0000000000000000000000000000000000000000..2e2e31ab0fbed1a14f5b9ed3675d649c75e697b2 GIT binary patch literal 230132 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

    KFjWXCIU2AqRG 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 + //ask user that how many elements they want to insert + printf("\nenter no. of elements_"); + scanf("%d",&x); + //taking user input + printf("\nenter data_"); + scanf("%d",&h->data); + //taking two pointer at start and at the end + p=h; + for(i=1;inext=(node*)malloc(sizeof(node)); + s=p; + p=p->next; + p->prev=s; + p->next=NULL; + printf("\nenter data_"); + scanf("%d",&p->data); + } + head=p; + //can make choice of where side of control user want to start + printf("\nChoice to give control from start or from last if(num =1 last node pointer will be pass)"); + scanf("%d",&num); + if(num==1) + return(h); + return(head); + } + ``` + +2. **Traversal**: + + ```text + void display(node*head) + { + node*p; + p=head; + //checking if the pointer pass from front or from end (in my case but you can create your creativity) + if(p->next!=NULL) + { + printf("\nDLL is:(by going with next)\n"); + while(p!=NULL) + { + printf("%d\t",p->data); + p=p->next; + } + } + else + { + printf("\nDLL is:(by going with previous)\n"); + while(p!=NULL) + { + printf("%d\t",p->data); + p=p->prev; + } + } + } + ``` +3. **Insertion (begining , last , or any location)**: + + ```text + void insertion(node*head) + { + int loc,i; + node*p,*q,*s; + p=(node*)malloc(sizeof(node)); + p->next=p->prev=NULL; + printf("\nenter inerting element_"); + //making your data's node to insert + scanf("%d",&p->data); + //enter location where you want to insert + printf("\nenter location_"); + scanf("%d",&loc); + q=head; + //insertion at begining + if(loc==1) + { + p->next=head; + head->prev=p; + display(p); + } + else + { + for(i=2;inext; + s=q->next; + p->next=s; + s->prev=p; + q->next=p; + p->prev=q; + //see the inserted linked list + display(head); + } + } + ``` +4. **Deletion (at begining , at last , or at any location)**: + + ```text + void delete(node*head) + { + node*p,*q,*s; + int loc,i; + //from where you want to delete + printf("\nenter location_"); + scanf("%d",&loc); + //at begining + if(loc==1) + { + head=head->next; + head->prev=NULL; + //see the deleted DLL + display(head); + } + else + { + p=head; + for(i=2;inext; + q=p->next->next; + p->next=NULL; + p->next=q; + q->prev=p; + //see the deleted DLL + display(head); + } + } + ``` +5. **Main function**: + + ```text + void main() + { + node*head; + printf("Doubly Linked list\n"); + //creating function + head=create(); + //display function + display(head); + //insertion function + insertion(head); + //delete function + delete(head); + } + ``` +### Complexity + +- **Time Complexity**: + + - Traversal: $O(n)$ + - Insertion : $O(1)$ + - Deletion: $O(1)$ + +- **Space Complexity**: $O(1)$ + +### Advantages: + + -Bidirectional traversal: You can traverse the list both forward and backward. + -Efficient insertion and deletion: Insertion and deletion operations are efficient at both ends of the list as well as in the middle, as you don’t need to shift elements like you would in an array. + +### Disadvantages: + +**Extra memory**: + Each node requires additional memory for storing the pointer to the previous node. +**More complex code**: + The management of two pointers (previous and next) makes the implementation more complex than a singly linked list. + +### Use Cases: + +**Browser History**: + Moving forward and backward through previously visited pages. +**Undo/Redo Operations**: + Navigating through changes in a document or application. +**Navigation systems**: + Efficiently traversing elements in both directions in applications such as playlists or slideshows. + +### Conclusion + +In this **C** implementation, we cover fundamental operations such as inserting and deleting nodes at both ends, as well as traversing the list in both directions. Understanding doubly linked lists is essential for mastering dynamic data structures and memory management in **C**. diff --git a/docs/linked-list/DoublyLL.png b/docs/linked-list/DoublyLL.png new file mode 100644 index 0000000000000000000000000000000000000000..bc2dd8bf764bec7c03faf1b69d9cb711a66d4da0 GIT binary patch literal 199538 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%0AgNpx_4yq?1!>0>(nS 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

    h1+sxFAx)L{-IN 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 Wzhzd`!|7AtPg(xHT!F0Vi~j=luNpA` literal 0 HcmV?d00001 diff --git a/docs/linked-list/Hare-Tortoise.md b/docs/linked-list/Hare-Tortoise.md new file mode 100644 index 000000000..94812e7f5 --- /dev/null +++ b/docs/linked-list/Hare-Tortoise.md @@ -0,0 +1,174 @@ +--- +id: introduction-to-LinkedList +title: Hare and Tortoise Algorithm +sidebar_label: Introduction to Hare and Tortoise Algorithm +sidebar_position: 11 +description: The Hare and Tortoise Algorithm, also known as Floyd's Cycle Detection Algorithm, is a method used to detect cycles in a linked list. It employs two pointers that move at different speeds to identify whether a cycle exists. + +tags: [dsa, data-structures,Hare and Tortoise Algorithm] +--- + + +### Defination: + +The Hare and Tortoise Algorithm, also known as Floyd's Cycle Detection Algorithm, is a method used to detect cycles in a linked list. It employs two pointers that move at different speeds to identify whether a cycle exists. + +### Characteristics: + +- **Two Pointer Technique**: +- The algorithm uses two pointers: a tortoise that moves one step at a time and a hare that moves two steps at a time. + +- **Cycle Detection**: +- If the linked list contains a cycle, the fast-moving hare will eventually meet the slow-moving tortoise. + +-**Space Efficiency**: +The algorithm uses a constant amount of space (O(1)), making it very efficient. + +-**Applicable to Linked Lists**: +- It is specifically designed to work with linked lists, where the next node is accessed through pointers. + +### Time Complexity: + +- **Best, Average, and Worst Case: O(N)** + - In the worst case, both pointers traverse the entire list, leading to linear time complexity, where n is the number of nodes in the linked list. + +- **Space Complexity: O(1)** +- The algorithm only uses two pointers regardless of the input size, resulting in constant space complexity. + +### C++ Implementation: + +```cpp +#include + +struct ListNode { + int value; + ListNode* next; + ListNode(int val) : value(val), next(nullptr) {} +}; + +bool hasCycle(ListNode* head) { + ListNode* tortoise = head; + ListNode* hare = head; + + while (hare != nullptr && hare->next != nullptr) { + tortoise = tortoise->next; // Move tortoise by 1 step + hare = hare->next->next; // Move hare by 2 steps + + if (tortoise == hare) { + return true; // Cycle detected + } + } + + return false; // No cycle +} + +int main() { + // Creating a linked list with a cycle for testing + ListNode* head = new ListNode(1); + head->next = new ListNode(2); + head->next->next = new ListNode(3); + head->next->next->next = new ListNode(4); + head->next->next->next->next = head->next; // Creating a cycle + + if (hasCycle(head)) { + std::cout << "Cycle detected in the linked list." << std::endl; + } else { + std::cout << "No cycle detected in the linked list." << std::endl; + } + + // Clean up memory (not reached due to cycle) + return 0; +} + + +``` + +### JAVA Implementation: + +```java +class ListNode { + int value; + ListNode next; + + ListNode(int val) { + this.value = val; + this.next = null; + } +} + +public class CycleDetection { + + public static boolean hasCycle(ListNode head) { + ListNode tortoise = head; + ListNode hare = head; + + while (hare != null && hare.next != null) { + tortoise = tortoise.next; // Move tortoise by 1 step + hare = hare.next.next; // Move hare by 2 steps + + if (tortoise == hare) { + return true; // Cycle detected + } + } + + return false; // No cycle + } + + public static void main(String[] args) { + // Creating a linked list with a cycle for testing + ListNode head = new ListNode(1); + head.next = new ListNode(2); + head.next.next = new ListNode(3); + head.next.next.next = new ListNode(4); + head.next.next.next.next = head.next; // Creating a cycle + + if (hasCycle(head)) { + System.out.println("Cycle detected in the linked list."); + } else { + System.out.println("No cycle detected in the linked list."); + } + } +} + + +``` + +### Python Implementation: +```py +class ListNode: + def __init__(self, value=0, next=None): + self.value = value + self.next = next + +def has_cycle(head): + tortoise = head + hare = head + + while hare and hare.next: + tortoise = tortoise.next # Move tortoise by 1 step + hare = hare.next.next # Move hare by 2 steps + + if tortoise == hare: + return True # Cycle detected + + return False # No cycle + +if __name__ == "__main__": + # Creating a linked list with a cycle for testing + head = ListNode(1) + head.next = ListNode(2) + head.next.next = ListNode(3) + head.next.next.next = ListNode(4) + head.next.next.next.next = head.next # Creating a cycle + + if has_cycle(head): + print("Cycle detected in the linked list.") + else: + print("No cycle detected in the linked list.") + + +``` + +### Summary: + +The Hare and Tortoise Algorithm is an efficient method for detecting cycles in a linked list using a two-pointer technique. It operates in linear time and constant space, making it a widely used approach in various applications involving linked data structures. diff --git a/docs/linked-list/Intersection_Linked_list_python.md b/docs/linked-list/Intersection_Linked_list_python.md new file mode 100644 index 000000000..797277d5d --- /dev/null +++ b/docs/linked-list/Intersection_Linked_list_python.md @@ -0,0 +1,97 @@ +--- +id: intersection-linked-lists-python +sidebar_position: 1 +title: "Find the Intersection Point of Two Linked Lists in Python using hash set" +description: "This tutorial explains how to find the intersection point of two singly linked lists using Python." +sidebar_label: "Linked List Intersection" +tags: [dsa, linked-lists, intersection,python,hash-set] +--- + +# Intersection of Two Linked Lists + +## Problem Statement + +In a linked list, the intersection of two lists occurs when two linked lists share a common node. Given two linked lists, this problem aims to find the node where the two lists intersect. If they do not intersect, the result should be `None`. + +### Example + +Consider the following two linked lists: + +- **List A**: `1 -> 2 -> 3` +- **List B**: `4 -> 5` +- Both lists intersect at the node with value `3`. + +The expected output in this case is: + + +## Approach + +To solve this problem, we can use a hash set to store the nodes of the first linked list. As we traverse the second linked list, we can check if any node exists in the set. If we find a match, that node is the intersection point. + +### Steps: + +1. Traverse the first linked list and add each node to a set. +2. Traverse the second linked list and check if any node is in the set. +3. If a node is found in the set, return that node as the intersection. +4. If no nodes match, return `None`. + +## Python Code + +Below is the implementation of the solution in Python: + +```python +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class Solution: + def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: + # Using a set to store the nodes of the first linked list + seen_nodes = set() + curr = headA + + while curr: + seen_nodes.add(curr) # Add the current node to the set + curr = curr.next + + curr2 = headB + while curr2: + if curr2 in seen_nodes: # Check if current node is in the set + return curr2 # Intersection found + curr2 = curr2.next + + return None # No intersection + +# Helper function to create a linked list from a list +def create_linked_list(values): + if not values: + return None + head = ListNode(values[0]) + curr = head + for value in values[1:]: + curr.next = ListNode(value) + curr = curr.next + return head + +# Example usage +if __name__ == "__main__": + # Create linked lists for the example + # List A: 1 -> 2 -> 3 + # List B: 4 -> 5 + # Intersection at node with value 3 + intersection_node = ListNode(3) + + headA = create_linked_list([1, 2]) + headA.next.next = intersection_node # Connect intersection + headB = create_linked_list([4, 5]) + headB.next.next = intersection_node # Connect intersection + + solution = Solution() + intersection = solution.getIntersectionNode(headA, headB) + + if intersection: + print(f"Intersection at node with value: {intersection.val}") + else: + print("No intersection") +``` \ No newline at end of file diff --git a/docs/linked-list/LinkedList.png b/docs/linked-list/LinkedList.png new file mode 100644 index 0000000000000000000000000000000000000000..31974c45af5df3249083c1b17c7bc4eff6cb86db GIT binary patch literal 53702 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 +using namespace std; + +struct Node { + int coeff; + int exp; + Node* next; + Node(int c, int e) : coeff(c), exp(e), next(nullptr) {} // Constructor for easy initialization +}; + +// Function to insert a term at the end of the polynomial +void insertTerm(Node*& head, int coeff, int exp) { + Node* newNode = new Node(coeff, exp); + if (head == nullptr) { + head = newNode; + } else { + Node* temp = head; + while (temp->next != nullptr) { + temp = temp->next; + } + temp->next = newNode; + } +} + +// Function to display the polynomial in a formatted way +void displayPolynomial(Node* head) { + Node* temp = head; + bool isFirstTerm = true; + + while (temp != nullptr) { + // Adjust display for x^1 and x^0 cases + if (temp->exp == 1) { + cout << (temp->coeff > 0 && !isFirstTerm ? " + " : "") << temp->coeff << "x"; + } else if (temp->exp == 0) { + cout << (temp->coeff > 0 && !isFirstTerm ? " + " : "") << temp->coeff; + } else { + cout << (temp->coeff > 0 && !isFirstTerm ? " + " : "") << temp->coeff << "x^" << temp->exp; + } + temp = temp->next; + isFirstTerm = false; + } + cout << endl; +} + +// Function to add two polynomials and return the resulting polynomial +Node* addPolynomials(Node* poly1, Node* poly2) { + Node* result = nullptr; + Node* p1 = poly1; + Node* p2 = poly2; + + while (p1 != nullptr && p2 != nullptr) { + if (p1->exp > p2->exp) { + insertTerm(result, p1->coeff, p1->exp); + p1 = p1->next; + } else if (p1->exp < p2->exp) { + insertTerm(result, p2->coeff, p2->exp); + p2 = p2->next; + } else { + int sumCoeff = p1->coeff + p2->coeff; + if (sumCoeff != 0) { // Only add non-zero coefficients + insertTerm(result, sumCoeff, p1->exp); + } + p1 = p1->next; + p2 = p2->next; + } + } + + // Insert remaining terms from either polynomial if any are left + while (p1 != nullptr) { + insertTerm(result, p1->coeff, p1->exp); + p1 = p1->next; + } + while (p2 != nullptr) { + insertTerm(result, p2->coeff, p2->exp); + p2 = p2->next; + } + + return result; +} + +int main() { + Node* poly1 = nullptr; + Node* poly2 = nullptr; + Node* result = nullptr; + int n, coeff, exp; + cout << "Enter the number of terms for the first polynomial: "; + cin >> n; + for (int i = 0; i < n; i++) { + cout << "Enter coefficient and exponent for term " << i + 1 << ": "; + cin >> coeff >> exp; + insertTerm(poly1, coeff, exp); + } + cout << "Enter the number of terms for the second polynomial: "; + cin >> n; + for (int i = 0; i < n; i++) { + cout << "Enter coefficient and exponent for term " << i + 1 << ": "; + cin >> coeff >> exp; + insertTerm(poly2, coeff, exp); + } + cout << "First Polynomial: "; + displayPolynomial(poly1); + cout << "Second Polynomial: "; + displayPolynomial(poly2); + result = addPolynomials(poly1, poly2); + cout << "Sum of Polynomials: "; + displayPolynomial(result); + return 0; +} +``` diff --git a/docs/linked-list/Practice-Problems.md b/docs/linked-list/Practice-Problems.md new file mode 100644 index 000000000..b72706b3b --- /dev/null +++ b/docs/linked-list/Practice-Problems.md @@ -0,0 +1,58 @@ +--- +id: practice-problems-on-linked-list +title: Practice Problems +sidebar_label: Practice Problems +sidebar_position: 16 +Description: Here are some practice problems for Linked List data structure divided into topic-wise and difficulty wise. +tags: [DSA, algorithms,linked list, dsa] +--- + +### 1. Basic Operations on Linked List + + - [Reverse a Linked List](https://leetcode.com/problems/reverse-linked-list/description/) + - [Middle of the Linked List](https://leetcode.com/problems/middle-of-the-linked-list/description/) + - [Length of Linked List](https://practice.geeksforgeeks.org/problems/find-length-of-loop/1) + - [Delete Node in a Linked List](https://leetcode.com/problems/delete-node-in-a-linked-list/description/) + - [Swap Nodes in Pairs](https://leetcode.com/problems/swap-nodes-in-pairs/description/) + - [Rotate List](https://leetcode.com/problems/rotate-list/description/) + +### 2. Two Pointer Technique + + - [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/) + - [Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) + - [Remove N-th Node from End](https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/) + - [Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/description/) + - [Split Linked List in Parts](https://leetcode.com/problems/split-linked-list-in-parts/description/) + +### 3. Linked List Merging + + - [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/description/) + - [Add Two Numbers](https://leetcode.com/problems/add-two-numbers/description/) + - [Merge in Between Linked Lists](https://leetcode.com/problems/merge-in-between-linked-lists/description/) + - [Sort List](https://leetcode.com/problems/sort-list/description/) + - [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/description/) + +### 4. Circular Linked List + - [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/) + - [Split Circular List](https://www.geeksforgeeks.org/problems/split-a-circular-linked-list-into-two-halves/1/) + - [Find the Winner of the Circular Game](https://leetcode.com/problems/find-the-winner-of-the-circular-game/description/) + - [Sorted insert for circular linked list](https://geeksforgeeks.org/problems/sorted-insert-for-circular-linked-list/1) + +### 5. Doubly Linked List + + - [Flatten a Multilevel List](https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/description/) + - [Reverse Doubly Linked List](https://www.geeksforgeeks.org/problems/reverse-a-doubly-linked-list/1) + - [Design Browser History](https://leetcode.com/problems/design-browser-history/description/) + +### 6. Advanced Linked List Problems + + - [Convert Binary in Linked List to Integer](https://leetcode.com/problems/convert-binary-number-in-a-linked-list-to-integer/description/) + - [Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/description/) + - [Flatten a Linked List](https://www.geeksforgeeks.org/problems/flattening-a-linked-list/1) + - [LRU Cache](https://leetcode.com/problems/lru-cache/description/) + - [Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/description/) + +### 7. Palindrome Linked List + + - [Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/description/) + - [Linked list of strings forms a palindrome](https://www.geeksforgeeks.org/problems/linked-list-of-strings-forms-a-palindrome/0) \ No newline at end of file diff --git a/docs/linked-list/_category_.json b/docs/linked-list/_category_.json new file mode 100644 index 000000000..43ba7b561 --- /dev/null +++ b/docs/linked-list/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Linked List", + "position": 11, + "link": { + "type": "generated-index", + "description": "Learn the most important concepts of Linked list." + } + } \ No newline at end of file diff --git a/docs/linked-list/circular-doubly-linked-list.md b/docs/linked-list/circular-doubly-linked-list.md new file mode 100644 index 000000000..36dfb7acb --- /dev/null +++ b/docs/linked-list/circular-doubly-linked-list.md @@ -0,0 +1,516 @@ +--- +id: introduction-to-CircularDoublyLinkedList +title: Circular Doubly Linked List Data Structure +sidebar_label: Introduction to Circular Doubly Linked List +sidebar_position: 3 +description: 'A Circular Doubly Linked List is a variation of a doubly linked list in which the last node points back to the first node, and the first node points to the last node.' +tags: [dsa, data-structures, Circular Doubly Linked List] +--- + +### Introduction to Circular Doubly Linked List + +A **Circular Doubly Linked List** is a variation of a doubly linked list in which the last node points back to the first node, and the first node points to the last node. Each node contains three parts: +- Value: The data value stored in the node. +- Next Pointer: A pointer/reference to the next node in the list. +- Previous Pointer: A pointer/reference to the previous node in the list. + + +![alt text](CircularDoubly.png) + + +### Circular Doubly Linked List Operations + +A Circular Doubly Linked List typically supports the following operations: + +1. **Insertion Operations** : Insertion at the beginning or end involves adjusting the next pointers, previous pointer and potentially updating the head pointer. +- **At the Beginning** +- **At the End** +- **After a Given Node** + +2. **Deletion Operations** : Deletion of nodes, whether from the beginning, end, or a specific node, requires properly updating the references of adjacent nodes. +- **Delete from the Beginning** +- **Delete from the End** +- **Delete by Key** + +3. **Search Operation** : The search operation traverses the list until it either finds the required node or returns to the head. + +4. **Traversal Operation** : Traversal begins from the head and continues until the node just before the head is encountered again. + +### Pseudocode + +#### Basic Operations + +1. **Insert at the Beginning**: + + ```text + function insertAtBeginning(list : CircularDoublyLinkedList, value : DataType) { + newNode = new Node(value) + if list.head is null { + newNode.next = newNode + newNode.prev = newNode + list.head = newNode + } else { + newNode.next = list.head + newNode.prev = list.tail + list.tail.next = newNode + list.head.prev = newNode + list.head = newNode + } + } + ``` + +2. **Insert at the End**: + + ```text + function insertAtEnd(list : CircularDoublyLinkedList, value : DataType) { + newNode = new Node(value) + if list.head is null { + newNode.next = newNode + newNode.prev = newNode + list.head = newNode + } else { + newNode.next = list.head + newNode.prev = list.tail + list.tail.next = newNode + list.head.prev = newNode + } + list.tail = newNode + } + ``` + +3. **Insert After a Given Node**: + + ```text + function insertAfter(list : CircularDoublyLinkedList, node : Node, value : DataType) { + if node is null { + return // Invalid node + } + newNode = new Node(value) + newNode.next = node.next + newNode.prev = node + + node.next.prev = newNode + node.next = newNode + + if node is list.tail { + list.tail = newNode // Update tail if necessary + } + } + + ``` + +4. **Delete a Node**: + + ```text + function deleteNode(list : CircularDoublyLinkedList, node : Node) { + if node is null { + return // Invalid node + } + if node.next is node { // Only node in the list + list.head = null + } else { + node.prev.next = node.next + node.next.prev = node.prev + + if node is list.head { + list.head = node.next // Update head if necessary + } + if node is list.tail { + list.tail = node.prev // Update tail if necessary + } + } + } + + ``` + +5. **Traverse Forward**: + + ```text + function traverseForward(list : CircularDoublyLinkedList) { + if list.head is null { + return // List is empty + } + current = list.head + do { + print(current.value) + current = current.next + } while current is not list.head + } + + ``` + +6. **Traverse Backward** + + ```text + function traverseBackward(list : CircularDoublyLinkedList) { + if list.tail is null { + return // List is empty + } + current = list.tail + do { + print(current.value) + current = current.prev + } while current is not list.tail + } + ``` + + +### Implementation in Python, C++, and Java + +#### Python Implementation + +```python +class Node: + def __init__(self, value): + self.value = value + self.next = None + self.prev = None + +class CircularDoublyLinkedList: + def __init__(self): + self.head = None + self.tail = None + + def insert_at_beginning(self, value): + new_node = Node(value) + if not self.head: + new_node.next = new_node + new_node.prev = new_node + self.head = new_node + self.tail = new_node + else: + new_node.next = self.head + new_node.prev = self.tail + self.tail.next = new_node + self.head.prev = new_node + self.head = new_node + + def insert_at_end(self, value): + new_node = Node(value) + if not self.head: + new_node.next = new_node + new_node.prev = new_node + self.head = new_node + self.tail = new_node + else: + new_node.next = self.head + new_node.prev = self.tail + self.tail.next = new_node + self.head.prev = new_node + self.tail = new_node + + def insert_after(self, prev_node, value): + if prev_node is None: + return + new_node = Node(value) + new_node.next = prev_node.next + new_node.prev = prev_node + prev_node.next.prev = new_node + prev_node.next = new_node + if prev_node is self.tail: + self.tail = new_node + + def delete_node(self, node): + if node is None: + return + if node.next == node: # Only one node + self.head = None + self.tail = None + else: + node.prev.next = node.next + node.next.prev = node.prev + if node is self.head: + self.head = node.next + if node is self.tail: + self.tail = node.prev + + def traverse_forward(self): + if not self.head: + return + current = self.head + while True: + print(current.value, end=' ') + current = current.next + if current == self.head: + break + print() + + def traverse_backward(self): + if not self.tail: + return + current = self.tail + while True: + print(current.value, end=' ') + current = current.prev + if current == self.tail: + break + print() + +# Example Usage +if __name__ == "__main__": + circular_dll = CircularDoublyLinkedList() + circular_dll.insert_at_beginning(10) + circular_dll.insert_at_end(20) + circular_dll.insert_at_end(30) + circular_dll.insert_at_beginning(5) + circular_dll.traverse_forward() # Output: 5 10 20 30 + circular_dll.traverse_backward() # Output: 30 20 10 5 + +``` + +#### C++ Implementation + +```cpp +#include +using namespace std; + +class Node { +public: + int value; + Node* next; + Node* prev; + + Node(int value) { + this->value = value; + this->next = nullptr; + this->prev = nullptr; + } +}; + +class CircularDoublyLinkedList { +public: + Node* head; + Node* tail; + + CircularDoublyLinkedList() { + head = nullptr; + tail = nullptr; + } + + void insertAtBeginning(int value) { + Node* newNode = new Node(value); + if (!head) { // If the list is empty + newNode->next = newNode; + newNode->prev = newNode; + head = newNode; + tail = newNode; + } else { + newNode->next = head; + newNode->prev = tail; + tail->next = newNode; + head->prev = newNode; + head = newNode; + } + } + + void insertAtEnd(int value) { + Node* newNode = new Node(value); + if (!head) { // If the list is empty + newNode->next = newNode; + newNode->prev = newNode; + head = newNode; + tail = newNode; + } else { + newNode->next = head; + newNode->prev = tail; + tail->next = newNode; + head->prev = newNode; + tail = newNode; + } + } + + void insertAfter(Node* prevNode, int value) { + if (prevNode == nullptr) return; + Node* newNode = new Node(value); + newNode->next = prevNode->next; + newNode->prev = prevNode; + prevNode->next->prev = newNode; + prevNode->next = newNode; + if (prevNode == tail) { + tail = newNode; + } + } + + void deleteNode(Node* node) { + if (node == nullptr) return; + if (node->next == node) { // Only one node + head = nullptr; + tail = nullptr; + } else { + node->prev->next = node->next; + node->next->prev = node->prev; + if (node == head) { + head = node->next; + } + if (node == tail) { + tail = node->prev; + } + } + } + + void traverseForward() { + if (!head) return; + Node* current = head; + do { + cout << current->value << " "; + current = current->next; + } while (current != head); + cout << endl; + } + + void traverseBackward() { + if (!tail) return; + Node* current = tail; + do { + cout << current->value << " "; + current = current->prev; + } while (current != tail); + cout << endl; + } +}; + +// Example Usage +int main() { + CircularDoublyLinkedList circularDLL; + circularDLL.insertAtBeginning(10); + circularDLL.insertAtEnd(20); + circularDLL.insertAtEnd(30); + circularDLL.insertAtBeginning(5); + circularDLL.traverseForward(); // Output: 5 10 20 30 + circularDLL.traverseBackward(); // Output: 30 20 10 5 + return 0; +} +``` + +#### Java Implementation + +```java +class Node { + int value; + Node next; + Node prev; + + Node(int value) { + this.value = value; + this.next = null; + this.prev = null; + } +} + +class CircularDoublyLinkedList { + Node head; + Node tail; + + CircularDoublyLinkedList() { + head = null; + tail = null; + } + + void insertAtBeginning(int value) { + Node newNode = new Node(value); + if (head == null) { + newNode.next = newNode; + newNode.prev = newNode; + head = newNode; + tail = newNode; + } else { + newNode.next = head; + newNode.prev = tail; + tail.next = newNode; + head.prev = newNode; + head = newNode; + } + } + + void insertAtEnd(int value) { + Node newNode = new Node(value); + if (head == null) { + newNode.next = newNode; + newNode.prev = newNode; + head = newNode; + tail = newNode; + } else { + newNode.next = head; + newNode.prev = tail; + tail.next = newNode; + head.prev = newNode; + tail = newNode; + } + } + + void insertAfter(Node prevNode, int value) { + if (prevNode == null) return; + Node newNode = new Node(value); + newNode.next = prevNode.next; + newNode.prev = prevNode; + prevNode.next.prev = newNode; + prevNode.next = newNode; + if (prevNode == tail) { + tail = newNode; + } + } + + void deleteNode(Node node) { + if (node == null) return; + if (node.next == node) { // Only one node + head = null; + tail = null; + } else { + node.prev.next = node.next; + node.next.prev = node.prev; + if (node == head) { + head = node.next; + } + if (node == tail) { + tail = node.prev; + } + } + } + + void traverseForward() { + if (head == null) return; + Node current = head; + do { + System.out.print(current.value + " "); + current = current.next; + } while (current != head); + System.out.println(); + } + + void traverseBackward() { + if (tail == null) return; + Node current = tail; + do { + System.out.print(current.value + " "); + current = current.prev; + } while (current != tail); + System.out.println(); + } + + // Example Usage + public static void main(String[] args) { + CircularDoublyLinkedList circularDLL = new CircularDoublyLinkedList(); + circularDLL.insertAtBeginning(10); + circularDLL.insertAtEnd(20); + circularDLL.insertAtEnd(30); + circularDLL.insertAtBeginning(5); + circularDLL.traverseForward(); // Output: 5 10 20 30 + circularDLL.traverseBackward(); // Output: 30 20 10 5 + } +} +``` + +### Complexity + +- **Time Complexity**: + + - Insertion : $O(1)$ + - Deletion: $O(1)$ + - Traversal: $O(n)$ + +- **Space Complexity**: $O(1)$ + + +### Conclusion + +The Circular Doubly Linked List (CDLL) is a versatile data structure that combines the advantages of both doubly linked lists and circular linked lists. By allowing traversal in both forward and backward directions, CDLLs facilitate efficient data manipulation and navigation. \ No newline at end of file diff --git a/docs/linked-list/doubly-linked-list.md b/docs/linked-list/doubly-linked-list.md new file mode 100644 index 000000000..9002d551a --- /dev/null +++ b/docs/linked-list/doubly-linked-list.md @@ -0,0 +1,410 @@ +--- +id: introduction-to-DoublyLinkedList +title: Doubly Linked List Data Structure +sidebar_label: Introduction to Doubly Linked List +sidebar_position: 4 +description: 'A Doubly Linked List (DLL) is a type of linked data structure that consists of nodes. Each node contains three fields: data, a pointer to the next node, and a pointer to the previous node. This structure allows traversal in both directions—forward and backward.' +tags: [dsa, data-structures, Doubly LinkedList] +--- + +### Introduction to Doubly Linked List + +A **Doubly LinkedList** is a variation of a linked list where the last node points back to the first node instead of null (or None in Python). This structure allows for a Doubly traversal where one can start from any node and eventually return to the same node. Doubly linked lists can be either singly or doubly linked. + +![alt text](DoublyLL.png) + + +### Doubly LinkedList Operations + +A Doubly LinkedList typically supports the following operations: + +1. **Insertion Operations** : Insertion at the beginning or end involves adjusting the next pointers to maintain the Doubly nature, and potentially updating the head pointer. +- **At the Beginning** +- **At the End** +- **After a Given Node** + +2. **Deletion Operations** : Deletion of nodes, whether from the beginning, end, or a specific node, requires properly updating the references of adjacent nodes so that the Doubly structure is maintained. +- **Delete from the Beginning** +- **Delete from the End** +- **Delete by Key** + +3. **Search Operation** : The search operation traverses the list until it either finds the required node or returns to the head. + +4. **Traversal Operation** : Traversal begins from the head and continues until the node just before the head is encountered again. + +### Pseudocode + +#### Basic Operations + +1. **Insert at the Beginning**: + + ```text + function insertAtBeginning(list : DoublyLinkedList, value : DataType) { + newNode = new Node(value) + if list.head is null { + list.head = newNode + list.tail = newNode + } else { + newNode.next = list.head + list.head.prev = newNode + list.head = newNode + } + } + ``` + +2. **Insert at the End**: + + ```text + function insertAtEnd(list : DoublyLinkedList, value : DataType) { + newNode = new Node(value) + if list.tail is null { + list.head = newNode + list.tail = newNode + } else { + list.tail.next = newNode + newNode.prev = list.tail + list.tail = newNode + } + } + ``` + +3. **Insert after a given node**: + + ```text + function insertAfter(list : DoublyLinkedList, node : Node, value : DataType) { + if node is null { + return // Invalid node + } + newNode = new Node(value) + newNode.next = node.next + newNode.prev = node + + if node.next is not null { + node.next.prev = newNode + } + node.next = newNode + + if node is list.tail { + list.tail = newNode // Update tail if necessary + } + } + ``` + +4. **Delete a Node**: + + ```text + function deleteNode(list : DoublyLinkedList, node : Node) { + if node is null { + return // Invalid node + } + if node.prev is not null { + node.prev.next = node.next + } else { + list.head = node.next // Update head if it's the first node + } + + if node.next is not null { + node.next.prev = node.prev + } else { + list.tail = node.prev // Update tail if it's the last node + } + + // Optional: Clear the node to help with garbage collection + node = null + } + ``` + +5. **Traverse Forward**: + + ```text + function traverseForward(list : DoublyLinkedList) { + current = list.head + while current is not null { + print(current.value) + current = current.next + } + } + ``` + +6. **Traverse Backward** + + ```text + function traverseBackward(list : DoublyLinkedList) { + current = list.tail + while current is not null { + print(current.value) + current = current.prev + } + } + ``` + + +### Implementation in Python, C++, and Java + +#### Python Implementation + +```python +class Node: + def __init__(self, data): + self.data = data + self.next = None + self.prev = None + + +class DoublyLinkedList: + def __init__(self): + self.head = None + + def insert_at_beginning(self, data): + new_node = Node(data) + new_node.next = self.head + if self.head is not None: + self.head.prev = new_node + self.head = new_node + + def insert_at_end(self, data): + new_node = Node(data) + if self.head is None: + self.head = new_node + return + last = self.head + while last.next: + last = last.next + last.next = new_node + new_node.prev = last + + def delete_node(self, key): + current = self.head + while current: + if current.data == key: + if current.prev: + current.prev.next = current.next + if current.next: + current.next.prev = current.prev + if current == self.head: + self.head = current.next + del current + return + current = current.next + print(f"Node with value {key} not found.") + + def display(self): + current = self.head + while current: + print(current.data, end=" <=> ") + current = current.next + print("None") + + +# Example usage +if __name__ == "__main__": + dll = DoublyLinkedList() + dll.insert_at_end(10) + dll.insert_at_end(20) + dll.insert_at_beginning(5) + dll.display() # Output: 5 <=> 10 <=> 20 <=> None + dll.delete_node(10) + dll.display() # Output: 5 <=> 20 <=> None + +``` + +#### C++ Implementation + +```cpp +#include +using namespace std; + +class Node { +public: + int data; + Node* next; + Node* prev; + + Node(int data) { + this->data = data; + this->next = nullptr; + this->prev = nullptr; + } +}; + +class DoublyLinkedList { +public: + Node* head; + + DoublyLinkedList() { + head = nullptr; + } + + void insertAtBeginning(int data) { + Node* newNode = new Node(data); + newNode->next = head; + if (head != nullptr) { + head->prev = newNode; + } + head = newNode; + } + + void insertAtEnd(int data) { + Node* newNode = new Node(data); + if (head == nullptr) { + head = newNode; + return; + } + Node* last = head; + while (last->next != nullptr) { + last = last->next; + } + last->next = newNode; + newNode->prev = last; e + } + + void deleteNode(int key) { + Node* current = head; + while (current != nullptr) { + if (current->data == key) { + if (current->prev != nullptr) { + current->prev->next = current->next; + } + if (current->next != nullptr) { + current->next->prev = current->prev; + } + if (current == head) { + head = current->next; + } + delete current; + return; + } + current = current->next; + } + cout << "Node with value " << key << " not found." << endl; + } + + void display() { + Node* current = head; + while (current != nullptr) { + cout << current->data << " <=> "; + current = current->next; + } + cout << "None" << endl; + } +}; + +// Example usage +int main() { + DoublyLinkedList dll; + dll.insertAtEnd(10); + dll.insertAtEnd(20); + dll.insertAtBeginning(5); + dll.display(); // Output: 5 <=> 10 <=> 20 <=> None + dll.deleteNode(10); + dll.display(); // Output: 5 <=> 20 <=> None + return 0; +} + +``` + +#### Java Implementation + +```java +class Node { + int data; + Node next; + Node prev; + + public Node(int data) { + this.data = data; + this.next = null; + this.prev = null; + } +} + +class DoublyLinkedList { + Node head; + + public DoublyLinkedList() { + head = null; + } + + public void insertAtBeginning(int data) { + Node newNode = new Node(data); + newNode.next = head; + if (head != null) { + head.prev = newNode; + } + head = newNode; + } + + public void insertAtEnd(int data) { + Node newNode = new Node(data); + if (head == null) { + head = newNode; + return; + } + Node last = head; + while (last.next != null) { + last = last.next; + } + last.next = newNode; + newNode.prev = last; + } + + public void deleteNode(int key) { + Node current = head; + while (current != null) { + if (current.data == key) { + if (current.prev != null) { + current.prev.next = current.next; + } + if (current.next != null) { + current.next.prev = current.prev; + } + if (current == head) { + head = current.next; + } + return; + } + current = current.next; + } + System.out.println("Node with value " + key + " not found."); + } + + public void display() { + Node current = head; + while (current != null) { + System.out.print(current.data + " <=> "); + current = current.next; + } + System.out.println("None"); + } +} + +// Example usage +public class Main { + public static void main(String[] args) { + DoublyLinkedList dll = new DoublyLinkedList(); + dll.insertAtEnd(10); + dll.insertAtEnd(20); + dll.insertAtBeginning(5); + dll.display(); // Output: 5 <=> 10 <=> 20 <=> None + dll.deleteNode(10); + dll.display(); // Output: 5 <=> 20 <=> None + } +} + +``` + +### Complexity + +- **Time Complexity**: + + - Insertion : $O(1)$ + - Deletion: $O(1)$ + - Search: $O(n)$ + - Traversal: $O(n)$ + +- **Space Complexity**: $O(1)$ + + +### Conclusion + +Doubly Linked Lists are powerful and versatile data structures that allow for efficient insertion and deletion from both ends and provides flexibility in traversing the list. \ No newline at end of file diff --git a/docs/linked-list/floyds-cycle-detection.md b/docs/linked-list/floyds-cycle-detection.md new file mode 100644 index 000000000..f776549cd --- /dev/null +++ b/docs/linked-list/floyds-cycle-detection.md @@ -0,0 +1,105 @@ +--- +id: floyds-cycle-detection +title: Floyd's Cycle Detection Algorithm +sidebar_label: Floyd's Cycle Detection +sidebar_position: 3 +description: 'Floyd’s Cycle Detection Algorithm, also called the Tortoise and Hare Algorithm, is a method used to detect cycles in a linked list. It uses two pointers that move at different speeds through the list to determine if a cycle exists.' +tags: [dsa, algorithms, cycle-detection, linkedList] +--- + +### Introduction + +Floyd's Cycle Detection Algorithm, also known as the **Tortoise and Hare** algorithm, is a two-pointer technique used to detect the presence of a cycle in a linked list. Named after the story of the tortoise and the hare, the algorithm relies on two pointers moving at different speeds—one fast and one slow—to identify if a loop exists in a linked list. + +The algorithm efficiently detects cycles with a time complexity of $O(n)$ and does not require extra space, making it a more memory-efficient solution compared to hash-based methods. + +### How the Algorithm Works + +Imagine you have a circular race track, and two runners are running around it. One is slower (the tortoise), and the other is faster (the hare). If the track is circular (i.e., there is a cycle), the faster runner will eventually lap the slower runner. This same concept is applied in Floyd's algorithm for linked lists: + +1. **Two Pointers (Tortoise and Hare)**: + - The **Tortoise** moves one step at a time. + - The **Hare** moves two steps at a time. + +2. **Cycle Detection**: + - If the linked list has a cycle, the hare will eventually meet the tortoise inside the loop. + - If the hare reaches the end of the list (`NULL`), the list is cycle-free. + +### Applications + +- **Cycle Detection in Linked Lists**: The algorithm is widely used in detecting cycles in singly linked lists, particularly in problems related to data structures and algorithms. +- **Cycle Detection in Graphs**: Though not limited to linked lists, variations of this algorithm are also applied to detect cycles in directed and undirected graphs. +- **Fast and Memory-Efficient**: Unlike using hash sets to store visited nodes, Floyd's algorithm uses constant space. + +### Algorithm Steps + +1. Initialize two pointers, `slow` and `fast`, both starting at the head of the linked list. +2. Move the `slow` pointer one step at a time and the `fast` pointer two steps at a time. +3. If there is a cycle, the `slow` and `fast` pointers will eventually meet. +4. If the `fast` pointer reaches the end of the list (i.e., encounters `NULL`), there is no cycle. + +### Pseudocode + +```text +Function detectCycle(head): + If head is NULL: + Return False + Initialize slow = head and fast = head + While fast is not NULL and fast.next is not NULL: + Move slow by one node (slow = slow.next) + Move fast by two nodes (fast = fast.next.next) + If slow == fast: + Return True # Cycle detected + Return False # No cycle detected +``` +### Implementation in C++ + +```cpp +#include +using namespace std; + +class ListNode { +public: + int val; + ListNode* next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +bool hasCycle(ListNode* head) { + if (!head || !head->next) return false; + + ListNode* slow = head; + ListNode* fast = head; + + while (fast && fast->next) { + slow = slow->next; + fast = fast->next->next; + if (slow == fast) { + return true; + } + } + return false; +} + +// Example usage +int main() { + ListNode* head = new ListNode(3); + head->next = new ListNode(2); + head->next->next = new ListNode(0); + head->next->next->next = new ListNode(-4); + head->next->next->next->next = head->next; // Creating a cycle + + if (hasCycle(head)) { + cout << "Cycle detected!" << endl; + } else { + cout << "No cycle." << endl; + } + + return 0; +} +``` +### Time and Space Complexity +- Time Complexity: $O(n)$ +In the worst case, both pointers will traverse the entire list once. +- Space Complexity: $O(1)$ +This algorithm only uses a constant amount of extra memory, regardless of the size of the input. diff --git a/docs/linked-list/gircular-linked-list.md b/docs/linked-list/gircular-linked-list.md new file mode 100644 index 000000000..34b786750 --- /dev/null +++ b/docs/linked-list/gircular-linked-list.md @@ -0,0 +1,640 @@ +--- +id: introduction-to-CircularLinkedList +title: Circular Linked List Data Structure +sidebar_label: Introduction to Circular Linked List +sidebar_position: 2 +description: 'A Circular Linked List is a linked data structure where the last node points back to the first node, forming a circle. This structure allows for efficient traversal and can be either singly or doubly linked. ' +tags: [dsa, data-structures, Circular LinkedList] +--- + +### Introduction to Circular Linked List + +A **Circular LinkedList** is a variation of a linked list where the last node points back to the first node instead of null (or None in Python). This structure allows for a circular traversal where one can start from any node and eventually return to the same node. Circular linked lists can be either singly or doubly linked. + +![alt text](CircularLinkedList.png) + + +### Circular LinkedList Operations + +A Circular LinkedList typically supports the following operations: + +1. **Insertion Operations** : Insertion at the beginning or end involves adjusting the next pointers to maintain the circular nature, and potentially updating the head pointer. +- **At the Beginning** +- **At the End** +- **After a Given Node** + +2. **Deletion Operations** : Deletion of nodes, whether from the beginning, end, or a specific node, requires properly updating the references of adjacent nodes so that the circular structure is maintained. +- **Delete from the Beginning** +- **Delete from the End** +- **Delete by Key** + +3. **Search Operation** : The search operation traverses the list until it either finds the required node or returns to the head. + +4. **Traversal Operation** : Traversal begins from the head and continues until the node just before the head is encountered again. + +### Pseudocode + +#### Basic Operations + +1. **Insert at the Beginning**: + + ```text + Function insert_at_beginning(data): + Create new_node with data + If head is NULL: + head = new_node + new_node.next = head # Points to itself + Else: + Set temp = head + While temp.next != head: + Move temp to temp.next # Traverse to last node + Set new_node.next = head + Set temp.next = new_node # Last node points to new_node + Set head = new_node # Update the head to the new node + End Function + ``` + +2. **Insert at the End**: + + ```text + Function insert_at_end(data): + Create new_node with data + If head is NULL: + head = new_node + new_node.next = head # Points to itself + Else: + Set temp = head + While temp.next != head: + Move temp to temp.next # Traverse to last node + Set temp.next = new_node + Set new_node.next = head # New node points to head + End Function + ``` + +3. **Delete Node by Value**: + + ```text + Function insert_after(prev_data, data): + Create new_node with data + If head is NULL: + Exit Function # List is empty + Else: + Set temp = head + While temp.data != prev_data: + Move temp to temp.next + If temp == head: + Print "Node not found" + Exit Function + Set new_node.next = temp.next # Link new_node to temp's next node + Set temp.next = new_node # Link temp to new_node + End Function + ``` + +4. **Search for a Node**: + + ```text + Function delete_beginning(): + If head is NULL: + Exit Function # List is empty + If head.next == head: # Only one node + head = NULL + Else: + Set temp = head + While temp.next != head: + Move temp to temp.next # Traverse to last node + Set temp.next = head.next # Last node points to second node + Set head = head.next # Update head to the second node + End Function + ``` + +5. **Traverse and Print the List**: + + ```text + Function delete_end(): + If head is NULL: + Exit Function # List is empty + If head.next == head: # Only one node + head = NULL + Else: + Set temp = head + Set prev = NULL + While temp.next != head: + Set prev = temp # Keep track of second last node + Move temp to temp.next + Set prev.next = head # Second last node points to head + End Function + ``` + +6. **Deletion of a Specific Node** + + ```text + Function delete_node(key): + If head is NULL: + Exit Function # List is empty + If head.data == key AND head.next == head: # Only one node + head = NULL + Else If head.data == key: + Set temp = head + While temp.next != head: + Move temp to temp.next # Traverse to last node + Set temp.next = head.next # Last node points to second node + Set head = head.next # Update head to the second node + Else: + Set temp = head + Set prev = NULL + While temp.data != key: + Set prev = temp # Keep track of previous node + Move temp to temp.next + If temp == head: + Print "Node not found" + Exit Function + Set prev.next = temp.next # Remove the node by linking prev to temp.next + End Function + ``` + +7. **Traversal (Displaying the List)** + + ```text + Function display(): + If head is NULL: + Print "List is empty" + Else: + Set temp = head + Do: + Print temp.data + Move temp to temp.next + While temp != head + End Function + ``` + +8. **Search for a Node** + + ```text + Function search(key): + If head is NULL: + Return False # List is empty + Set temp = head + Do: + If temp.data == key: + Return True # Node found + Move temp to temp.next + While temp != head + Return False # Node not found + End Function + ``` + + +### Implementation in Python, C++, and Java + +#### Python Implementation + +```python +class Node: + def __init__(self, data): + self.data = data + self.next = None + +class CircularLinkedList: + def __init__(self): + self.head = None + + def insert_beginning(self, data): + new_node = Node(data) + if not self.head: + self.head = new_node + new_node.next = self.head + else: + temp = self.head + while temp.next != self.head: + temp = temp.next + new_node.next = self.head + temp.next = new_node + self.head = new_node + + def insert_end(self, data): + new_node = Node(data) + if not self.head: + self.head = new_node + new_node.next = self.head + else: + temp = self.head + while temp.next != self.head: + temp = temp.next + temp.next = new_node + new_node.next = self.head + + def insert_after_node(self, target, data): + if not self.head: + print("List is empty") + return + new_node = Node(data) + temp = self.head + while True: + if temp.data == target: + new_node.next = temp.next + temp.next = new_node + return + temp = temp.next + if temp == self.head: + break + print(f"Node with data {target} not found.") + + def delete_by_key(self, key): + if not self.head: + print("List is empty") + return + current = self.head + prev = None + while True: + if current.data == key: + if prev: + prev.next = current.next + else: + # Deleting head + if current.next == self.head: + self.head = None + else: + temp = self.head + while temp.next != self.head: + temp = temp.next + self.head = current.next + temp.next = self.head + return + prev = current + current = current.next + if current == self.head: + break + print(f"Key {key} not found.") + + def search(self, key): + if not self.head: + return False + temp = self.head + while True: + if temp.data == key: + return True + temp = temp.next + if temp == self.head: + break + return False + + def display(self): + nodes = [] + if self.head: + temp = self.head + while True: + nodes.append(temp.data) + temp = temp.next + if temp == self.head: + break + print(" -> ".join(map(str, nodes))) + +# Example Usage +cll = CircularLinkedList() +cll.insert_end(1) + cll.insert_end(2) + cll.insert_end(3) + cll.display() # Output: 1 -> 2 -> 3 + + cll.insert_beginning(0) + cll.display() # Output: 0 -> 1 -> 2 -> 3 + + cll.insert_after_node(2, 2.5) + cll.display() # Output: 0 -> 1 -> 2 -> 2.5 -> 3 + + cll.delete_by_key(2) + cll.display() # Output: 0 -> 1 -> 2.5 -> 3 + + print("Search for 2:", cll.search(2)) # Output: False + print("Search for 2.5:", cll.search(2.5)) # Output: True + +``` + +#### C++ Implementation + +```cpp +#include +using namespace std; + +class Node { +public: + int data; + Node* next; + + Node(int data) { + this->data = data; + this->next = nullptr; + } +}; + +class CircularLinkedList { +public: + Node* head; + + CircularLinkedList() { + head = nullptr; + } + + void append(int data) { + Node* newNode = new Node(data); + if (head == nullptr) { + head = newNode; + newNode->next = head; + } else { + Node* temp = head; + while (temp->next != head) { + temp = temp->next; + } + temp->next = newNode; + newNode->next = head; + } + } + + void insertBeginning(int data) { + Node* newNode = new Node(data); + if (head == nullptr) { + head = newNode; + newNode->next = head; + } else { + Node* temp = head; + while (temp->next != head) + temp = temp->next; + newNode->next = head; + temp->next = newNode; + head = newNode; + } + } + + void insertEnd(int data) { + Node* newNode = new Node(data); + if (head == nullptr) { + head = newNode; + newNode->next = head; + } else { + Node* temp = head; + while (temp->next != head) + temp = temp->next; + temp->next = newNode; + newNode->next = head; + } + } + + void insertAfterNode(int target, int data) { + if (head == nullptr) { + cout << "List is empty" << endl; + return; + } + Node* temp = head; + do { + if (temp->data == target) { + Node* newNode = new Node(data); + newNode->next = temp->next; + temp->next = newNode; + return; + } + temp = temp->next; + } while (temp != head); + cout << "Node with data " << target << " not found." << endl; + } + + void deleteByKey(int key) { + if (head == nullptr) { + cout << "List is empty" << endl; + return; + } + Node* current = head; + Node* prev = nullptr; + do { + if (current->data == key) { + if (prev != nullptr) { + prev->next = current->next; + } else { + // Deleting head + if (current->next == head) { + head = nullptr; + } else { + Node* temp = head; + while (temp->next != head) + temp = temp->next; + head = current->next; + temp->next = head; + } + } + delete current; + return; + } + prev = current; + current = current->next; + } while (current != head); + cout << "Key " << key << " not found." << endl; + } + + bool search(int key) { + if (head == nullptr) + return false; + Node* temp = head; + do { + if (temp->data == key) + return true; + temp = temp->next; + } while (temp != head); + return false; + } + + void display() { + if (head != nullptr) { + Node* temp = head; + do { + cout << temp->data << " -> "; + temp = temp->next; + } while (temp != head); + cout << endl; + } + } +}; + +// Example Usage +int main() { + CircularLinkedList cll; + cll.insertEnd(1); + cll.insertEnd(2); + cll.insertEnd(3); + cll.display(); // Output: 1 -> 2 -> 3 -> + + cll.insertBeginning(0); + cll.display(); // Output: 0 -> 1 -> 2 -> 3 -> + + cll.insertAfterNode(2, 2.5); + cll.display(); // Output: 0 -> 1 -> 2 -> 2.5 -> 3 -> + + cll.deleteByKey(2); + cll.display(); // Output: 0 -> 1 -> 2.5 -> 3 -> + + cout << "Search for 2: " << (cll.search(2) ? "Found" : "Not Found") << endl; // Output: Not Found + cout << "Search for 2.5: " << (cll.search(2.5) ? "Found" : "Not Found") << endl; // Output: Found + + return 0; +} + +``` + +#### Java Implementation + +```java +class Node { + int data; + Node next; + + public Node(int data) { + this.data = data; + this.next = null; + } +} + +class CircularLinkedList { + Node head; + + public CircularLinkedList() { + head = null; + } + + public void insertAtBeginning(int data) { + Node newNode = new Node(data); + if (head == null) { + head = newNode; + newNode.next = head; + } else { + Node temp = head; + while (temp.next != head) { + temp = temp.next; + } + newNode.next = head; + temp.next = newNode; + head = newNode; + } + } + + public void insertAtEnd(int data) { + Node newNode = new Node(data); + if (head == null) { + head = newNode; + newNode.next = head; + } else { + Node temp = head; + while (temp.next != head) { + temp = temp.next; + } + temp.next = newNode; + newNode.next = head; + } + } + + public void insertAfter(int prevData, int data) { + Node temp = head; + Node newNode = new Node(data); + if (head == null) { + return; + } + do { + if (temp.data == prevData) { + newNode.next = temp.next; + temp.next = newNode; + return; + } + temp = temp.next; + } while (temp != head); + } + + public void deleteNode(int key) { + if (head == null) { + return; + } + if (head.data == key && head.next == head) { + head = null; + } else if (head.data == key) { + Node temp = head; + while (temp.next != head) { + temp = temp.next; + } + temp.next = head.next; + head = head.next; + } else { + Node temp = head; + Node prev = null; + do { + if (temp.data == key) { + prev.next = temp.next; + return; + } + prev = temp; + temp = temp.next; + } while (temp != head); + } + } + + public void display() { + if (head != null) { + Node temp = head; + do { + System.out.print(temp.data + " -> "); + temp = temp.next; + } while (temp != head); + System.out.println(); + } + } + + public boolean search(int key) { + Node temp = head; + do { + if (temp.data == key) { + return true; + } + temp = temp.next; + } while (temp != head); + return false; + } + +// Example usage + public static void main(String[] args) { + CircularLinkedList cll = new cll.insertEnd(1); + cll.insertEnd(2); + cll.insertEnd(3); + cll.display(); // Output: 1 -> 2 -> 3 -> + + cll.insertBeginning(0); + cll.display(); // Output: 0 -> 1 -> 2 -> 3 -> + + cll.insertAfter(2, 2.5); + cll.display(); // Output: 0 -> 1 -> 2 -> 2.5 -> 3 -> + + cll.deleteByKey(2); + cll.display(); // Output: 0 -> 1 -> 2.5 -> 3 -> + + System.out.println("Search for 2: " + cll.search(2)); // Output: false + System.out.println("Search for 2.5: " + cll.search(2.5)); // Output: true + } +} +``` + +### Complexity + +- **Time Complexity**: + + - Insertion at the Beginning: $O(n)$ + - Insertion at the End: $O(n)$ + - Insert After Node: $O(n)$ + - Delete from Beginning: $O(n)$ + - Delete from End: $O(n)$ + - Delete by Key: $O(n)$ + - Search: $O(n)$ + - Traversal: $O(n)$ + +- **Space Complexity**: + +- Operations typically use $O(1) $ extra space as they only involve manipulating existing nodes. +- In Python's display method, storing node data in a list requires O(n) space. + + +### Conclusion + +Circular Linked Lists are versatile data structures that allow for efficient cyclic traversals. While most operations have a time complexity of O(n) due to the need to traverse the list, they offer the advantage of not having a null reference at the end, which can be beneficial in certain applications like implementing round-robin schedulers or circular queues. \ No newline at end of file diff --git a/docs/linked-list/intersection-linked-lists.md b/docs/linked-list/intersection-linked-lists.md new file mode 100644 index 000000000..2cd7700b1 --- /dev/null +++ b/docs/linked-list/intersection-linked-lists.md @@ -0,0 +1,168 @@ +--- +id: intersection-linked-lists +sidebar_position: 1 +title: "Find the Intersection Point of Two Linked Lists in C++" +description: "This tutorial explains how to find the intersection point of two singly linked lists using C++." +sidebar_label: "Linked List Intersection" +tags: [dsa, linked-lists, intersection] +--- + +## Linked List Intersection: + +This tutorial provides a C++ implementation to find the intersection point of two singly linked lists. Intersection occurs when two lists share the same nodes after a certain point. + +### Problem Statement: + +Given two singly linked lists, find the node where the two linked lists intersect. Intersection is determined based on the reference of nodes, not the value. + +### Approach: + +The key steps in the approach are as follows: + +1. **Count the Nodes in Each List**: Determine the number of nodes in both linked lists. +2. **Calculate the Difference**: Find the difference in the number of nodes between the two lists. +3. **Align the Longer List**: Traverse the longer list by the difference in lengths so that both lists now have an equal number of nodes left. +4. **Find the Intersection Point**: Traverse both lists simultaneously until the intersection is found by comparing the node addresses. + +### C++ Implementation: + +Here is the C++ code that implements this approach: + +```cpp +#include +using namespace std; + +/* Node structure */ +class Node { +public: + int data; + Node* next; +}; + +/* Function to count the number of nodes in a list */ +int getCount(Node* head); + +/* Function to get the intersection point of two linked lists */ +int getIntersectionNode(Node* head1, Node* head2); + +/* Helper function to find the intersection point */ +int findIntersection(int diff, Node* head1, Node* head2); + +/* Count the number of nodes in the linked list */ +int getCount(Node* head) { + int count = 0; + Node* current = head; + while (current != nullptr) { + count++; + current = current->next; + } + return count; +} + +/* Function to find the intersection node */ +int getIntersectionNode(Node* head1, Node* head2) { + int count1 = getCount(head1); + int count2 = getCount(head2); + int diff; + + if (count1 > count2) { + diff = count1 - count2; + return findIntersection(diff, head1, head2); + } else { + diff = count2 - count1; + return findIntersection(diff, head2, head1); + } +} + +/* Function to find the intersection node after adjusting for the difference */ +int findIntersection(int diff, Node* head1, Node* head2) { + Node* current1 = head1; + Node* current2 = head2; + + // Move the pointer of the longer list ahead by the difference in counts + for (int i = 0; i < diff; i++) { + if (current1 == nullptr) { + return -1; + } + current1 = current1->next; + } + + // Traverse both lists simultaneously to find the intersection point + while (current1 != nullptr && current2 != nullptr) { + if (current1 == current2) { + return current1->data; + } + current1 = current1->next; + current2 = current2->next; + } + + return -1; +} + +/* Driver Code */ +int main() { + Node* newNode; + + // Create two linked lists + Node* head1 = new Node(); + head1->data = 10; + Node* head2 = new Node(); + head2->data = 3; + + newNode = new Node(); + newNode->data = 6; + head2->next = newNode; + + newNode = new Node(); + newNode->data = 9; + head2->next->next = newNode; + + newNode = new Node(); + newNode->data = 15; + head1->next = newNode; + head2->next->next->next = newNode; + + newNode = new Node(); + newNode->data = 30; + head1->next->next = newNode; + + head1->next->next->next = nullptr; + + cout << "The intersection point is " << getIntersectionNode(head1, head2) << endl; + + return 0; +} +``` +## Explanation: + +## Step 1: The function getCount() counts the number of nodes in each linked list. +## Step 2: The getIntersectionNode() function computes the difference between the lengths of the two lists and calls findIntersection() to adjust the longer list. +## Step 3: The findIntersection() function aligns both lists by moving the pointer of the longer list ahead by the difference in node counts, and then simultaneously traverses both lists to find the intersection. + +Example Usage: + + +Given the following lists: +``` +List 1: 10 -> 15 -> 30 -> NULL +List 2: 3 -> 6 -> 9 -> 15 -> 30 -> NULL +``` +The output would be: +``` + The intersection point is 15 +``` +The intersection point is 15 +Time Complexity: + +Time Complexity: O(m + n), where m and n are the lengths of the two linked lists. + +Space Complexity: O(1), since no additional space is required. + + +Applications: +This method is useful in several contexts: + +Linked List Algorithms: Finding intersections is a common problem in linked list manipulation. +Networking: Detecting loops or intersections in routing tables. +Geometric Applications: Identifying overlapping paths or routes. + diff --git a/docs/linked-list/introduction-to-linked-list.md b/docs/linked-list/introduction-to-linked-list.md new file mode 100644 index 000000000..c09a759a4 --- /dev/null +++ b/docs/linked-list/introduction-to-linked-list.md @@ -0,0 +1,456 @@ +--- +id: introduction-to-linkedList +title: Linked List Data Structure +sidebar_label: Introduction to Linked List +sidebar_position: 1 +description: 'A Linked List is a linear data structure in which elements are stored in nodes, and each node points to the next node, forming a chain. Unlike arrays, linked lists do not store elements in contiguous memory locations. Instead, each node holds two main components: data and a reference (or pointer) to the next node in the sequence. This structure allows for dynamic memory allocation, meaning the list can grow or shrink as needed without reallocating or resizing.' +tags: [dsa, data-structures, LinkedList] +--- + +### Introduction to Linked List + +A **LinkedList** is a linear data structure in which elements are stored in nodes, and each node points to the next node, forming a chain. Imagine a train where each car is connected to the next car, but you can only move forward through the train. Each car contains passengers (data) and has a coupling (pointer) that connects it to the next car. + +### Definition and Structure +A linked list consists of nodes, where each node contains: +- **Data:** The value stored in the node. +- **Next:** A reference to the next node in the sequence (or `null` if there is no next node). + +The sequence starts from a node called the **head** and continues until it reaches a node that points to `null`, which marks the end of the list. + +### Properties +Key characteristics of linked lists include: +- **Dynamic Size:** Unlike arrays, linked lists can grow and shrink dynamically as nodes are added or removed. +- **Sequential Access:** Accessing elements in a linked list requires traversal from the head, as elements are not indexed like in an array. + + ``` + Head -> A -> B -> C -> D -> null + ``` + +### Types of Linked Lists +1. **Singly Linked Lists:** Each node has a reference to the next node in the sequence. + + Example: + ```plaintext + Head -> 10 -> 20 -> 30 -> null + ``` + +2. **Doubly Linked Lists:** Each node has two references—one to the next node and one to the previous node. + + Example: + ```plaintext + Head <-> 10 <-> 20 <-> 30 <-> null + ``` + +3. **Circular Linked Lists:** The last node points back to the head, forming a circular structure. + + Example: + ```plaintext + Head -> 10 -> 20 -> 30 --| + |-----------------| + ``` + +4. **Doubly Circular Linked Lists:** Similar to a circular linked list but with both next and previous references. + + Example: + ```plaintext + Head <-> 10 <-> 20 <-> 30 <-> Head + ``` +![alt text](LinkedList.png) + +### LinkedList Operations + +A LinkedList typically supports the following operations: + +1. **Insert at the Beginning**: +- A new node is created with the given data. +- The new node's next pointer is set to the current head. - The head pointer is updated to point to the new node. +2. **Insert at the End**: +- If the list is empty, the new node becomes the head. +- Otherwise, traverse the list until the last node is found, and set its next to the new node. +3. **Delete Node by Value**: +- If the head contains the key, adjust the head to point to the next node. +-Otherwise, traverse the list to find the node before the target node and adjust its next pointer to skip the target node. +4. **Search for a Node**: +- Traverse the list while comparing each node’s data with the key. +- If a match is found, return True; otherwise, after reaching the end of the list, return False. + +5. **Traverse and Print the List**: +-Traverse the list, printing the data in each node until the end of the list (NULL) is reached. + +### Advantages and Disadvantages +#### Advantages: + +- **Efficient Insertion/Deletion**: Can insert and delete nodes at any position in constant time if the node reference is known. +- **Dynamic Size**: Can easily grow and shrink in size without the need for resizing or memory reallocation like arrays. + +#### Disadvantages: + +- **No Random Access**: Unlike arrays, linked lists do not provide direct access to elements via index, requiring traversal from the head. +- **Memory Overhead**: Each node requires extra memory for storing a pointer to the next node. +- **Slow Lookups**: Finding an element requires linear time (O(n)) as the list must be traversed. + +### Applications of Linked Lists + +- **Dynamic Memory Allocation**: Linked lists provide an efficient way to manage memory when the number of elements is not known in advance. They are widely used in memory management systems to keep track of free and used memory blocks. + +- **Implementation of Other Data Structures**: Linked lists serve as the foundation for more complex data structures such as: + - **Stacks**: Dynamic stacks can be efficiently implemented using linked lists, allowing for dynamic memory usage. + - **Queues**: Linked lists are ideal for building dynamic queues, ensuring efficient insertion and deletion operations. + - **Graphs**: Linked lists are used to represent adjacency lists in graph data structures, allowing efficient traversal and manipulation of nodes. + +- **Efficient Insertions/Deletions**: For applications where elements are frequently inserted or removed, such as task scheduling or buffer management, linked lists are ideal due to their dynamic nature and minimal overhead for these operations. + +- **Polynomial Representation**: Linked lists are used to represent polynomials, where each term is stored in a node. This structure allows efficient addition and manipulation of polynomial terms. + + Example: + ```plaintext + (5x^2 + 3x + 2) -> 5 -> 3 -> 2 -> null + + +### Pseudocode + +#### Basic Operations + +1. **Insert at the Beginning**: + + ```text + Function insertAtBeginning(head, data): + Create newNode with data + Set newNode.next = head + Set head = newNode + Return head + ``` + +2. **Insert at the End**: + + ```text + Function insertAtEnd(head, data): + Create newNode with data + If head is NULL: + Set head = newNode + Return head + Set temp = head + While temp.next is not NULL: + Move temp to temp.next + Set temp.next = newNode + Return head + ``` + +3. **Delete Node by Value**: + + ```text + Function deleteNode(head, key): + If head.data equals key: + Set head = head.next + Return head + Set temp = head + While temp is not NULL and temp.next.data is not key: + Move temp to temp.next + If temp is NULL: + Return head (Key not found) + Set temp.next = temp.next.next + Return head + ``` + +4. **Search for a Node**: + + ```Function searchNode(head, key): + Set temp = head + While temp is not NULL: + If temp.data equals key: + Return True + Move temp to temp.next + Return False + ``` + +5. **Traverse and Print the List**: + + ```text + Function traverseList(head): + Set temp = head + While temp is not NULL: + Print temp.data + Move temp to temp.next + ``` + +### Implementation in Python, C++, and Java + +#### Python Implementation + +```python +class Node: + def __init__(self, data): + self.data = data + self.next = None + +class LinkedList: + def __init__(self): + self.head = None + + def insert_at_beginning(self, data): + new_node = Node(data) + new_node.next = self.head + self.head = new_node + + def insert_at_end(self, data): + new_node = Node(data) + if self.head is None: + self.head = new_node + return + last = self.head + while last.next: + last = last.next + last.next = new_node + + def delete_node(self, key): + temp = self.head + if temp is not None: + if temp.data == key: + self.head = temp.next + temp = None + return + while temp is not None: + if temp.data == key: + break + prev = temp + temp = temp.next + if temp is None: + return + prev.next = temp.next + temp = None + + def search(self, key): + current = self.head + while current: + if current.data == key: + return True + current = current.next + return False + + def print_list(self): + temp = self.head + while temp: + print(temp.data, end=" -> ") + temp = temp.next + print("None") + +# Example usage +ll = LinkedList() +ll.insert_at_end(1) +ll.insert_at_end(2) +ll.insert_at_beginning(0) +ll.print_list() # Outputs: 0 -> 1 -> 2 -> None +ll.delete_node(2) +ll.print_list() # Outputs: 0 -> 1 -> None +print(ll.search(1)) # Outputs: true +``` + +#### C++ Implementation + +```cpp +#include +using namespace std; + +class Node { +public: + int data; + Node* next; + Node(int val) : data(val), next(nullptr) {} +}; + +class LinkedList { +public: + Node* head; + + LinkedList() { head = nullptr; } + + void insertAtBeginning(int data) { + Node* newNode = new Node(data); + newNode->next = head; + head = newNode; + } + + void insertAtEnd(int data) { + Node* newNode = new Node(data); + if (head == nullptr) { + head = newNode; + return; + } + Node* last = head; + while (last->next != nullptr) { + last = last->next; + } + last->next = newNode; + } + + void deleteNode(int key) { + Node* temp = head; + if (temp != nullptr && temp->data == key) { + head = temp->next; + delete temp; + return; + } + Node* prev = nullptr; + while (temp != nullptr && temp->data != key) { + prev = temp; + temp = temp->next; + } + if (temp == nullptr) return; + prev->next = temp->next; + delete temp; + } + + bool search(int key) { + Node* current = head; + while (current != nullptr) { + if (current->data == key) + return true; + current = current->next; + } + return false; + } + + void printList() { + Node* temp = head; + while (temp != nullptr) { + cout << temp->data << " -> "; + temp = temp->next; + } + cout << "None" << endl; + } +}; + +// Example usage +int main() { + LinkedList ll; + ll.insertAtEnd(1); + ll.insertAtEnd(2); + ll.insertAtBeginning(0); + ll.printList(); //Outputs: 0 -> 1 -> 2 -> None + ll.deleteNode(2); + ll.printList(); // Outputs: 0 -> 1 -> None + cout << ll.search(1) << endl; // Outputs: true + return 0; +} +``` + +#### Java Implementation + +```java +class LinkedList { + Node head; + + class Node { + int data; + Node next; + + Node(int d) { + data = d; + next = null; + } + } + + public void insertAtBeginning(int data) { + Node newNode = new Node(data); + newNode.next = head; + head = newNode; + } + + public void insertAtEnd(int data) { + Node newNode = new Node(data); + if (head == null) { + head = newNode; + return; + } + Node last = head; + while (last.next != null) { + last = last.next; + } + last.next = newNode; + } + + public void deleteNode(int key) { + Node temp = head, prev = null; + if (temp != null && temp.data == key) { + head = temp.next; + return; + } + while (temp != null && temp.data != key) { + prev = temp; + temp = temp.next; + } + if (temp == null) return; + prev.next = temp.next; + } + + public boolean search(int key) { + Node current = head; + while (current != null) { + if (current.data == key) { + return true; + } + current = current.next; + } + return false; + } + + public void printList() { + Node temp = head; + while (temp != null) { + System.out.print(temp.data + " -> "); + temp = temp.next; + } + System.out.println("None"); + } + +// Example usage + public static void main(String[] args) { + LinkedList ll = new LinkedList(); + ll.insertAtEnd(1); + ll.insertAtEnd(2); + ll.insertAtBeginning(0); + ll.printList(); // Outputs: 0 -> 1 -> 2 -> None + ll.deleteNode(2); + ll.printList(); //Outputs: 0 -> 1 -> None + System.out.println(ll.search(1)); //Outputs: True + } +} +``` + +### Complexity + +- **Time Complexity**: + + - Insertion at the Beginning: $O(1)$ + - Insertion at the End: $O(n)$ + - Deletion by Value: $O(n)$ + - Search for a Node by Value: $O(n)$ + - Traversal (Print the List): $O(n)$ + +- **Space Complexity**: $O(n)$, where $n$ is the number of nodes. + +### Example + +Consider that you start with an empty list of student IDs and perform the following operations: + +1. Insert 101 +2. Insert 102 at the beginning +3. Insert 103 at the end +4. Insert 100 at the beginning +5. Search for a student with ID 102 +6. Delete the student with ID 103 +7. Print the final list of students + +**Operations**: + +- **Insert 101**: List: 101 +- **Insert 102 at the beginning**: List: 102 -> 101 +- **Insert 103 at the end**: List: 102 -> 101 -> 103 +- **Insert 100 at the beginning**: List: 100 -> 102 -> 101 -> 103 +- **Search for a student with ID 102**: Found: 1 (true) +- **Delete ID 103 and print final list of students**: Output: 100 -> 102 -> 101 -> None + +### Conclusion + +Singly Linked Lists (SLLs) offer dynamic memory management. They grow or shrink in size as needed, avoiding the limitations of static data structures like arrays. SLLs are excellent for applications that involve frequent insertions and deletions (especially at the beginning or middle), such as in stacks, queues, or other dynamic datasets. A singly linked list can be slower in terms of searching compared to arrays, since every search requires linear time. \ No newline at end of file diff --git a/docs/linked-list/linked-list-approaches.md b/docs/linked-list/linked-list-approaches.md new file mode 100644 index 000000000..ec525fa8c --- /dev/null +++ b/docs/linked-list/linked-list-approaches.md @@ -0,0 +1,113 @@ +--- +id: linked-list-approaches-dsa +title: Linked List Approaches +sidebar_label: Different Approaches in Linked List +sidebar_position: 6 +description: "Linked lists are dynamic data structures, and various approaches can be used to solve problems involving linked lists. This file outlines iterative and recursive approaches used to implement and manipulate linked lists." +tags: [linked-list, data-structures, approaches, dsa] +--- + +# Linked List Approaches | Problem Solving Techniques + +A **Linked List** is a linear data structure that allows dynamic memory management by linking elements (nodes) via pointers. This document outlines different approaches to solving problems involving linked lists, particularly focusing on **iterative** and **recursive** methods for common linked list operations. + +--- + +## Common Linked List Operations + +The primary operations on linked lists include: + +1. **Insertion**: Adding an element at the head, tail, or a specific position in the list. +2. **Deletion**: Removing an element from the head, tail, or a specific position. +3. **Searching**: Finding an element in the list. +4. **Traversal**: Iterating through all elements in the list. + +--- + +## Approach 1: Iterative Approach for Linked List Operations + +### Insertion at Head (Iterative) + +Inserting a new node at the head of the list involves adjusting the `next` pointer of the new node to point to the current head, and then updating the head pointer to the new node. + +```cpp +struct Node { + int data; + Node* next; +}; + +void insertAtHead(Node*& head, int value) { + Node* newNode = new Node(); + newNode->data = value; + newNode->next = head; + head = newNode; +} +``` + +## Approach 2: Recursive Approach for Linked List Operations +### Insertion at End (Recursive) +Inserting at the tail can also be done recursively. Each recursive call moves one step forward until it reaches the end of the list, where the new node is appended. + +```cpp +void insertAtEnd(Node*& head, int value) { + if (head == nullptr) { + head = new Node(); + head->data = value; + head->next = nullptr; + return; + } + + insertAtEnd(head->next, value); +} +``` +## Approach 3: Two Pointer Approach for Linked Lists +The two-pointer approach, also known as the slow and fast pointer technique, is commonly used in linked list problems such as detecting cycles or finding the middle element. + +### Detecting Cycle in a Linked List (Floyd’s Cycle Detection) +This approach uses two pointers: slow moves one step at a time, and fast moves two steps at a time. If there is a cycle, the two pointers will eventually meet. + +```cpp +bool detectCycle(Node* head) { + Node* slow = head; + Node* fast = head; + + while (fast != nullptr && fast->next != nullptr) { + slow = slow->next; + fast = fast->next->next; + + if (slow == fast) { + return true; + } + } + return false; +} +``` + +## Approach 4: Recursive Reversal of Linked List +Reversing a linked list recursively involves reversing the rest of the list, then fixing the head pointer. + +```cpp +Node* reverseRecursive(Node* head) { + if (head == nullptr || head->next == nullptr) return head; + + Node* rest = reverseRecursive(head->next); + head->next->next = head; + head->next = nullptr; + + return rest; +} +``` + +## Time and Space Complexities +### Iterative Approach +- Time Complexity: O(n) for most operations, where n is the number of nodes. +- Space Complexity: O(1) (no additional memory used). +### Recursive Approach +- Time Complexity: O(n) for most operations. +- Space Complexity: O(n) due to recursive stack space. +### Two Pointer Approach +- Time Complexity: O(n) for cycle detection and finding the middle. +- Space Complexity: O(1). +### Recursive Reversal +- Time Complexity: O(n). +- Space Complexity: O(n) due to recursion. diff --git a/docs/linked-list/merge-two-sorted-list.md b/docs/linked-list/merge-two-sorted-list.md new file mode 100644 index 000000000..5e3820c8c --- /dev/null +++ b/docs/linked-list/merge-two-sorted-list.md @@ -0,0 +1,82 @@ +--- +id: merge-two-sorted-list +sidebar_position: 1 +title: "Merge Two Sorted Linked Lists" +description: "This tutorial explains how to merge two sorted list using Cpp." +sidebar_label: "Linked List Intersection" +tags: [dsa, linked-lists, merge,cpp] +--- +# Merge Two Sorted Linked Lists + +## Problem Statement + +Given two sorted linked lists, the task is to merge them into one sorted linked list. The merged linked list should be created by splicing together the nodes of the input lists. + +### Example + +**Input:** +- `list1 = [1, 2, 4]` +- `list2 = [1, 3, 4]` + +**Output:** +- `Merged List: 1 -> 1 -> 2 -> 3 -> 4 -> 4` + +### Constraints +- Both lists are sorted in non-decreasing order. +- The output should maintain the sorted order by merging nodes directly from the input lists. + +## Solution Explanation + +To merge the two sorted linked lists: +1. **Dummy Node and Tail**: Start with a dummy node to simplify list manipulation. Use a `tail` pointer to keep track of the last node in the merged list. +2. **Comparison and Insertion**: + - Traverse both lists. For each pair of nodes from the two lists, attach the smaller node to the `tail` and move to the next node in that list. +3. **Remaining Nodes**: + - Once one list is exhausted, link the rest of the nodes from the remaining list to the `tail`. +4. **Return Merged List**: + - The merged list starts from `dummy.next` since `dummy` is just a placeholder. + +### Complexity +- **Time Complexity**: `O(n + m)`, where `n` and `m` are the lengths of the two input lists. +- **Space Complexity**: `O(1)` (in-place merging without additional data structures). + +## Code Implementation + +Here’s the C++ code for merging two sorted linked lists: + +```cpp +#include +#include +using namespace std; + +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +class Solution { +public: + ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) { + ListNode dummy(0); // Dummy node to start the merged list + ListNode* tail = &dummy; + + // Merge the lists by comparing nodes + while (list1 && list2) { + if (list1->val < list2->val) { + tail->next = list1; + list1 = list1->next; + } else { + tail->next = list2; + list2 = list2->next; + } + tail = tail->next; + } + + // Attach the remaining nodes, if any + tail->next = list1 ? list1 : list2; + + return dummy.next; // Return the head of the merged list + } +}; +``` \ No newline at end of file diff --git a/docs/linked-list/range-sum-of-linked-list.md b/docs/linked-list/range-sum-of-linked-list.md new file mode 100644 index 000000000..1438f27e0 --- /dev/null +++ b/docs/linked-list/range-sum-of-linked-list.md @@ -0,0 +1,78 @@ +--- +id: range-sum-of-linked-list +title: Range Sum of Linked List +sidebar_label: Range Sum of Linked List +description: 'Calculate the sum of node values within this range.' +tags: [dsa, data-structures, LinkedList] +--- + +### Range Sum of Linked List + +Given a linked list and a range defined by start and end (0-indexed), calculate the sum of the node values within this range. + +### Implementation in c++ + +```cpp +#include +using namespace std; + +struct ListNode { + int val; + ListNode* next; + ListNode(int x) : val(x), next(NULL) {} +}; + +int rangeSum(ListNode* head, int start, int end) { + int rangeSum = 0; // Sum of values within the range + int position = 0; // Track the current position in the list + ListNode* current = head; // Pointer to traverse the list + + // Traverse the linked list + while (current != nullptr) { + // If the position is within the specified range, add to sum + if (position >= start && position <= end) { + rangeSum += current->val; + } + + // Break if we've passed the end of the range + if (position > end) { + break; + } + + // Move to the next node and increment the position + current = current->next; + position++; + } + + return rangeSum; +} + +int main() { + // Creating a sample linked list: 1 -> 2 -> 3 -> 4 -> 5 + ListNode* head = new ListNode(1); + head->next = new ListNode(2); + head->next->next = new ListNode(3); + head->next->next->next = new ListNode(4); + head->next->next->next->next = new ListNode(5); + + // Calculate the sum of node values from position 1 to 3 (inclusive) + int start = 1; + int end = 3; + cout << "Range Sum: " << rangeSum(head, start, end) << endl; // Output should be 2 + 3 + 4 = 9 + + // Clean up the memory allocated for the linked list + ListNode* temp; + while (head != nullptr) { + temp = head; + head = head->next; + delete temp; + } + + return 0; +} +``` + +### Complexity + +- **Time Complexity**: $O(n)$ +- **Space Complexity**: $O(1)$ diff --git a/docs/linked-list/remove-duplicates-from-sorted-list.md b/docs/linked-list/remove-duplicates-from-sorted-list.md new file mode 100644 index 000000000..54dfc4b6a --- /dev/null +++ b/docs/linked-list/remove-duplicates-from-sorted-list.md @@ -0,0 +1,120 @@ +--- +id: remove-duplicates-from-sorted-list +sidebar_position: 1 +title: "Remove Duplicates from Sorted Linked Lists" +description: "This tutorial explains how to remove duplicates from sorted list using Cpp." +sidebar_label: "Linked List Intersection" +tags: [dsa, linked-lists,cpp] +--- + +# Remove Duplicates from Sorted List + +## Problem Statement + +Given the head of a sorted linked list, remove all duplicates such that each element appears only once. Return the modified linked list, which remains sorted. + +### Example + +**Input:** +- `head = [1,1,2]` + +**Output:** +- `[1,2]` + +### Constraints +- The list is sorted in non-decreasing order. +- The output should retain the sorted order with no duplicate values. + +## Solution Explanation + +To remove duplicates from the sorted linked list: +1. **Single Pass with Current Pointer**: + - Use a pointer (`current`) to traverse the list. + - At each node, compare the value of `current` with `current->next`. + - If the values are the same, update the `next` pointer of `current` to skip the duplicate node. + - If the values are different, move `current` to the next node. +2. **End Condition**: + - Continue the process until `current` reaches the end of the list. +3. **In-place Modification**: + - This algorithm modifies the list in place without additional data structures. + +### Complexity +- **Time Complexity**: `O(n)`, where `n` is the number of nodes in the linked list, as we traverse each node once. +- **Space Complexity**: `O(1)`, as it operates in constant space by modifying the list in place. + +## Code Implementation + +Here’s the C++ code for removing duplicates from a sorted linked list: + +```cpp +#include +#include +using namespace std; + +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +class Solution { +public: + ListNode* deleteDuplicates(ListNode* head) { + if (!head) return nullptr; // If list is empty, return null + + ListNode* current = head; // Start with the head of the list + + // Traverse the list + while (current && current->next) { + if (current->val == current->next->val) { + // Skip the duplicate node + ListNode* duplicate = current->next; + current->next = duplicate->next; + delete duplicate; // Free memory for the duplicate node + } else { + // Move to the next distinct element + current = current->next; + } + } + + return head; // Return the modified list without duplicates + } +}; + +// Helper function to create a linked list from an array +ListNode* createLinkedList(const vector& values) { + ListNode dummy(0); + ListNode* current = &dummy; + for (int value : values) { + current->next = new ListNode(value); + current = current->next; + } + return dummy.next; +} + +// Helper function to print a linked list +void printLinkedList(ListNode* head) { + while (head) { + cout << head->val; + if (head->next) cout << " -> "; + head = head->next; + } + cout << endl; +} + +int main() { + vector list_values = {1, 1, 2}; + ListNode* head = createLinkedList(list_values); + + cout << "Original List: "; + printLinkedList(head); + + Solution solution; + ListNode* modifiedHead = solution.deleteDuplicates(head); + + cout << "List after removing duplicates: "; + printLinkedList(modifiedHead); + + return 0; +} +``` \ No newline at end of file diff --git a/docs/machine-learning/AdaBoost.md b/docs/machine-learning/AdaBoost.md new file mode 100644 index 000000000..8cd49b790 --- /dev/null +++ b/docs/machine-learning/AdaBoost.md @@ -0,0 +1,136 @@ +--- + +id: adaboost-visualizations +title: AdaBoost Visualizations +sidebar_label: AdaBoost +description: "Implement the AdaBoost algorithm to combine multiple weak classifiers into a strong ensemble model. This feature will visualize the boosting process and support various base learners." +tags: [machine learning, ensemble methods, AdaBoost, data visualization, classifiers] + +--- + +### Definition: +**AdaBoost (Adaptive Boosting)** is a popular ensemble learning algorithm that combines the outputs of multiple weak classifiers to create a robust model. By focusing on the errors made by previous classifiers, AdaBoost iteratively improves its predictions and effectively reduces bias and variance. + +### Characteristics: +- **Weak Learners**: + Utilizes multiple weak classifiers (often decision stumps) that perform slightly better than random guessing. + +- **Adaptive Weighting**: + Adjusts the weights of misclassified samples in each iteration, allowing the model to focus more on difficult cases. + +- **Boosting Technique**: + Sequentially adds weak learners, each correcting the mistakes of its predecessors, ultimately creating a strong combined model. + +### Components of AdaBoost: +1. **Base Learners**: + Simple models (weak classifiers) that serve as the building blocks of the ensemble. + +2. **Weights**: + Each data point is assigned a weight, which is updated based on classification performance. + +3. **Final Model**: + The final strong classifier is a weighted sum of the individual weak classifiers, where the weights reflect their performance. + +### Steps Involved: +1. **Initialize Weights**: + Assign equal weights to all training samples at the start. + +2. **Train Weak Classifier**: + Fit a weak learner to the training data using the current weights. + +3. **Calculate Error**: + Compute the error rate of the weak learner based on the weighted samples. + +4. **Update Weights**: + Increase the weights of misclassified samples and decrease the weights of correctly classified samples. + +5. **Combine Classifiers**: + Add the new weak learner to the ensemble with a weight based on its performance, and repeat the process for a specified number of iterations. + +### Key Concepts: +- **Ensemble Learning**: + Combines multiple models to improve overall performance and robustness. + +- **Weight Update Rule**: + The formula used to adjust sample weights based on classification results. + +- **Final Classifier**: + The aggregate model formed from the weak learners, providing the final predictions. + +### Advantages of AdaBoost: +- **Improved Accuracy**: + Significantly enhances model performance by effectively reducing both bias and variance. + +- **Flexibility**: + Can work with various types of weak classifiers, allowing for customization based on the problem. + +- **Robustness to Overfitting**: + While more susceptible to noise, AdaBoost can perform well with appropriately selected weak learners and parameters. + +### Limitations of AdaBoost: +- **Sensitive to Noisy Data**: + Outliers can adversely affect model performance since AdaBoost focuses on misclassified samples. + +- **Weak Learner Dependency**: + The performance heavily relies on the choice of base learners; poorly chosen weak classifiers may lead to suboptimal results. + +### Popular Applications of AdaBoost: +1. **Image Recognition**: + Used to classify images by combining features from weak classifiers. + +2. **Text Classification**: + Effective for categorizing documents based on textual features. + +3. **Medical Diagnosis**: + Applied in healthcare for identifying diseases from complex datasets. + +4. **Fraud Detection**: + Helps in detecting fraudulent activities by analyzing transaction patterns. + +5. **Customer Segmentation**: + Utilized in marketing to classify customer behavior for targeted strategies. + +### Example of AdaBoost in Python: +```python +import numpy as np +from sklearn.ensemble import AdaBoostClassifier +from sklearn.tree import DecisionTreeClassifier +from sklearn.datasets import make_classification +import matplotlib.pyplot as plt + +# Create a sample dataset +X, y = make_classification(n_samples=100, n_features=20, n_informative=10, n_redundant=10) + +# Initialize the base learner +base_learner = DecisionTreeClassifier(max_depth=1) # Decision stump + +# Create AdaBoost classifier +ada_classifier = AdaBoostClassifier(base_estimator=base_learner, n_estimators=50) + +# Fit the model +ada_classifier.fit(X, y) + +# Visualize the decision boundaries +plt.figure(figsize=(8, 6)) +plt.title('AdaBoost Decision Boundaries') +plt.scatter(X[:, 0], X[:, 1], c=ada_classifier.predict(X), cmap='viridis', edgecolor='k') +plt.xlabel('Feature 1') +plt.ylabel('Feature 2') +plt.grid() +plt.show() +``` + +### Time and Space Complexity: +- **Time Complexity**: + Training complexity is approximately $O(n \cdot m \cdot t)$, where $n$ is the number of samples, $m$ is the number of features, and $t$ is the number of weak learners. + +- **Space Complexity**: + The space required is $O(t)$ for storing the weak classifiers and their weights. + +### Summary & Applications: +- **AdaBoost** is a powerful ensemble technique that enhances classification performance by leveraging the strengths of multiple weak learners. + +- **Applications**: + Commonly used in various domains, including image and text classification, fraud detection, and medical diagnosis, making it a valuable addition to any machine learning toolkit. + +--- diff --git a/docs/machine-learning/Autoencoders.md b/docs/machine-learning/Autoencoders.md new file mode 100644 index 000000000..f933ee2f9 --- /dev/null +++ b/docs/machine-learning/Autoencoders.md @@ -0,0 +1,180 @@ +--- + +id: autoencoders +title: Autoencoders +sidebar_label: Autoencoders +description: "In this post, we will explore Autoencoders, a type of artificial neural network used for unsupervised learning that focuses on efficiently encoding input data and reconstructing it." +tags: [machine learning, deep learning, autoencoders, neural networks, unsupervised learning] + +--- + +### Definition: +**Autoencoders** are a type of artificial neural network used to learn efficient representations of data in an unsupervised manner. Their goal is to map input data to a compressed representation (encoding) and then reconstruct the input data from this representation (decoding). Autoencoders are widely used for dimensionality reduction, feature learning, and data denoising. + +### Characteristics: +- **Unsupervised Learning**: + Autoencoders do not require labeled data, making them ideal for unsupervised learning tasks like dimensionality reduction and anomaly detection. + +- **Compression and Reconstruction**: + Autoencoders aim to learn a lower-dimensional encoding of the input data and reconstruct the original input as closely as possible. + +- **Symmetric Architecture**: + The network is typically symmetric, with the encoder compressing the data and the decoder reconstructing the input. + +### Components of Autoencoders: +1. **Encoder**: + The encoder maps the input data to a lower-dimensional latent space (or hidden representation) through multiple layers of neurons. This part compresses the input data into fewer dimensions. + +2. **Latent Space**: + The latent space, or bottleneck layer, represents the compressed, encoded version of the input. This space holds the most critical features needed for reconstruction. + +3. **Decoder**: + The decoder takes the compressed data from the latent space and attempts to reconstruct the original input data. The output of the decoder should ideally resemble the input. + +4. **Reconstruction Loss**: + The difference between the input data and its reconstruction (the output) is captured by a loss function. This loss, often referred to as **reconstruction loss**, is minimized during training to improve the quality of the autoencoder. + +### Types of Autoencoders: +1. **Vanilla Autoencoders**: + The simplest form of an autoencoder, consisting of an encoder and a decoder. Both parts are neural networks, and the goal is to minimize the reconstruction loss. + +2. **Denoising Autoencoders (DAE)**: + These autoencoders are designed to remove noise from input data. The input is corrupted with noise, and the autoencoder learns to reconstruct the clean, original data. + +3. **Sparse Autoencoders**: + A regularization term is added to the loss function to encourage sparsity in the latent representation. These autoencoders learn features by constraining the model to activate only a few neurons in the hidden layer. + +4. **Variational Autoencoders (VAE)**: + These autoencoders are probabilistic models that generate new data similar to the training data by learning the distribution of the input data. VAEs are used in tasks like image generation. + +5. **Convolutional Autoencoders (CAE)**: + These autoencoders apply convolutional layers instead of fully connected layers, making them suitable for tasks involving image data. CAEs are used for tasks like image denoising and compression. + +### Steps Involved: +1. **Input Data**: + The autoencoder receives raw input data (e.g., images, text, or tabular data). + +2. **Encoding**: + The encoder processes the input through multiple layers to generate a lower-dimensional latent representation. + +3. **Bottleneck/Latent Space**: + The latent space holds the compressed version of the input data. + +4. **Decoding**: + The decoder takes the latent representation and attempts to reconstruct the original input data. + +5. **Minimizing Loss**: + The network is trained to minimize reconstruction loss, which measures the difference between the input data and the reconstructed data. + +### Problem Statement: +Given a set of unlabeled data, the goal is to train an autoencoder to efficiently encode and reconstruct the data, minimizing reconstruction loss. + +### Key Concepts: +- **Dimensionality Reduction**: + Autoencoders can reduce the dimensionality of data, which helps with data visualization, compression, and speeding up downstream tasks like classification. + +- **Unsupervised Learning**: + Since autoencoders do not require labels, they are highly useful in unsupervised learning scenarios where the goal is to discover underlying structure in data. + +- **Reconstruction Loss**: + The reconstruction loss quantifies how well the autoencoder can replicate the input data from its encoded representation. Common loss functions include: + - **Mean Squared Error (MSE)**: + Measures the average squared difference between the input and output. + - **Binary Cross-Entropy**: + Used for binary or normalized input data. + +- **Latent Space Representation**: + The compressed representation in the latent space can be used for other tasks like clustering, visualization, or as input for another machine learning model. + +### Split Criteria: +Autoencoders are trained to minimize the reconstruction loss between the input and the output, so the criteria are not based on splitting but on reconstructing the input accurately. + +### Time Complexity: +- **Training Complexity**: + The time complexity depends on the number of layers and neurons in the encoder and decoder. For an autoencoder with $l$ layers and $n$ neurons per layer, the complexity is $O(n \cdot l)$. + +- **Prediction Complexity**: + The prediction or encoding complexity is also proportional to the number of layers and neurons, as the data passes through each layer of the network. + +### Space Complexity: +- **Space Complexity**: + The space complexity depends on the number of neurons and weights in the encoder and decoder, as well as the size of the latent space. + +### Example: +Consider a simple example of an autoencoder applied to **image compression**. The autoencoder compresses an input image into a lower-dimensional latent space and then reconstructs the image from this compressed version. + +#### Image Compression with Autoencoders: + +1. **Input**: + An input image is passed through the encoder, which compresses it into a latent space of reduced dimensions. + +2. **Latent Space**: + The compressed version of the image (latent representation) is much smaller than the original image but contains enough information to reconstruct it. + +3. **Reconstruction**: + The decoder reconstructs the image from the latent space representation, with the aim of minimizing reconstruction loss. + +### Python Implementation: +Here is a simple implementation of an autoencoder using **TensorFlow/Keras**: + +```python +import tensorflow as tf +from tensorflow.keras import layers, models +import numpy as np + +# Load dataset (for example, MNIST digits dataset) +(x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data() +x_train = x_train.astype('float32') / 255.0 +x_test = x_test.astype('float32') / 255.0 + +# Flatten the data (since autoencoder works on vectorized input) +x_train = x_train.reshape((x_train.shape[0], -1)) +x_test = x_test.reshape((x_test.shape[0], -1)) + +# Define Autoencoder architecture +input_dim = x_train.shape[1] + +# Encoder +input_layer = layers.Input(shape=(input_dim,)) +encoded = layers.Dense(128, activation='relu')(input_layer) +encoded = layers.Dense(64, activation='relu')(encoded) +encoded = layers.Dense(32, activation='relu')(encoded) + +# Decoder +decoded = layers.Dense(64, activation='relu')(encoded) +decoded = layers.Dense(128, activation='relu')(decoded) +decoded = layers.Dense(input_dim, activation='sigmoid')(decoded) + +# Autoencoder Model +autoencoder = models.Model(input_layer, decoded) + +# Compile the model +autoencoder.compile(optimizer='adam', loss='mse') + +# Train the autoencoder +autoencoder.fit(x_train, x_train, epochs=50, batch_size=256, shuffle=True, validation_data=(x_test, x_test)) + +# Encode and Decode Test Data +encoded_imgs = autoencoder.predict(x_test) + +# Evaluate reconstruction loss on test data +loss = autoencoder.evaluate(x_test, x_test) +print(f"Reconstruction Loss: {loss}") +``` + +### Summary and Applications: +- **Dimensionality Reduction**: + Autoencoders can reduce the dimensionality of data, providing a more compact representation useful for visualization and speeding up subsequent algorithms. + +- **Denoising**: + Denoising autoencoders can remove noise from corrupted data (e.g., images, audio) by learning how to reconstruct the clean version of the input. + +- **Anomaly Detection**: + Autoencoders can be used to detect anomalies in data by comparing the reconstruction loss. Unusual data points tend to have higher reconstruction errors. + +- **Data Compression**: + Autoencoders compress input data into a lower-dimensional space, which can be useful for storage and transmission purposes. + +- **Feature Extraction**: + The latent space representation learned by the encoder can serve as a feature vector for other machine learning tasks, such as classification or clustering. + diff --git a/docs/machine-learning/BeamSearch.md b/docs/machine-learning/BeamSearch.md new file mode 100644 index 000000000..35a103869 --- /dev/null +++ b/docs/machine-learning/BeamSearch.md @@ -0,0 +1,128 @@ +--- +id: beam-search +title: Beam Search Algorithm +sidebar_label: Beam Search +description: "This guide covers the Beam Search algorithm, a heuristic search technique commonly used in sequence generation tasks to find the most probable output sequence in machine learning." +tags: [machine learning, search algorithm, beam search, NLP, transformer] +--- + +### Definition: +**Beam Search** is a heuristic search algorithm that is widely used in sequence prediction tasks to find the most likely sequence of outputs by considering multiple candidates at each step. Beam Search is particularly useful in applications like language translation, speech recognition, and image captioning where the goal is to generate coherent, accurate sequences based on probabilities. + +### Characteristics: +- **Heuristic Search**: + Beam Search uses a probabilistic approach, evaluating multiple partial sequences at each time step and discarding less likely candidates. +- **Controlled Exploration**: + Beam Search keeps a fixed number of candidates at each step, called the "beam width," balancing between search breadth and computational efficiency. +- **Greedy Yet Flexible**: + Unlike pure greedy search, Beam Search maintains multiple candidates, allowing it to recover from locally optimal but globally suboptimal choices. + +### Components of Beam Search: +1. **Beam Width (k)**: + The beam width determines the number of candidate sequences kept at each time step. A higher beam width allows more paths to be considered but requires more computational resources. +2. **Score Calculation**: + Beam Search calculates scores for each candidate sequence by combining the probability of the sequence with additional metrics like length normalization. +3. **Pruning**: + At each time step, Beam Search keeps only the top `k` sequences with the highest scores, discarding the rest to manage computational efficiency. +4. **Termination Condition**: + The algorithm stops when all selected sequences reach an end condition, such as a specified token (`` token in NLP tasks) or a maximum length. + +### Beam Search Architecture: +1. **Input Sequence**: + The model is provided with an initial input sequence, usually a `` token for text generation tasks, to begin predicting the output sequence. +2. **Candidate Expansion**: + For each candidate sequence in the beam, the model generates probabilities for the next token in the sequence. +3. **Pruning**: + The algorithm keeps only the `k` most likely sequences at each time step, maintaining only the highest-scoring candidates. +4. **Output Selection**: + When the search reaches the termination condition, Beam Search outputs the sequence with the highest score among the final candidates. + +### Problem Statement: +Given an initial input sequence and a model that can predict probabilities for the next token in a sequence, the goal of Beam Search is to generate the most probable sequence of tokens. This is achieved by exploring multiple possible paths and discarding less probable ones to optimize search efficiency while maintaining high-quality results. + +### Key Concepts: +- **Sequence Probability**: + The overall probability of a sequence is calculated as the product of the probabilities of each token in the sequence. Beam Search aims to maximize this probability. +- **Beam Width (k)**: + Beam width controls the number of candidates explored at each step. Higher beam widths can improve output quality but also increase computation. +- **Normalization**: + Length normalization can be applied to avoid bias toward shorter or longer sequences, depending on the task. +- **Pruning Mechanism**: + Pruning reduces the search space by keeping only the top `k` candidates, discarding sequences with lower probabilities to manage computation. + +### Steps Involved in Beam Search: +1. **Initialize Beam**: + Start with the initial input token (e.g., `` in text generation) and calculate the initial probabilities for possible first tokens. +2. **Generate Candidates**: + For each sequence in the beam, generate possible next tokens and calculate their probabilities. +3. **Score and Prune**: + Compute scores for each candidate sequence by combining the probabilities of tokens in the sequence. Retain only the top `k` sequences. +4. **Repeat Until Termination**: + Continue expanding, scoring, and pruning until the sequences reach the end condition. +5. **Select Final Output**: + Output the sequence with the highest score among the remaining candidates. + +### Example: +```python +import torch +import torch.nn.functional as F + +def beam_search(model, start_token, end_token, beam_width, max_length): + # Initialize the beam with the start token + beam = [(start_token, 0.0)] # (sequence, score) + + for _ in range(max_length): + new_beam = [] + + # Expand each sequence in the current beam + for seq, score in beam: + # Stop expanding if end token is reached + if seq[-1] == end_token: + new_beam.append((seq, score)) + continue + + # Predict next token probabilities + predictions = model(torch.tensor([seq])) + probs = F.log_softmax(predictions[-1], dim=-1) + + # Get top beam_width tokens + top_tokens = torch.topk(probs, beam_width) + + # Add each top token to the new beam + for token, token_prob in zip(top_tokens.indices, top_tokens.values): + new_seq = seq + [token.item()] + new_score = score + token_prob.item() # Add log-probability + new_beam.append((new_seq, new_score)) + + # Prune to keep only top beam_width sequences + new_beam = sorted(new_beam, key=lambda x: x[1], reverse=True)[:beam_width] + beam = new_beam + + # Return the sequence with the highest score + return max(beam, key=lambda x: x[1])[0] + +# Example usage +start_token = 0 # example start token +end_token = 1 # example end token +beam_width = 3 +max_length = 10 + +# Simulate a model function +def model(input_seq): + # Dummy model function returning random probabilities for simplicity + return torch.randn(len(input_seq) + 1, 5000) + +output_sequence = beam_search(model, [start_token], end_token, beam_width, max_length) +print("Output Sequence:", output_sequence) + +``` + +### Summary & Applications of Beam Search: +- **Language Translation**: + Beam Search is frequently used in neural machine translation to generate coherent translations by maximizing the probability of the output sequence. +- **Speech Recognition**: + Beam Search helps select the most likely sequence of phonemes or words in automatic speech recognition. +- **Image Captioning**: + In image captioning, Beam Search is used to generate descriptive captions by exploring multiple candidate captions. +- **Text Summarization**: + Beam Search aids in summarizing texts by generating summary sequences with high probabilities, balancing informativeness and coherence. diff --git a/docs/machine-learning/Convolutional_Neural_Network.md b/docs/machine-learning/Convolutional_Neural_Network.md new file mode 100644 index 000000000..9a0c540b4 --- /dev/null +++ b/docs/machine-learning/Convolutional_Neural_Network.md @@ -0,0 +1,176 @@ +--- + +id: convolutional-neural-networks +title: Convolutional Neural Networks (CNN) +sidebar_label: CNNs +description: "This post explores Convolutional Neural Networks (CNN), a specialized neural network architecture widely used for tasks involving image processing and computer vision." +tags: [machine learning, deep learning, cnn, neural networks, computer vision] + +--- + +### Definition: +**Convolutional Neural Networks (CNNs)** are a class of deep neural networks specifically designed to process data with a grid-like structure, such as images. CNNs are highly effective in tasks like image classification, object detection, and recognition due to their ability to capture spatial hierarchies in data through convolutional layers. + +### Characteristics: +- **Convolutional Layers**: + CNNs use convolutional layers to automatically detect spatial features (e.g., edges, textures) from input data, reducing the number of parameters and computational cost compared to fully connected layers. + +- **Local Connectivity**: + Each neuron in a convolutional layer is connected only to a small, local region of the input data, capturing localized patterns that are useful for tasks like image and video analysis. + +- **Hierarchical Feature Learning**: + CNNs learn to extract features in a hierarchical manner, starting with low-level features (edges, textures) and progressing to more complex patterns (shapes, objects). + +### Components of CNN: +1. **Convolutional Layer**: + This layer applies a set of filters (or kernels) to the input, producing feature maps. It captures local patterns in the data by sliding the filters over the input, detecting different features at each position. + +2. **Activation Function (ReLU)**: + After convolution, a non-linear activation function, typically **ReLU (Rectified Linear Unit)**, is applied to introduce non-linearity and help the network learn complex patterns. + +3. **Pooling Layer (Subsampling)**: + The pooling layer reduces the spatial dimensions of the feature maps, summarizing the most important features and making the network more computationally efficient. Common pooling methods include **Max Pooling** and **Average Pooling**. + +4. **Fully Connected Layer**: + After the convolutional and pooling layers, the data is flattened and passed through fully connected layers. These layers combine the learned features to make predictions. + +5. **Softmax Layer (for Classification)**: + In classification tasks, the output of the last fully connected layer is passed through a **softmax** function to produce probability distributions over classes. + +### CNN Architecture: +1. **Input Layer**: + The input can be an image (e.g., 32x32 pixels with 3 color channels: RGB). CNNs can also handle other grid-like data, such as time-series or audio spectrograms. + +2. **Convolutional Layer(s)**: + Multiple convolutional layers are stacked, each extracting progressively more abstract features from the input data. + +3. **Pooling Layer(s)**: + Pooling layers (e.g., Max Pooling) are interleaved between convolutional layers to reduce the dimensionality of feature maps while retaining important information. + +4. **Fully Connected Layer(s)**: + After several convolutional and pooling layers, the feature maps are flattened and passed through fully connected layers, which serve as a classifier or regressor depending on the task. + +5. **Output Layer**: + The final fully connected layer outputs the class probabilities (for classification) or the prediction (for regression). + +### Types of Convolutions: +1. **Standard Convolution**: + A kernel is applied to the entire image, sliding over it to produce a feature map. + +2. **Depthwise Convolution**: + This type of convolution is applied separately to each input channel (e.g., RGB channels), reducing computational cost by keeping channels independent. + +3. **Dilated Convolution**: + The filter is applied with gaps between each element, allowing for a larger receptive field without increasing computational cost. + +4. **Transposed Convolution**: + Used in tasks like image generation, transposed convolutions perform the opposite operation of standard convolutions, increasing the spatial dimensions of the input. + +### Problem Statement: +Given an image dataset, the goal of a CNN is to classify the images into different categories (e.g., classifying digits in the MNIST dataset or identifying objects in CIFAR-10). CNNs are also used in segmentation, detection, and generation tasks in computer vision. + +### Key Concepts: +- **Filters (Kernels)**: + Filters are small matrices that slide over the input data to detect features like edges, corners, or textures. Multiple filters are used to detect various features. + +- **Stride**: + The number of pixels by which the filter slides over the input data. A larger stride reduces the spatial dimensions of the feature map. + +- **Padding**: + Adding pixels (typically zeros) around the input to maintain its spatial dimensions after convolution. Padding can be used to prevent shrinking of the feature maps. + +- **Receptive Field**: + The region of the input image that influences a particular feature in the output. Deeper layers in a CNN have a larger receptive field and can detect more complex features. + +- **Pooling**: + Pooling layers downsample the feature maps by summarizing regions of the data. Max pooling selects the maximum value, while average pooling computes the average. + +### Steps Involved: +1. **Input Data**: + The input is typically an image or a grid-like structure. For example, an RGB image with dimensions 32x32x3. + +2. **Convolution**: + The input is passed through convolutional layers, where multiple filters detect features like edges, corners, or textures. + +3. **Activation**: + A non-linear activation function (ReLU) is applied to the convolved output, introducing non-linearity. + +4. **Pooling**: + Pooling layers reduce the spatial dimensions of the feature maps, making the network computationally efficient. + +5. **Fully Connected Layers**: + After several convolutional and pooling layers, the feature maps are flattened and passed through fully connected layers, producing a prediction. + +6. **Output**: + For classification, the output is passed through a softmax layer, which converts the output into class probabilities. + +### Split Criteria: +CNNs split data by progressively extracting features at different layers, with lower layers detecting simple patterns (e.g., edges) and higher layers capturing complex features (e.g., objects). + +### Time Complexity: +- **Training Complexity**: + The time complexity depends on the number of filters, kernel size, and input dimensions. For an image of size $n \times n$ with $k$ filters of size $f \times f$, the time complexity of a convolutional layer is $O(n^2 \cdot f^2 \cdot k)$. + +- **Prediction Complexity**: + For inference, the time complexity depends on the depth of the network and the number of layers. + +### Space Complexity: +- **Space Complexity**: + The space complexity is proportional to the number of filters, input dimensions, and kernel size, as well as the storage for feature maps and weights. + +### Example: +Consider an example where we use a CNN to classify handwritten digits from the MNIST dataset: + +```python +import tensorflow as tf +from tensorflow.keras import layers, models + +# Load MNIST dataset +(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() + +# Preprocess data +x_train = x_train.reshape(-1, 28, 28, 1).astype('float32') / 255.0 +x_test = x_test.reshape(-1, 28, 28, 1).astype('float32') / 255.0 + +# CNN Model +model = models.Sequential() + +# Convolutional Layer +model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) +model.add(layers.MaxPooling2D((2, 2))) + +# Second Convolutional Layer +model.add(layers.Conv2D(64, (3, 3), activation='relu')) +model.add(layers.MaxPooling2D((2, 2))) + +# Fully Connected Layers +model.add(layers.Flatten()) +model.add(layers.Dense(64, activation='relu')) +model.add(layers.Dense(10, activation='softmax')) # 10 output classes for MNIST + +# Compile model +model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) + +# Train the model +model.fit(x_train, y_train, epochs=5, batch_size=64, validation_data=(x_test, y_test)) + +# Evaluate on test data +test_loss, test_acc = model.evaluate(x_test, y_test) +print(f"Test Accuracy: {test_acc}") +``` + +### Summary & Applications of CNNs: +- **Image Classification**: + CNNs are used in tasks like classifying handwritten digits (MNIST), recognizing objects in images (CIFAR-10), and classifying medical images. + +- **Object Detection**: + CNNs are widely used for detecting objects in images or videos, identifying their location, and labeling them (e.g., YOLO, R-CNN). + +- **Image Segmentation**: + In segmentation tasks, CNNs are used to assign labels to each pixel in an image, differentiating between different objects or regions. + +- **Face Recognition**: + CNNs are used for identifying or verifying individuals in photos or videos by learning facial features. + +- **Self-driving Cars**: + CNNs are used to analyze camera data and make decisions in real-time diff --git a/docs/machine-learning/DBSCAN_Clustering_Algorithm.md b/docs/machine-learning/DBSCAN_Clustering_Algorithm.md new file mode 100644 index 000000000..7700e25c9 --- /dev/null +++ b/docs/machine-learning/DBSCAN_Clustering_Algorithm.md @@ -0,0 +1,162 @@ +--- + +id: dbscan-clustering +title: DBSCAN Clustering Algorithm +sidebar_label: DBSCAN Clustering +description: "In this post, we'll explore DBSCAN, a density-based clustering algorithm used to identify clusters of arbitrary shape and noise in datasets." +tags: [clustering, machine learning, DBSCAN, density-based] + +--- + +### Definition: +**DBSCAN (Density-Based Spatial Clustering of Applications with Noise)** is a clustering algorithm that groups points based on the density of the data. It can identify clusters of arbitrary shapes and handle noise (outliers) effectively by grouping densely packed points and marking sparse points as noise. + +### Characteristics: +- **Density-Based**: + DBSCAN forms clusters by grouping points that are closely packed and have many neighboring points. Points in low-density regions are classified as noise. + +- **Arbitrary Shape Clusters**: + Unlike other clustering algorithms like K-Means, DBSCAN can find clusters of arbitrary shape, making it useful for non-linear data distributions. + +- **Robust to Outliers**: + DBSCAN can automatically detect and exclude outliers, as they do not belong to any dense region. + +### Key Concepts: +1. **Core Points**: + A point is considered a **core point** if it has at least `MinPts` points (including itself) within a distance `ε` (epsilon), the neighborhood radius. + +2. **Border Points**: + A **border point** is not a core point but falls within the neighborhood of a core point. + +3. **Noise Points**: + A **noise point** does not belong to any cluster. These points are outliers and do not have sufficient neighboring points to be part of a cluster. + +4. **Epsilon (ε)**: + The maximum distance between two points for them to be considered neighbors. It defines the neighborhood of a point. + +5. **MinPts**: + The minimum number of points (including the core point itself) required to form a dense region. It is a crucial parameter that controls the density threshold for forming clusters. + +### DBSCAN Clustering Process: +1. **Pick a Random Point**: + Start with a random point that has not been visited. + +2. **Check Neighborhood**: + If the point has at least `MinPts` points within distance `ε`, it becomes a core point and a new cluster is formed. Otherwise, the point is marked as noise (it may later become part of a cluster if it falls within the neighborhood of a core point). + +3. **Expand Cluster**: + Once a core point is found, all points within its `ε` neighborhood are recursively added to the cluster if they are within the defined density threshold. Border points are included if they are within the range of core points. + +4. **Mark as Clustered or Noise**: + The process continues until all points have been visited, either assigned to a cluster or labeled as noise. + +### DBSCAN Algorithm Steps: +1. For each point in the dataset that is not yet visited: + - Mark it as visited. + - Retrieve the `ε`-neighborhood of the point. + - If the point is a core point (i.e., has at least `MinPts` neighbors), create a new cluster and expand it by adding all reachable points (core and border points). + - If the point is not a core point and has fewer than `MinPts` neighbors, mark it as noise. + +2. Repeat the process until all points are either clustered or classified as noise. + +### Parameters: +- **Epsilon (ε)**: + Defines the neighborhood distance. The choice of `ε` depends on the dataset and is critical to the performance of DBSCAN. + +- **MinPts**: + Minimum number of points required to form a dense region. Typically, `MinPts` is set to a value greater than or equal to the number of dimensions plus one. + +### Advantages of DBSCAN: +- **No Need for Predefined Clusters**: + Unlike K-Means, DBSCAN does not require specifying the number of clusters beforehand. + +- **Handles Noise**: + DBSCAN is effective at handling outliers and noise, automatically marking them as noise points. + +- **Detects Arbitrary Shaped Clusters**: + DBSCAN can discover clusters of arbitrary shapes, making it suitable for complex datasets with non-linear cluster boundaries. + +### Disadvantages of DBSCAN: +- **Sensitive to Parameters**: + The performance of DBSCAN is highly sensitive to the choice of `ε` and `MinPts`. Poor choices can lead to bad clustering results. + +- **Difficulty with Varying Density**: + DBSCAN struggles when clusters have significantly varying densities, as it relies on a global `ε` and `MinPts` for all clusters. + +### Example of DBSCAN: +Consider a dataset with two dense clusters and a few scattered noise points. DBSCAN can identify the dense clusters and label the noise points as outliers. + +### Python Implementation: +Here is an example implementation of DBSCAN using **scikit-learn**: + +```python +import numpy as np +import matplotlib.pyplot as plt +from sklearn.cluster import DBSCAN +from sklearn.datasets import make_moons + +# Generate sample data (two clusters with noise) +X, _ = make_moons(n_samples=300, noise=0.05, random_state=0) + +# Apply DBSCAN clustering +dbscan = DBSCAN(eps=0.2, min_samples=5) +clusters = dbscan.fit_predict(X) + +# Plot the clusters +plt.scatter(X[:, 0], X[:, 1], c=clusters, cmap='Paired') +plt.title("DBSCAN Clustering") +plt.xlabel("Feature 1") +plt.ylabel("Feature 2") +plt.show() +``` + +### DBSCAN Parameters: +In the example above: +- `eps=0.2`: Specifies the radius of the neighborhood. +- `min_samples=5`: Sets the minimum number of points required to form a dense region. + +### Choosing `ε` and `MinPts`: +1. **Epsilon (ε)**: + The right value for `ε` depends on the dataset. You can use a **k-distance graph** to help determine the value of `ε`. Plot the distance to the `k`-th nearest point for each point and look for an "elbow" point. + +2. **MinPts**: + A common rule of thumb is to set `MinPts` to `d + 1`, where `d` is the number of dimensions in the dataset. + +### Example Clustering with Noise: +Let's look at another example where DBSCAN identifies clusters and outliers: + +```python +from sklearn.datasets import make_blobs + +# Create a dataset with clusters and outliers +X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=0) + +# Apply DBSCAN with eps=0.5 and min_samples=5 +dbscan = DBSCAN(eps=0.5, min_samples=5) +labels = dbscan.fit_predict(X) + +# Plotting the results +plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='Paired') +plt.title("DBSCAN with Clusters and Outliers") +plt.xlabel("Feature 1") +plt.ylabel("Feature 2") +plt.show() +``` + +### Example Output: +In the plot, you will see well-formed clusters identified by DBSCAN and noise points scattered across the plot, labeled separately. + +### DBSCAN Use Cases: +- **Geospatial Data**: + DBSCAN can be used for clustering spatial data, like grouping houses in a region or identifying geographic patterns. + +- **Anomaly Detection**: + By identifying outliers, DBSCAN can be used for detecting anomalies in various domains like fraud detection and intrusion detection. + +- **Customer Segmentation**: + In marketing, DBSCAN can help group customers based on purchase behavior, identifying natural customer segments and outliers. + +### Summary: +**DBSCAN (Density-Based Spatial Clustering of Applications with Noise)** is a powerful clustering algorithm that forms clusters based on the density of points. It is ideal for datasets with clusters of arbitrary shapes and handles noise effectively. While it is sensitive to its parameters (`ε` and `MinPts`), it offers a robust solution for many real-world clustering problems, including anomaly detection, geospatial clustering, and pattern recognition. + +--- diff --git a/docs/machine-learning/Extra_Trees.md b/docs/machine-learning/Extra_Trees.md new file mode 100644 index 000000000..ea6616d80 --- /dev/null +++ b/docs/machine-learning/Extra_Trees.md @@ -0,0 +1,129 @@ +--- + +id: extra-trees +title: Extra Trees Algorithm +sidebar_label: Extra Trees +description: "In this post, we’ll explore the Extra Trees Algorithm, an ensemble learning model used for classification and regression tasks, known for its efficiency and randomness in both feature selection and data sampling." +tags: [machine learning, algorithms, extra trees, classification, regression] + +--- + +### Definition: +The **Extra Trees Algorithm** (Extremely Randomized Trees) is an ensemble learning technique similar to Random Forest, but with added randomness in the way splits are selected during tree construction. Like random forests, it is applicable to both **classification** and **regression** tasks. The key difference is that Extra Trees chooses split points randomly for each feature, making the trees more varied and often faster to train than random forests. + +### Characteristics: +- **Extreme Randomness in Split Selection**: + Unlike traditional decision trees and random forests, Extra Trees selects a split point randomly from a range of possible values, increasing variability among trees in the ensemble. + +- **Efficiency**: + Since the split points are selected randomly rather than by calculating the best split (as in random forests), Extra Trees tend to be faster to train while maintaining competitive accuracy. + +- **Bias-Variance Tradeoff**: + Extra Trees generally reduce variance compared to single decision trees, but they may introduce more bias due to the randomness in split selection. However, the ensemble effect mitigates this, often leading to strong overall performance. + +### Types of Extra Trees: +1. **Classification Trees**: + Used when the target variable is categorical. The model makes predictions by averaging votes across all trees to assign a class label. + +2. **Regression Trees**: + Used for continuous target variables. The algorithm averages the output of all trees to generate the final prediction for regression tasks. + +### Steps Involved: +1. **Bootstrap Sampling (Optional)**: + Unlike random forests, Extra Trees can optionally use the full dataset for training each tree without bootstrapping. When bootstrapping is used, the training process is similar to random forests. + +2. **Random Feature Subset Selection**: + At each node, a random subset of features is selected. However, instead of finding the optimal split, Extra Trees choose a random split point from the range of possible values for the selected feature. + +3. **Grow Decision Trees**: + Each tree is grown to its full depth without pruning. The extreme randomness makes the individual trees more diverse but potentially less accurate in isolation. + +4. **Aggregate Results**: + For classification tasks, the final prediction is made by majority voting across all trees. For regression tasks, the final output is the average of the predictions from all trees. + +### Problem Statement: +Given a dataset with features and target values, the goal is to build an ensemble of extremely randomized decision trees that can **classify** data points or **predict** continuous values based on random splits and random feature selection. + +### Key Concepts: +- **Random Split Selection**: + Instead of selecting the best split by maximizing a criterion (e.g., Gini impurity or information gain), Extra Trees choose a random split from possible values, increasing randomness and diversity among trees. + +- **Aggregation Methods**: + - **Majority Voting (for Classification)**: + The class predicted by the majority of trees is the final output. + - **Averaging (for Regression)**: + The average of the predictions from all trees gives the final result. + +### Split Criteria: +- **Random Split Points**: + While traditional decision trees optimize split criteria such as Gini impurity or entropy, Extra Trees randomly select split points, making the algorithm computationally cheaper but still effective. + +- **Gini Impurity** or **Entropy** for classification and **Mean Squared Error (MSE)** for regression tasks can still be used to evaluate the quality of the random splits after they are made. + +### Time Complexity: +- **Training Complexity**: + For `T` trees trained on `n` samples with `d` features, the time complexity is approximately $O(T \cdot n \cdot \log n)$, as splits are selected randomly without the need to evaluate all possible splits. This makes the algorithm faster than random forests. + +- **Prediction Complexity**: + Like random forests, prediction complexity is $O(T \cdot \log n)$, where `T` is the number of trees and `n` is the number of samples. + +### Space Complexity: +- **Space Complexity**: + The space complexity is $O(T \cdot n \cdot d)$ due to the need to store `T` trees, each containing `n` samples and `d` features. + +### Example: +Consider a dataset where the goal is to predict customer churn based on features like age, income, and activity: + +- Dataset: +| Age | Income | Active | Churned | +|-----|--------|--------|---------| +| 25 | High | Yes | No | +| 45 | Medium | No | Yes | +| 35 | Low | Yes | No | +| 22 | Low | No | Yes | + +Step-by-Step Execution: + +1. **Bootstrap Sampling**: + Optionally, a random sample of the dataset is selected for training each tree. + +2. **Random Feature Selection and Split**: + At each node, Extra Trees randomly select features and then randomly select split points from the feature’s value range. + +3. **Grow Trees**: + Each tree is grown to its maximum depth without pruning. + +4. **Aggregate Predictions**: + For classification tasks, predictions are based on the majority vote from all trees. For regression tasks, the final output is the average prediction across all trees. + +### Python Implementation: +Here’s a simple implementation of the Extra Trees Algorithm using **scikit-learn**: + +```python +from sklearn.datasets import load_iris +from sklearn.ensemble import ExtraTreesClassifier +from sklearn.model_selection import train_test_split +from sklearn.metrics import accuracy_score + +# Load dataset +iris = load_iris() +X, y = iris.data, iris.target + +# Split dataset +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# Create Extra Trees classifier +clf = ExtraTreesClassifier(n_estimators=100, random_state=42) + +# Train model +clf.fit(X_train, y_train) + +# Predict +y_pred = clf.predict(X_test) + +# Evaluate +accuracy = accuracy_score(y_test, y_pred) +print(f"Accuracy: {accuracy:.2f}") +``` + +--- diff --git a/docs/machine-learning/GBM.md b/docs/machine-learning/GBM.md new file mode 100644 index 000000000..1c1904edb --- /dev/null +++ b/docs/machine-learning/GBM.md @@ -0,0 +1,174 @@ +--- + +id: gbm-visualizations +title: Gradient Boosting Machines (GBM) Visualization +sidebar_label: GBM +description: "Explore the Gradient Boosting Machines (GBM) algorithm for machine learning, including popular variants like XGBoost and LightGBM. Learn how it builds models sequentially, improving performance by correcting errors from previous models." +tags: [machine learning, gradient boosting, XGBoost, LightGBM, data visualization, ensemble learning] + +--- + +### Definition: +**Gradient Boosting Machines (GBM)** are a family of machine learning algorithms that build models sequentially. Each new model focuses on correcting the errors made by previous models. The primary objective of GBM is to minimize a loss function by combining weak learners (typically decision trees) into a stronger model. + +### Characteristics: +- **Sequential Learning**: + GBMs build models in a step-by-step fashion, correcting errors from previous iterations. + +- **Gradient Descent Optimization**: + Each new model is trained to minimize the residual errors of the previous models by leveraging gradient descent optimization. + +- **Boosting Technique**: + By emphasizing difficult-to-predict observations, GBMs create a powerful predictive model that outperforms individual weak learners. + +### Components of GBM: +1. **Base Learner (Weak Learner)**: + Typically, decision trees are used as the base learners in GBM. They are sequentially improved to correct errors from earlier iterations. + +2. **Gradient Descent**: + GBM uses gradient descent to minimize the loss function by adjusting the parameters of the model iteratively. + +3. **Learning Rate**: + A key hyperparameter that controls the contribution of each new model to the ensemble. A smaller learning rate requires more iterations but often leads to better accuracy. + +4. **Loss Function**: + Different loss functions can be used depending on the task (e.g., mean squared error for regression, log loss for classification). The choice of loss function directly impacts how the errors are corrected. + +### Steps Involved: +1. **Initialize the Model**: + Start by initializing the predictions with a simple model (often the mean for regression or uniform distribution for classification). + +2. **Compute Residuals**: + Calculate the residuals, which are the differences between the actual values and the current predictions. + +3. **Fit a New Learner to Residuals**: + Train a new decision tree to predict the residuals from the previous model. + +4. **Update Predictions**: + Adjust the predictions by adding a fraction of the new learner's output (based on the learning rate). + +5. **Iterate**: + Repeat the process until a stopping criterion is met (e.g., maximum iterations or minimal improvement). + +6. **Final Model**: + The final model is a weighted sum of all the models built during the iterations. + +### Key Concepts: +- **Boosting**: + A method that converts weak learners into a strong learner by emphasizing the correction of errors made in earlier iterations. + +- **Learning Rate**: + Controls how much each new model contributes to the ensemble. Lower values result in slower but more reliable convergence. + +- **Loss Function**: + Measures the accuracy of the model. The gradient of the loss function guides the learning process. + +- **Tree Depth**: + The depth of each decision tree controls the complexity of the model. Shallow trees are less likely to overfit, while deeper trees capture more complex patterns. + +### GBM Algorithm Architecture: +1. **Input Layer**: + The input consists of the training dataset with features and targets. The process begins with an initial guess or simple prediction (like the mean value). + +2. **Residual Computation Layer**: + Residuals are calculated by subtracting the predicted values from the true values. + +3. **Weak Learner Training Layer**: + Decision trees are trained on the residuals to learn the patterns missed by previous models. + +4. **Model Update Layer**: + Each new learner's output is scaled by the learning rate and added to the ensemble model's predictions. + +5. **Output Layer**: + The final predictions are a combination of all models created in the process, leading to an improved and accurate predictive model. + +### Advantages of GBM: +- **High Predictive Accuracy**: + GBMs are known for their superior predictive power, especially in competitions and real-world applications. + +- **Flexibility**: + They can handle a variety of data types and loss functions, making them versatile for different machine learning tasks. + +- **Feature Importance**: + GBMs provide insights into the most influential features in the dataset, making them useful for feature selection and interpretability. + +### Limitations of GBM: +- **Computational Complexity**: + Training GBMs can be computationally intensive, especially for large datasets or deep trees. + +- **Overfitting Risk**: + GBMs are prone to overfitting if the model is too complex or the learning rate is too high. + +- **Hyperparameter Tuning**: + GBMs require careful tuning of parameters like learning rate, tree depth, and number of iterations to achieve optimal performance. + +### Popular Variants: +1. **XGBoost**: + A highly optimized version of GBM that uses advanced regularization techniques, tree-pruning, and parallel processing to speed up training. + +2. **LightGBM**: + A variant designed for speed and efficiency, particularly on large datasets. It uses a novel leaf-wise tree growth strategy and histogram-based learning. + +3. **CatBoost**: + A gradient boosting library specifically designed to handle categorical features without extensive preprocessing. + +### Use Cases: +1. **Classification & Regression**: + GBMs excel in both classification and regression tasks, commonly used in areas like financial risk prediction, fraud detection, and customer segmentation. + +2. **Ranking**: + GBMs are popular in ranking applications, such as search engines, recommendation systems, and personalized advertising. + +3. **Feature Engineering**: + GBMs can be used for feature selection, identifying which features contribute the most to the predictive power of the model. + +4. **Time-Series Forecasting**: + GBMs can be adapted for time-series analysis, predicting future values based on past observations. + +### Example of GBM in Python: +```python +import numpy as np +import matplotlib.pyplot as plt +from sklearn.datasets import load_boston +from sklearn.model_selection import train_test_split +from sklearn.ensemble import GradientBoostingRegressor +from sklearn.metrics import mean_squared_error + +# Load dataset +data = load_boston() +X = data.data +y = data.target + +# Split data into training and testing sets +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) + +# Train GBM model +gbm = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42) +gbm.fit(X_train, y_train) + +# Predictions +y_pred = gbm.predict(X_test) + +# Plot predictions vs. actual values +plt.figure(figsize=(8, 6)) +plt.scatter(y_test, y_pred, alpha=0.7, color='blue') +plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color='red', lw=2) +plt.title("GBM Predictions vs. Actual Values") +plt.xlabel("Actual") +plt.ylabel("Predicted") +plt.show() +``` + +### Time and Space Complexity: +- **Time Complexity**: + Training time is roughly $O(m \cdot d \cdot n \cdot \log(n))$, where $m$ is the number of iterations, $d$ is the average depth of the trees, and $n$ is the number of data points. + +- **Space Complexity**: + Space complexity is $O(n \cdot d)$ due to the storage required for decision trees. + +### Summary & Applications: +- **Gradient Boosting Machines (GBM)** combine multiple weak learners (decision trees) in a sequential manner to create a strong predictive model. They are renowned for their versatility and high accuracy in machine learning tasks. + +- **Applications**: + GBMs are widely used in finance, healthcare, marketing, and many other fields for predictive modeling, ranking tasks, and feature importance analysis. + diff --git a/docs/machine-learning/Gaussian_Mixture_Model.md b/docs/machine-learning/Gaussian_Mixture_Model.md new file mode 100644 index 000000000..bd5b1e633 --- /dev/null +++ b/docs/machine-learning/Gaussian_Mixture_Model.md @@ -0,0 +1,154 @@ +--- + +id: gaussian-mixture-models +title: Gaussian Mixture Models (GMM) +sidebar_label: GMM +description: "This post explores Gaussian Mixture Models (GMM), a probabilistic model for representing normally distributed subpopulations within a larger population." +tags: [machine learning, clustering, gmm, gaussian, statistics] + +--- + +### Definition: +**Gaussian Mixture Models (GMMs)** are a probabilistic model used to represent a mixture of multiple Gaussian distributions within a dataset. GMMs are commonly applied in clustering tasks where data is assumed to be generated from several Gaussian-distributed subpopulations, but the identity of the subpopulation to which a particular data point belongs is unknown. + +### Characteristics: +- **Probabilistic Model**: + GMM represents each data point as belonging to one of several Gaussian distributions, each with its own mean, covariance, and weight (prior probability). + +- **Soft Clustering**: + Unlike methods like K-Means, which provide hard assignments of data points to clusters, GMM assigns each data point a probability of belonging to each cluster. + +- **Multivariate Gaussian Distributions**: + GMMs can model data in multiple dimensions, with each Gaussian component having its own covariance matrix, allowing for flexibility in cluster shapes. + +### Components of GMM: +1. **Gaussian Components**: + Each component in GMM is a Gaussian distribution, defined by a mean vector, a covariance matrix, and a mixing coefficient. The model assumes that data points are drawn from these Gaussian distributions. + +2. **Means**: + The mean vector defines the center of each Gaussian distribution, representing the location of the cluster in the feature space. + +3. **Covariance Matrix**: + This matrix defines the shape and orientation of each Gaussian distribution. Depending on the covariance type (full, diagonal, tied, spherical), GMM can model clusters with different sizes and orientations. + +4. **Mixing Coefficients**: + Mixing coefficients (or weights) represent the proportion of data points that belong to each Gaussian component, summing to 1 across all components. + +5. **Expectation-Maximization (EM) Algorithm**: + GMM parameters are typically estimated using the EM algorithm, which iteratively assigns probabilities to each data point and updates the model parameters to maximize the likelihood of the data. + +### GMM Architecture: +1. **Input Data**: + The input to a GMM can be multi-dimensional data points, such as 2D or 3D points, where the goal is to identify underlying subgroups or clusters within the data. + +2. **Gaussian Components**: + The model assumes that the data comes from a mixture of Gaussian distributions, each representing a potential cluster in the data. + +3. **EM Algorithm**: + The Expectation-Maximization algorithm alternates between two steps: + - **Expectation (E-step)**: Calculates the probability of each data point belonging to each Gaussian component (soft assignments). + - **Maximization (M-step)**: Updates the parameters of each Gaussian component (mean, covariance, and weights) based on the data's probability distribution from the E-step. + +4. **Cluster Assignment**: + After convergence, data points are assigned to clusters based on their highest probability of belonging to a particular Gaussian component. + +### Covariance Types in GMM: +1. **Full Covariance**: + Each Gaussian component has its own general covariance matrix, allowing clusters to take on any elliptical shape. + +2. **Diagonal Covariance**: + Each Gaussian component has its own diagonal covariance matrix, implying that features are independent but can have different variances. + +3. **Tied Covariance**: + All Gaussian components share the same covariance matrix, limiting the flexibility of cluster shapes. + +4. **Spherical Covariance**: + Each Gaussian component has a covariance matrix that is a scaled identity matrix, meaning clusters are spherical and have the same radius. + +### Problem Statement: +Given a set of multi-dimensional data points, the goal of GMM is to model the data as being generated from a mixture of several Gaussian distributions. This helps in clustering the data points into different subpopulations based on their probability of belonging to each Gaussian component. + +### Key Concepts: +- **Latent Variables**: + In GMM, each data point is assumed to be associated with a hidden or latent variable, indicating which Gaussian component it comes from. + +- **Likelihood**: + GMM maximizes the likelihood of the data, which is the probability that the observed data was generated by the mixture of Gaussian distributions. + +- **Posterior Probability**: + The posterior probability gives the likelihood that a data point belongs to a particular Gaussian component, computed during the E-step of the EM algorithm. + +- **Convergence**: + The EM algorithm iterates between the E-step and M-step until the parameters converge, i.e., the likelihood does not change significantly between iterations. + +### Steps Involved: +1. **Initialize Parameters**: + Initialize the means, covariance matrices, and mixing coefficients for each Gaussian component, either randomly or using a method like K-Means. + +2. **Expectation Step**: + For each data point, calculate the probability that it belongs to each Gaussian component based on the current parameters. + +3. **Maximization Step**: + Update the means, covariance matrices, and mixing coefficients of each Gaussian component based on the probabilities calculated in the E-step. + +4. **Repeat**: + Repeat the E-step and M-step until the model parameters converge. + +5. **Cluster Assignment**: + Assign each data point to the Gaussian component with the highest posterior probability, or retain the soft assignments for probabilistic clustering. + +### Example: + +```python +from sklearn.mixture import GaussianMixture +import numpy as np + +# Generate synthetic data +np.random.seed(42) +data = np.vstack([ + np.random.normal(loc=0, scale=1, size=(100, 2)), + np.random.normal(loc=5, scale=1.5, size=(100, 2)) +]) + +# Fit a GMM model with 2 components +gmm = GaussianMixture(n_components=2, covariance_type='full') +gmm.fit(data) + +# Predict the cluster for each data point +labels = gmm.predict(data) + +# Get the probabilities of each data point belonging to each Gaussian component +probs = gmm.predict_proba(data) + +# Print the means and covariances of the Gaussian components +print("Means:", gmm.means_) +print("Covariances:", gmm.covariances_) +``` + +### Summary & Applications of GMM: +- **Clustering**: + GMMs are widely used in clustering tasks, particularly when clusters are not well-separated or when clusters have different shapes and sizes. + +- **Anomaly Detection**: + GMMs can be used to detect anomalies or outliers in the data by modeling the normal data as a mixture of Gaussians and flagging points with low likelihood under this model. + +- **Density Estimation**: + GMMs are used for density estimation, allowing for probabilistic modeling of the data distribution, useful in scenarios where data is continuous. + +- **Speech Recognition**: + GMMs are a key component in traditional speech recognition systems, where they model the distribution of feature vectors corresponding to different phonemes. + +- **Image Segmentation**: + GMMs can be used for segmenting images into regions by modeling pixel intensities as a mixture of Gaussians. + +### Time Complexity: +- **Training Complexity**: + The time complexity of fitting a GMM with EM is generally $O(n \cdot d^2 \cdot k \cdot t)$, where $n$ is the number of data points, $d$ is the dimensionality, $k$ is the number of components, and $t$ is the number of iterations until convergence. + +- **Prediction Complexity**: + For inference, the complexity is $O(n \cdot d^2 \cdot k)$, where $n$ is the number of data points, $d$ is the dimensionality, and $k$ is the number of Gaussian components. + +### Space Complexity: +- **Space Complexity**: + GMM space complexity depends on the number of components $k$, dimensionality $d$, and the number of data points $n$, typically $O(k \cdot d^2)$ for storing the parameters. + diff --git a/docs/machine-learning/Generative_Adversarial_Networks.md b/docs/machine-learning/Generative_Adversarial_Networks.md new file mode 100644 index 000000000..027b36bb4 --- /dev/null +++ b/docs/machine-learning/Generative_Adversarial_Networks.md @@ -0,0 +1,173 @@ +--- + +id: generative-adversarial-networks +title: Generative Adversarial Networks (GAN) +sidebar_label: GANs +description: "In this post, we'll explore Generative Adversarial Networks (GAN), a powerful class of neural networks used for generating new data based on learned distributions." +tags: [deep learning, neural networks, GANs, generative models] + +--- + +### Definition: +**Generative Adversarial Networks (GANs)** are a class of deep learning models designed to generate new data samples that are similar to a given dataset. GANs consist of two neural networks, the **generator** and the **discriminator**, which are trained simultaneously in a game-theoretic setting. The **generator** learns to produce realistic data, while the **discriminator** tries to distinguish between real and generated data. This adversarial process helps the generator improve over time. + +### Characteristics: +- **Generative Model**: + GANs are used to generate new, previously unseen data samples that resemble the training data. + +- **Adversarial Training**: + The generator and discriminator are trained simultaneously in a competitive setting, each improving as the other learns. + +- **Unsupervised Learning**: + GANs typically work with unlabeled data, making them suitable for unsupervised learning tasks. + +### How GANs Work: +1. **Generator**: + The generator is a neural network that takes random noise as input and generates synthetic data (e.g., images, text) that resemble the real data. The goal of the generator is to produce data that the discriminator cannot distinguish from real data. + +2. **Discriminator**: + The discriminator is another neural network that takes both real data and generated data as input and tries to classify whether the input is real (from the dataset) or fake (generated by the generator). The discriminator's task is binary classification. + +3. **Adversarial Process**: + The generator and discriminator play a two-player minimax game, where the generator tries to fool the discriminator, and the discriminator tries not to be fooled. The objective of the generator is to minimize the discriminator's accuracy, while the discriminator's goal is to maximize its classification accuracy. + +### Objective Function: +The objective function for GANs is a **minimax game** where the generator $G$ tries to minimize the loss, and the discriminator $D$ tries to maximize it. This is given by: + +![image](https://github.com/user-attachments/assets/684b5961-1fad-4995-8632-c7d3e0d51da5) + + +Where: +- ![image](https://github.com/user-attachments/assets/ca6c5152-87c0-46db-a8d6-2b29c1cb0622) + is the distribution of the real data. +- ![image](https://github.com/user-attachments/assets/d03461ef-0afc-4136-a22a-233766f7208d) + is the distribution of the random noise input. +- $D(x)$ is the probability that &( x )$ is real. +- $G(z)$ is the generator's output based on random noise $( z )$. + +### Types of GANs: +1. **Vanilla GAN**: + The basic form of GAN where the generator and discriminator are both fully connected networks. + +2. **Conditional GAN (cGAN)**: + A variant of GAN where both the generator and discriminator are conditioned on additional information, such as class labels or data attributes. This allows for controlled generation of specific types of data. + +3. **Deep Convolutional GAN (DCGAN)**: + A type of GAN that uses convolutional neural networks (CNNs) in both the generator and discriminator, making it especially effective for generating high-quality images. + +4. **CycleGAN**: + A GAN that learns to translate images from one domain to another without paired examples (e.g., turning a photo of a horse into a zebra). + +### How GANs Are Trained: +1. **Step 1**: + The generator creates synthetic data from random noise. + +2. **Step 2**: + The discriminator takes both real data and generated data as input and classifies them as real or fake. + +3. **Step 3**: + The generator's goal is to make the discriminator classify the generated data as real, while the discriminator aims to correctly distinguish between real and fake data. + +4. **Step 4**: + During backpropagation, the generator updates its parameters to fool the discriminator, while the discriminator updates its parameters to become better at detecting fake data. + +5. **Repeat**: + The process continues until the generator produces data indistinguishable from real data, and the discriminator is unable to tell the difference with a 50% accuracy rate. + +### Key Concepts: +- **Adversarial Loss**: + The loss function used in GANs where the generator tries to minimize the discriminator's accuracy, and the discriminator tries to maximize its accuracy. + +- **Mode Collapse**: + A common issue in GANs where the generator produces limited or repetitive outputs, failing to capture the full diversity of the training data. + +- **Wasserstein GAN (WGAN)**: + An improved GAN variant that uses the Wasserstein distance as a loss function, helping to stabilize training and reduce mode collapse. + +### Example of GAN Architecture: + +1. **Generator Network**: + - Input: Random noise vector (e.g., $z \sim N(0, 1)$). + - Output: Synthetic data (e.g., an image). + + ![Generator Network](https://github.com/user-attachments/assets/e457fd7f-a8c5-46d8-a3be-2a517f8bcdd4) + +2. **Discriminator Network**: + - Input: Real or generated data. + - Output: Probability that the input is real or fake. + + ![Discriminator Network](https://github.com/user-attachments/assets/f9f5d21f-a9d4-4fcb-b84b-96a2e9b3de63) + +### Applications of GANs: +1. **Image Generation**: + GANs are widely used to generate high-quality images, including art, photos, and even realistic human faces. + +2. **Data Augmentation**: + GANs can be used to augment datasets by generating additional data points, improving model training. + +3. **Image-to-Image Translation**: + CycleGANs and other GAN variants can translate images from one domain to another (e.g., turning a winter scene into a summer scene). + +4. **Text-to-Image Generation**: + GANs can be used to generate images based on textual descriptions. + +### Python Implementation: +Here is a basic implementation of a simple GAN in Python using **TensorFlow**: + +```python +import tensorflow as tf +from tensorflow.keras import layers + +# Generator model +def build_generator(): + model = tf.keras.Sequential() + model.add(layers.Dense(128, input_dim=100, activation='relu')) + model.add(layers.Dense(784, activation='sigmoid')) + return model + +# Discriminator model +def build_discriminator(): + model = tf.keras.Sequential() + model.add(layers.Dense(128, input_dim=784, activation='relu')) + model.add(layers.Dense(1, activation='sigmoid')) + return model + +# Build and compile models +generator = build_generator() +discriminator = build_discriminator() +discriminator.compile(loss='binary_crossentropy', optimizer='adam') + +# GAN model (generator + discriminator) +discriminator.trainable = False +gan_input = layers.Input(shape=(100,)) +gan_output = discriminator(generator(gan_input)) +gan = tf.keras.Model(gan_input, gan_output) +gan.compile(loss='binary_crossentropy', optimizer='adam') + +# Train the GAN (example code) +import numpy as np + +def train_gan(gan, generator, discriminator, epochs, batch_size=128): + for epoch in range(epochs): + # Generate random noise + noise = np.random.normal(0, 1, (batch_size, 100)) + generated_data = generator.predict(noise) + + # Get real data (placeholder for real dataset) + real_data = np.random.rand(batch_size, 784) # Example real data + + # Train discriminator + combined_data = np.concatenate([real_data, generated_data]) + labels = np.concatenate([np.ones(batch_size), np.zeros(batch_size)]) + discriminator.train_on_batch(combined_data, labels) + + # Train generator + noise = np.random.normal(0, 1, (batch_size, 100)) + misleading_labels = np.ones(batch_size) + gan.train_on_batch(noise, misleading_labels) +``` + +### Summary: +Generative Adversarial Networks (GANs) are a powerful and flexible class of deep learning models for generating new data that resemble the input dataset. By leveraging an adversarial process, GANs can learn complex distributions, making them suitable for tasks like image generation, data augmentation, and domain translation. However, GAN training can be unstable, and addressing challenges like mode collapse is essential for producing high-quality results. + +--- diff --git a/docs/machine-learning/HBOS.md b/docs/machine-learning/HBOS.md new file mode 100644 index 000000000..09693b642 --- /dev/null +++ b/docs/machine-learning/HBOS.md @@ -0,0 +1,95 @@ +--- +id: histogram-based-outlier-score +title: Histogram-Based Outlier Score (HBOS) +sidebar_label: HBOS +description: "In this post, we'll explore Histogram-Based Outlier Score (HBOS), an unsupervised anomaly detection technique that analyzes each feature independently." +tags: [anomaly detection, outlier detection, unsupervised learning] + +--- + +### Overview +Histogram-Based Outlier Score (HBOS) is an unsupervised anomaly detection technique that assumes independence between features and analyzes each feature independently. It calculates histograms for each feature and then evaluates the "outlierness" of a data point based on its position in the histogram bins. + +The main idea is that points falling in bins with low frequencies (rare occurrences) are more likely to be considered outliers. + +### How HBOS Works + +1. **Feature Independence Assumption**: + - HBOS assumes that all features are independent, which simplifies the computation. + - This allows the detection process to analyze each feature individually without considering multivariate dependencies. + +2. **Creating Histograms for Each Feature**: + - For each feature in the dataset, a histogram is created by dividing the range of the feature into several bins. + - The number of bins and the binning strategy can be set manually or determined automatically. + +3. **Scoring Data Points**: + - The outlier score for a data point is calculated based on the inverse of the bin frequency for each feature. If a data point falls into a bin with a low frequency (i.e., fewer samples), it is assigned a higher outlier score. + - The final outlier score for a data point is often the product of the individual scores for each feature (assuming independence). Alternatively, the sum of logarithmic scores can be used for numerical stability. + +4. **Normalization of Scores**: + - Scores are typically normalized to fall within a certain range, such as [0, 1], to facilitate interpretation. + +### Mathematical Formulation + +Let **x** = (x₁, x₂, ..., xₙ) be a data point in an n-dimensional feature space. The outlier score for the data point **x**, denoted as HBOS(x), is computed based on the frequency of each feature value in the histogram bins. + +### Step 1: Construct Histograms +For each feature *i*, construct a histogram with *bᵢ* bins. The frequency of data points falling within each bin is used to estimate the probability distribution for the feature. + +### Step 2: Calculate the Probability for Each Feature +The probability for a feature value *xᵢ* to fall within a particular bin is given by: +Pᵢ(xᵢ) = (count of data points in the bin containing xᵢ) / (total number of data points) + +### Step 3: Compute the HBOS Score +The HBOS score for the data point **x** is then calculated as the product of the inverse probabilities for each feature (assuming feature independence): + +HBOS(x) = ∏ (1 / Pᵢ(xᵢ)), for i = 1 to n + +Alternatively, a logarithmic version can be used to improve numerical stability: + +HBOS(x) = ∑ -log(Pᵢ(xᵢ)), for i = 1 to n + +### Advantages of HBOS + +- **Computational Efficiency**: Since each feature is processed independently, HBOS is computationally efficient and can handle large datasets with high dimensions. +- **Scalability**: It scales well with the number of data points and features, making it suitable for big data applications. +- **Interpretability**: The algorithm is straightforward to understand and interpret, especially in cases where the distributions of features are known. + +### Limitations of HBOS + +- **Independence Assumption**: The primary limitation is the assumption that features are independent. This may not hold in many real-world datasets, leading to less effective anomaly detection. +- **Binning Sensitivity**: The choice of the number of bins and binning strategy can significantly affect the results. Improper binning may lead to missed or false detections of anomalies. +- **Univariate Approach**: As it handles each feature separately, it may not detect anomalies that only manifest when considering the interaction between multiple features. + +### Use Cases for HBOS + +- **Network Intrusion Detection**: Identifying unusual patterns in network traffic based on individual features like packet size, duration, or frequency. +- **Credit Card Fraud Detection**: Detecting unusual transactions by evaluating independent features such as transaction amount or frequency. +- **Sensor Data Monitoring**: Identifying anomalies in IoT sensor data by assessing readings for individual sensors. + +### Implementation Example (Python) + +Here's a basic example of how HBOS can be implemented using Python with the `pyod` library: + +```python +from pyod.models.hbos import HBOS +from sklearn.datasets import make_classification + +# Generate synthetic data +X, _ = make_classification(n_samples=1000, n_features=10, contamination=0.1, random_state=42) + +# Initialize HBOS detector +hbos = HBOS(n_bins=10, alpha=0.1) + +# Fit the model +hbos.fit(X) + +# Predict anomaly scores +anomaly_scores = hbos.decision_function(X) + +# Get binary labels (0: inlier, 1: outlier) +anomaly_labels = hbos.predict(X) + +print("Anomaly Scores:", anomaly_scores) +print("Anomaly Labels:", anomaly_labels) +``` diff --git a/docs/machine-learning/Hidden_Markov_Model.md b/docs/machine-learning/Hidden_Markov_Model.md new file mode 100644 index 000000000..8086b60c7 --- /dev/null +++ b/docs/machine-learning/Hidden_Markov_Model.md @@ -0,0 +1,142 @@ +--- + +id: hidden-markov-model +title: Hidden Markov Models (HMM) Algorithm +sidebar_label: Hidden Markov Models +description: "In this post, we'll explore Hidden Markov Models (HMMs), a statistical model that represents systems with hidden and observable states, commonly used for sequence data in various domains." +tags: [machine learning, hidden markov model, HMM, sequence modeling] + +--- + +### Definition: +**Hidden Markov Models (HMMs)** are statistical models that represent systems as a set of hidden states and observable sequences. They are widely used for sequential data modeling, where the system evolves over time and only observable data points can be seen, while the underlying states remain hidden. + +### Characteristics: +- **Probabilistic Transitions**: + The model represents transitions between states as probabilities. Each state has a probability of transitioning to another state or staying the same. + +- **Hidden and Observable States**: + HMMs have two types of states: hidden states, which define the unobserved structure, and observable states, which can be directly measured. + +- **Sequence Modeling**: + HMMs are suitable for time-series data, natural language processing, and speech recognition, where the sequence order and probabilistic dependencies are important. + +### Key Concepts: +1. **States**: + States in HMMs are categorized into hidden states (not directly observed) and observable states (can be observed). Examples include the weather (hidden) and umbrella usage (observable). + +2. **Transition Probabilities**: + Defines the probability of transitioning from one hidden state to another, representing the likelihood of moving between different states in the system. + +3. **Emission Probabilities**: + The probability of observing a particular observation given a hidden state, representing how likely an observation is based on the hidden state. + +4. **Initial State Distribution**: + The probability of starting in each hidden state at the beginning of the sequence. + +### Hidden Markov Model Process: +1. **Define States and Observations**: + Identify the hidden and observable states based on the system or data structure. + +2. **Specify Parameters**: + Determine the transition and emission probabilities and initial state distribution based on training data or domain knowledge. + +3. **Train the Model**: + Use data to estimate the parameters (transition, emission probabilities, etc.) or utilize algorithms like the Baum-Welch for training. + +4. **Inference with the Model**: + Use algorithms like the **Viterbi** algorithm for the most probable state sequence or the **Forward-Backward** algorithm to calculate the probability of a sequence. + +### HMM Algorithm Steps: +1. **Initialize Model Parameters**: + Define initial probabilities for states, transition probabilities, and emission probabilities. + +2. **Calculate Forward Probabilities**: + Use the Forward algorithm to compute the probability of observing a sequence given the model. + +3. **Compute Backward Probabilities**: + Apply the Backward algorithm to find probabilities of observing the remaining part of the sequence, starting from each hidden state. + +4. **Viterbi Algorithm**: + Use the Viterbi algorithm to determine the most likely sequence of hidden states given the observations. + +### Parameters: +- **Transition Probability Matrix**: + A matrix where each cell \((i, j)\) represents the probability of transitioning from state \(i\) to state \(j\). + +- **Emission Probability Matrix**: + Each cell represents the probability of an observable state given a hidden state. + +- **Initial State Probability Vector**: + Vector specifying the starting probability of each state in the sequence. + +### Advantages of HMM: +- **Captures Temporal Dependencies**: + Ideal for sequential and time-series data, where the order of events is crucial. + +- **Good for Partially Observable Data**: + Useful in situations where only partial data (observations) is visible, but underlying states are hidden. + +### Disadvantages of HMM: +- **Limited to Markov Assumptions**: + Assumes that future states depend only on the current state, which may be restrictive for some applications. + +- **Parameter Estimation Complexity**: + Requires large amounts of data for accurate parameter estimation, which can be computationally intensive. + +### Python Implementation: +Here is an example implementation of HMM using **hmmlearn**: + +```python +import numpy as np +from hmmlearn import hmm + +# Define states and observations +states = ["Rainy", "Sunny"] +observations = ["walk", "shop", "clean"] + +# Convert to numerical format +state_map = {state: i for i, state in enumerate(states)} +obs_map = {obs: i for i, obs in enumerate(observations)} + +# Initialize the model +model = hmm.MultinomialHMM(n_components=len(states), n_iter=100) + +# Define model parameters (probabilities should sum to 1) +model.startprob_ = np.array([0.6, 0.4]) # Initial state distribution +model.transmat_ = np.array([ + [0.7, 0.3], # Transition probabilities from "Rainy" + [0.4, 0.6] # Transition probabilities from "Sunny" +]) +model.emissionprob_ = np.array([ + [0.1, 0.4, 0.5], # Emission probabilities for "Rainy" + [0.6, 0.3, 0.1] # Emission probabilities for "Sunny" +]) + +# Define an observation sequence +obs_seq = np.array([[obs_map["walk"]], [obs_map["shop"]], [obs_map["clean"]]]) + +# Fit the model (if training needed) and predict hidden states +model.fit(obs_seq) +logprob, hidden_states = model.decode(obs_seq, algorithm="viterbi") + +print("Most likely hidden states:", [states[state] for state in hidden_states]) +``` + +### HMM Parameters: +In the example above: +- `startprob_`: Specifies the initial state probabilities. +- `transmat_`: Defines the transition probability matrix. +- `emissionprob_`: Specifies the emission probability matrix for each observable state. + +### Choosing Parameters: +1. **Transition and Emission Probabilities**: + Should be estimated from training data or set based on domain knowledge. + +2. **Initial State Probabilities**: + Choose initial probabilities that match the expected start of sequences. + +### Summary: +**Hidden Markov Models (HMMs)** are effective for modeling sequential data with hidden and observable states. They are widely used for applications involving time-dependent or sequence data, such as speech recognition, natural language processing, and bioinformatics. By representing complex systems with hidden states and probabilistic transitions, HMMs offer powerful tools for analyzing data with underlying temporal structures. + +--- diff --git a/docs/machine-learning/HierarchialClustering.md b/docs/machine-learning/HierarchialClustering.md new file mode 100644 index 000000000..383da6653 --- /dev/null +++ b/docs/machine-learning/HierarchialClustering.md @@ -0,0 +1,153 @@ +--- + +id: hierarchical-clustering +title: Hierarchical Clustering Algorithm +sidebar_label: Hierarchical Clustering +description: "Hierarchical clustering is a method of grouping similar data points into clusters based on their relative distances, creating a hierarchy that can be visualized as a dendrogram." +tags: [Machine Learning, Clustering] + +--- + +# Hierarchical Clustering Algorithm + +Hierarchical clustering is a method of grouping similar data points into clusters based on their relative distances from each other. Unlike flat clustering techniques such as k-means, hierarchical clustering does not require a pre-specified number of clusters. Instead, it creates a hierarchy of clusters that can be visualized as a dendrogram, showing the hierarchical relationship between clusters. + +--- + +## Table of Contents +- [Introduction](#introduction) +- [How It Works](#how-it-works) +- [Types of Hierarchical Clustering](#types-of-hierarchical-clustering) +- [Linkage Methods](#linkage-methods) +- [Benefits and Use Cases](#benefits-and-use-cases) +- [Implementation](#implementation) + +--- + +## Introduction + +Hierarchical clustering is an unsupervised machine learning algorithm that builds a multi-level hierarchy of clusters. This hierarchical structure allows users to choose their desired number of clusters based on the level of detail they need. Hierarchical clustering is often applied in: +- **Biology:** for phylogenetic tree construction to show relationships among species. +- **Social Sciences and Psychology:** to cluster people based on survey data or behavioral patterns. +- **Marketing:** to segment customers based on their purchasing behavior. +- **Text Analysis:** to group similar documents or articles together. + +Unlike methods like k-means clustering, hierarchical clustering does not require users to specify the number of clusters in advance. Instead, clusters are determined based on distances between data points and merge or split until a single cluster or the desired cluster number is achieved. + +--- + +## How It Works + +Hierarchical clustering uses a distance metric to calculate the similarity between points or clusters. In the **agglomerative approach** (bottom-up): +1. Each data point begins as its own cluster. +2. Calculate the distance between each pair of clusters using a chosen linkage criterion. +3. Merge the two closest clusters. +4. Repeat steps 2-3 until only one cluster remains or a specified number of clusters is reached. + +In the **divisive approach** (top-down): +1. All data points start in one large cluster. +2. This cluster is split into smaller clusters recursively until each data point is its own cluster or a predefined threshold is met. + +The results can be visualized with a **dendrogram**, a tree-like diagram showing the order and level of merges or splits. + +--- + +## Types of Hierarchical Clustering + +### Agglomerative (Bottom-Up) +In the agglomerative approach, each data point is initially its own cluster, and clusters are iteratively merged based on similarity. This approach is more common due to its intuitive nature and ease of implementation. + +### Divisive (Top-Down) +The divisive approach begins with a single cluster containing all data points and recursively splits it. Although less commonly used, it can be more effective in some cases, particularly for datasets with natural group separations. + +--- + +## Linkage Methods + +The linkage method determines how the distance between clusters is calculated when they are merged or split. Common linkage methods include: + +- **Single Linkage:** The distance between two clusters is defined as the minimum distance between any two points in the two clusters. This often results in "chain-like" clusters. + +- **Complete Linkage:** The distance between two clusters is defined as the maximum distance between any two points in the two clusters, leading to compact clusters. + +- **Average Linkage:** The distance between two clusters is defined as the average distance between all pairs of points in the two clusters. + +- **Ward’s Method:** This linkage minimizes the total variance within clusters. It is often preferred when clusters are expected to be roughly spherical. + +Each linkage method produces different cluster shapes, and the choice of linkage can significantly affect the final clustering outcome. + +--- + +## Benefits and Use Cases + +### Benefits +1. **Flexibility:** Hierarchical clustering can produce a range of cluster sizes and numbers, allowing for detailed exploration of data structure. +2. **Visualization:** The dendrogram provides a clear, visual representation of how clusters relate at different levels, which is useful for understanding the data's structure. +3. **No Need to Predefine Cluster Count:** Hierarchical clustering does not require the user to specify the number of clusters in advance, which is often a requirement in methods like k-means. + +### Use Cases +- **Biological Data Analysis:** Constructing phylogenetic trees or understanding genetic similarity between species. +- **Market Segmentation:** Grouping customers by purchasing patterns or demographics. +- **Document Classification:** Organizing large collections of text data into meaningful categories. +- **Image Segmentation:** Grouping pixels or image features for applications in computer vision. + +--- + +## Implementation + +### Dependencies +Ensure you have the following libraries installed: +```bash +pip install scipy matplotlib +``` + +#### Python Implementation + +``` +import numpy as np +from scipy.cluster.hierarchy import dendrogram, linkage, fcluster +from scipy.spatial.distance import pdist +import matplotlib.pyplot as plt + +# Sample data (2D points) +data = np.array([ + [1, 2], + [2, 3], + [3, 4], + [5, 6], + [8, 8], + [7, 7], + [8, 9] +]) + +# Step 1: Compute the pairwise distance matrix +distance_matrix = pdist(data) + +# Step 2: Perform hierarchical clustering using a specified linkage method +Z = linkage(distance_matrix, method='single') # Options: 'single', 'complete', 'average', 'ward' + +# Step 3: Visualize the clustering as a dendrogram +plt.figure(figsize=(10, 7)) +dendrogram(Z, labels=[f'Point {i+1}' for i in range(len(data))]) +plt.title("Hierarchical Clustering Dendrogram") +plt.xlabel("Data Points") +plt.ylabel("Distance") +plt.show() + +# Step 4: Extract clusters by setting a threshold +threshold = 3 # Adjust threshold based on dataset and desired cluster separation +clusters = fcluster(Z, threshold, criterion='distance') + +print("Cluster Assignments:", clusters) + +# Optional: Scatter plot of clustered data +plt.figure(figsize=(8, 5)) +plt.scatter(data[:, 0], data[:, 1], c=clusters, cmap='rainbow', s=100) +plt.title("Hierarchical Clustering - Clustered Data Points") +plt.xlabel("X-axis") +plt.ylabel("Y-axis") +plt.show() +``` + + + diff --git a/docs/machine-learning/Independent Component Analysis.md b/docs/machine-learning/Independent Component Analysis.md new file mode 100644 index 000000000..8deb076c9 --- /dev/null +++ b/docs/machine-learning/Independent Component Analysis.md @@ -0,0 +1,128 @@ +--- +id: independent-component-analysis +title: Independent Component Analysis +sidebar_label: Independent Component Analysis +description: "In this post, we'll explore the Independent Component Analysis (ICA) Algorithm, a powerful technique in statistical data analysis." +tags: [machine learning, algorithms, ICA, signal processing] + +--- + +### Definition: +**Independent Component Analysis (ICA)** is a computational method used for separating a multivariate signal into additive, independent components. It is widely applied in the fields of signal processing, data analysis, and feature extraction, particularly in scenarios where the observed data is a mixture of signals from different sources. + +### Characteristics: +- **Statistical Independence**: + ICA assumes that the components are statistically independent from each other, which distinguishes it from other methods like PCA (Principal Component Analysis). + +- **Non-Gaussianity**: + ICA exploits the non-Gaussian properties of the signals. The more non-Gaussian the signals are, the better the separation results. + +- **Mixing Process**: + ICA can handle linear mixtures of non-Gaussian signals, allowing for the recovery of the original signals from the mixed observations. + +### How ICA Works: +1. **Data Representation**: + The observed data is represented as a linear combination of independent source signals. + +2. **Centering**: + The data is centered by subtracting the mean to ensure that the components have a zero mean. + +3. **Whitening**: + The data is whitened (decorrelated) to remove redundancy and prepare it for ICA processing. + +4. **Independent Component Extraction**: + ICA algorithms, such as FastICA or Infomax, are used to extract the independent components from the mixed signals. This is typically done by maximizing the statistical independence of the output signals. + +### Mathematical Model: +In ICA, the observed data \( X \) can be modeled as: + +$$ +X = A.S +$$ + +Where: +- \( X \) is the observed data matrix. +- \( A \) is the mixing matrix. +- \( S ) is the matrix of independent components. + +## Time Complexity + +The time complexity of ICA can vary depending on the specific algorithm used (such as FastICA, Infomax, etc.). Generally, the complexity is: + +- **Fast ICA: $O(n^2 . m)$** + - Where \(n\) is the number of samples and \(m) is the number of signals/components. + +## Space Complexity + +The space complexity of ICA is typically: + +- **$O(n + m)$** + - Where \(n\) is the number of samples, and \(m) is the number of components. This accounts for storage of the input signals and the estimated components. + +### Loss Function +The objective of ICA is to minimize the mutual information between the extracted components, effectively maximizing their statistical independence. + +### Key Concepts: +- **Mixing Matrix (A)**: + Represents the coefficients used to combine the independent signals into the observed signals. + +- **Independent Components (S)**: + The signals that are recovered by ICA, which are statistically independent from each other. + +- **Non-Gaussianity**: + A measure of how much a distribution deviates from a Gaussian distribution, used to differentiate signals. + +### Advantages + +1. **Blind Source Separation**: ICA is effective in separating mixed signals without prior information about the source signals. +2. **Non-Gaussian Assumption**: ICA leverages the non-Gaussian nature of source signals, which can provide better separation compared to Gaussian-based methods. +3. **Robustness**: It can handle noise and other distortions in the mixed signals. +4. **Widely Applicable**: ICA is useful in various fields, including audio processing, image analysis, and biomedical signal processing. + +### Disadvantages + +1. **Assumption of Independence**: ICA assumes that the source signals are statistically independent, which may not always hold true in real-world applications. +2. **Sensitivity to Initialization**: The performance of ICA can be sensitive to the initial conditions and may converge to different solutions based on starting points. +3. **Computational Complexity**: Depending on the algorithm used, ICA can be computationally intensive, especially for large datasets. + +### Applications: +- **Signal Separation**: + Commonly used in separating audio signals (e.g., the "cocktail party problem") where multiple audio sources are mixed together. + +- **Image Processing**: + ICA can be used for facial recognition, where it helps to separate different facial features from images. + +- **Biomedical Signal Processing**: + ICA is used in analyzing EEG and fMRI data to separate brain activity signals. + +### Python Implementation: +Here is a basic implementation of Independent Component Analysis using **scikit-learn**: + +```python +import numpy as np +from sklearn.decomposition import FastICA + +# Generate sample data: two independent sources +S = np.array([[1, 2, 3, 4, 5], + [5, 4, 3, 2, 1]]) + +# Mix the data +A = np.array([[1, 1], [0.5, 2]]) # Mixing matrix +X = S.dot(A.T) # Mixed signals + +# Apply ICA +ica = FastICA(n_components=2) +S_ = ica.fit_transform(X) # Recovered signals +A_ = ica.mixing_ # Estimated mixing matrix + +# Display the results +print("Mixed Signals (X):") +print(X) +print("Recovered Independent Components (S):") +print(S) +print("Estimated Mixing Matrix (A):") +print(A) +``` + +### Summary +Independent Component Analysis is a powerful technique for separating mixed signals into their independent sources. While it has numerous advantages, it also has limitations that must be considered when applying it to real-world problems. Its broad range of applications in various fields demonstrates its versatility and effectiveness in data analysis. \ No newline at end of file diff --git a/docs/machine-learning/K-Means_clustering.md b/docs/machine-learning/K-Means_clustering.md new file mode 100644 index 000000000..b768ef173 --- /dev/null +++ b/docs/machine-learning/K-Means_clustering.md @@ -0,0 +1,133 @@ +--- + +id: k-means-clustering-visualizations +title: K-Means Clustering Visualizations +sidebar_label: K-Means Clustering +description: "Implement the K-Means clustering algorithm to partition data into K clusters based on feature similarity. This feature will include visualizations to help users understand the clustering process." +tags: [data science, clustering, K-Means, data visualization, machine learning] + +--- + +### Definition: +**K-Means Clustering** is a popular unsupervised machine learning algorithm used to partition a dataset into K distinct clusters. It groups similar data points together based on feature similarity, minimizing the variance within each cluster and maximizing the variance between clusters. + +### Characteristics: +- **Centroid-Based**: + K-Means works by identifying K centroids, which represent the center of each cluster. + +- **Iterative Refinement**: + The algorithm iteratively updates the centroids and the cluster assignments until convergence is achieved. + +- **Distance Metric**: + Typically uses Euclidean distance to measure similarity between data points and centroids. + +### Components of K-Means: +1. **Clusters**: + The K groups into which the data is partitioned. + +2. **Centroids**: + The center points of each cluster, which are recalculated during each iteration. + +3. **Iterations**: + The process of assigning points to clusters and updating centroids continues until a stopping criterion is met. + +### Steps Involved: +1. **Initialize Centroids**: + Randomly select K data points as the initial centroids. + +2. **Assign Clusters**: + Assign each data point to the nearest centroid based on the chosen distance metric. + +3. **Update Centroids**: + Recalculate the centroids as the mean of all data points assigned to each cluster. + +4. **Repeat**: + Continue the assignment and update steps until the centroids no longer change significantly or a maximum number of iterations is reached. + +### Key Concepts: +- **Elbow Method**: + A technique used to determine the optimal number of clusters (K) by plotting the explained variance against the number of clusters. + +- **Silhouette Score**: + A metric that measures how similar a point is to its own cluster compared to other clusters, aiding in the evaluation of clustering quality. + +- **Convergence**: + The point at which the centroids stabilize and do not change significantly between iterations. + +### Advantages of K-Means: +- **Simplicity**: + Easy to implement and interpret, making it a popular choice for clustering tasks. + +- **Efficiency**: + Performs well with large datasets, especially when K is small. + +- **Scalability**: + Scales linearly with the number of data points and clusters. + +### Limitations of K-Means: +- **Choosing K**: + Requires the user to specify the number of clusters in advance, which may not always be clear. + +- **Sensitivity to Initialization**: + The final results can vary depending on the initial placement of centroids. + +- **Assumption of Spherical Clusters**: + K-Means assumes clusters are spherical and evenly sized, which may not be suitable for all data distributions. + +### Popular Applications of K-Means: +1. **Customer Segmentation**: + Grouping customers based on purchasing behavior for targeted marketing. + +2. **Image Compression**: + Reducing the number of colors in an image by clustering similar colors together. + +3. **Document Clustering**: + Organizing text documents into categories based on content similarity. + +4. **Anomaly Detection**: + Identifying outliers in data by clustering normal instances and observing deviations. + +5. **Genomic Data Analysis**: + Clustering genes or samples based on expression patterns in biological research. + +### Example of K-Means in Python: +```python +import numpy as np +import matplotlib.pyplot as plt +from sklearn.cluster import KMeans +from sklearn.datasets import make_blobs + +# Create a sample dataset +X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0) + +# Apply K-Means +kmeans = KMeans(n_clusters=4) +kmeans.fit(X) +y_kmeans = kmeans.predict(X) + +# Visualize the results +plt.figure(figsize=(8, 6)) +plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis') +centers = kmeans.cluster_centers_ +plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='X') +plt.title('K-Means Clustering Visualization') +plt.xlabel('Feature 1') +plt.ylabel('Feature 2') +plt.grid() +plt.show() +``` + +### Time and Space Complexity: +- **Time Complexity**: + The time complexity is approximately $O(n \cdot k \cdot i)$, where $n$ is the number of data points, $k$ is the number of clusters, and $i$ is the number of iterations. + +- **Space Complexity**: + The space required is $O(n)$ for storing the data points and cluster assignments. + +### Summary & Applications: +- **K-Means Clustering** is a widely used technique for exploratory data analysis, providing a simple and efficient method for partitioning data into meaningful groups. + +- **Applications**: + Effective in various domains, including marketing, image processing, and biological data analysis, enhancing the ability to discover patterns and insights in complex datasets. + +--- diff --git a/docs/machine-learning/K-NearestNeighbours.md b/docs/machine-learning/K-NearestNeighbours.md new file mode 100644 index 000000000..774c084b7 --- /dev/null +++ b/docs/machine-learning/K-NearestNeighbours.md @@ -0,0 +1,208 @@ +--- +id: k-nearest-neighbors +title: k-Nearest Neighbors Algorithm +sidebar_label: k-Nearest Neighbors +description: "In this post, we'll explore the k-Nearest Neighbors (k-NN) Algorithm, one of the simplest and most intuitive algorithms in machine learning." +tags: [machine learning, algorithms, classification, regression, k-NN] +--- + +**k-Nearest Neighbors (k-NN)** is a simple and widely used supervised learning algorithm. It can be applied to both classification and regression tasks. The algorithm classifies or predicts a data point based on how closely it resembles its neighbours. k-NN does not have an explicit training phase; instead, it stores the entire dataset and makes predictions by finding the **k nearest neighbours** of a given input and using their majority class (for classification) or average value (for regression) to make predictions. + +## Characteristics: + +- **Instance-Based Learning**: + k-NN is a **lazy learner**, meaning it stores all training instances and delays computation until prediction time. + +- **Non-Parametric**: + It makes no assumptions about the underlying data distribution, making it highly flexible but sensitive to noisy data. + +- **Distance-Based**: + The algorithm relies on a **distance metric** (e.g., Euclidean distance) to measure the data points' proximity or similarity. + +## How k-NN Works: + +1. **Data Collection**: + k-NN requires a labelled dataset of examples, where each example consists of feature values and a corresponding label (for classification) or continuous target (for regression). + +2. **Prediction**: + To predict the label or value for a new, unseen data point: + - Measure the distance between the new point and all points in the training set using a distance metric. + - Select the **k nearest neighbours** based on the shortest distances. + - For classification, assign the most frequent class (majority voting) among the k neighbours. For regression, calculate the average of the k neighbours’ values. + +## Distance Metrics: +The most commonly used distance metrics in k-NN are: + +### 1. Euclidean Distance + +Euclidean Distance is the most common distance metric, defined as the straight-line distance between two points in Euclidean space. + +$$ +d(x, y) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2} +$$ + +where: +- $x_i$ and $y_i$ are the coordinates of the points in $n$-dimensional space. + +## 2. Manhattan Distance + +Manhattan Distance is the sum of the absolute differences between the coordinates of the points. It is also known as the L1 distance or taxicab distance. + +$$ +d(x, y) = \sum_{i=1}^{n} |x_i - y_i| +$$ + +where: +- $x_i$ and $y_i$ are the coordinates of the points in $n$-dimensional space. + +## 3. Minkowski Distance + +Minkowski Distance is a generalized metric that can be seen as a generalization of both the Euclidean and Manhattan distances. + +$$ +d(x, y) = \left( \sum_{i=1}^{n} |x_i - y_i|^p \right)^{\frac{1}{p}} +$$ + +where: +- \$p$ is a parameter that defines the distance metric: + - $p = 1$ gives the Manhattan distance. + - $p = 2$ gives the Euclidean distance. +- $x_i$ and $y_i$ are the coordinates of the points in $n$-dimensional space. + +## 4. Hamming Distance + +Hamming Distance is used for categorical data and is defined as the number of positions at which the corresponding elements are different. + +$$ +d(x, y) = \sum_{i=1}^{n} \delta(x_i, y_i) +$$ + +**where:** +$$ +\delta(x_i, y_i) = +\begin{cases} +1 & \text{if } x_i \neq y_i \\ +0 & \text{if } x_i = y_i +\end{cases} +$$ + +## Choosing k: +- **Small k**: + A smaller k (e.g., k=1 or k=3) makes the model sensitive to noise and can lead to **overfitting** because it considers fewer neighbors. + +- **Large k**: + A larger k provides a more generalized prediction but may lead to **underfitting** if it includes too many neighbors from different classes. + +- **Optimal k**: + The ideal value of k is often found through experimentation or by using techniques like **cross-validation**. + +### Classification with k-NN: +In classification tasks, k-NN assigns the class label based on the majority class among the k-nearest neighbours. Each neighbour votes for its class, and the most frequent class becomes the prediction. + +**Example**: +Suppose we are classifying an unknown data point based on three nearest neighbours (k=3), and the classes of these neighbours are: +- Neighbor 1: Class A +- Neighbor 2: Class A +- Neighbor 3: Class B + +Since Class A occurs more frequently, the new point is assigned to **Class A**. + +## Regression with k-NN: +In regression tasks, k-NN predicts the target value based on the **average** of the values of its k nearest neighbours. + +**Example**: +To predict the price of a house, k-NN will find k houses with similar features (square footage, number of rooms) and return the average price of those k houses as the predicted price. + +### Steps in k-NN Algorithm: +1. **Data Storage**: + k-NN stores the entire dataset of training examples. + +2. **Distance Calculation**: + For a new input data point, compute the distance between the input and every point in the training set using a chosen distance metric. + +3. **Identify Neighbors**: + Sort the distances and identify the k-nearest neighbours. + +4. **Prediction**: + - For classification, count the occurrences of each class among the k neighbours and assign the class with the majority votes. + - For regression, take the average of the k neighbours' target values. + +## Problem Statement: +Given a dataset with labelled examples (for classification) or continuous targets (for regression), the goal is to classify or predict new input data points by finding the k most similar data points in the training set and using them to infer the output. + +### Key Concepts: +- **Lazy Learning**: + k-NN is called a lazy learner because it doesn’t explicitly learn a model during training but simply stores the training dataset. + +- **Similarity**: + The similarity between data points is quantified by calculating the distance between their feature vectors. + +- **Majority Voting**: + For classification, the class of a new data point is determined by the majority class among its k nearest neighbours. + +- **Averaging**: + For regression, the predicted value is the average of the k nearest neighbour's target values. + +### Time Complexity: +- **Training Time Complexity: $O(1)$** + k-NN doesn’t require a training phase, so it takes constant time. + +- **Prediction Time Complexity: $O(n \cdot d)$** + Predicting the class or value for a new data point requires computing the distance between the new point and all n training points, each of which has d dimensions. + +### Space Complexity: +- **Space Complexity: $O(n \cdot d)$** + The algorithm stores the entire dataset, which consists of n points in d dimensions. + +### Example: +Consider a simple k-NN classification example for predicting whether a fruit is an apple or an orange based on its features (weight and Color): + +- Dataset: + ``` + | Weight (g) | Color (scale 1-10) | Fruit | + |------------|--------------------|---------| + | 150 | 8 | Apple | + | 170 | 7 | Apple | + | 130 | 6 | Orange | + | 140 | 5 | Orange | + ``` + +**Step-by-Step Execution**: + +1. **Store Dataset**: + Store the dataset as-is. + +2. **Calculate Distances**: + For a new fruit with a weight of 160g and Color value of 7, compute the distance from this point to all existing data points. + +3. **Find k Nearest Neighbors**: + If k=3, identify the 3 closest fruits to the new one based on the shortest distances. + +4. **Make Prediction**: + Count the class occurrences (Apple or Orange) among the 3 nearest neighbours and assign the new fruit to the most frequent class. + +### Python Implementation: +Here’s a simple implementation of the k-NN algorithm using **scikit-learn**: + +```python +from sklearn.neighbors import KNeighborsClassifier +import numpy as np + +# Sample data +X = np.array([[150, 8], [170, 7], [130, 6], [140, 5]]) # Features (Weight, Color) +y = np.array(['Apple', 'Apple', 'Orange', 'Orange']) # Target (Fruit) + +# Create k-NN classifier +knn = KNeighborsClassifier(n_neighbors=3) + +# Train the model +knn.fit(X, y) + +# Make a prediction for a new fruit +new_fruit = np.array([[160, 7]]) # New fruit with weight 160g and color 7 +predicted_fruit = knn.predict(new_fruit) +print(f"The predicted fruit is: {predicted_fruit[0]}") +``` + +### Summary: +The **k-Nearest Neighbors Algorithm** is a straightforward and intuitive method for both classification and regression tasks. It works by finding the k most similar examples in the training dataset and using them to predict the class or value of a new data point. While easy to implement, k-NN can be computationally expensive, especially on large datasets, as it requires calculating the distance to every training point at prediction time. diff --git a/docs/machine-learning/LinearRegression.md b/docs/machine-learning/LinearRegression.md new file mode 100644 index 000000000..817b8c3de --- /dev/null +++ b/docs/machine-learning/LinearRegression.md @@ -0,0 +1,167 @@ +--- +id: linear-regression +title: Linear Regression Algorithm +sidebar_label: Linear Regression +description: "In this post, we'll explore the Linear Regression Algorithm, one of the most basic and commonly used algorithms in machine learning." +tags: [machine learning, algorithms, linear regression, regression] + +--- + +### Definition: +**Linear Regression** is a supervised learning algorithm used for **predictive modeling** of continuous numerical variables. It establishes a linear relationship between a dependent variable (the target) and one or more independent variables (the features). The goal of linear regression is to model this relationship using a straight line (linear equation) to predict the target values based on input features. + +### Characteristics: +- **Regression Model**: + Unlike classification, linear regression predicts **continuous** values rather than categories. + +- **Linear Relationship**: + Assumes a linear relationship between the features and the target variable, where changes in feature values proportionally affect the target. + +- **Minimizing Error**: + The model minimizes the difference between the actual values and predicted values using a method called **Ordinary Least Squares** (OLS). + +### Types of Linear Regression: +1. **Simple Linear Regression**: + Used when there is one independent variable to predict the target. + Example: Predicting house price based solely on square footage. + +2. **Multiple Linear Regression**: + Used when there are two or more independent variables to predict the target. + Example: Predicting house price based on square footage, number of rooms, and age of the house. + +### Linear Equation: +In linear regression, the relationship between the target \( y \) and the input features \( X \) is modeled using the equation of a straight line: + +![image](https://github.com/user-attachments/assets/1875d7db-cf35-4ce7-a907-52c2366b2f94) + + +Where: +- \( y \) is the dependent variable (target). +- ![image](https://github.com/user-attachments/assets/e1719652-349b-456c-a1e1-e45a751bc619) + are the independent variables (features). +- ![image](https://github.com/user-attachments/assets/63ea3e53-41fc-463d-b485-72cf47d8edcf) + is the intercept![image](https://github.com/user-attachments/assets/20179b4e-8bbc-4c75-af5e-0c6697628740) +. +- ![image](https://github.com/user-attachments/assets/48f41c2a-c6fe-4c22-9ba5-e3c41ddd2588) + are the coefficients (slopes), representing the change in \( y \) for a unit change in the corresponding ![image](https://github.com/user-attachments/assets/88f0e8e8-3f9b-4194-81fb-fb2e1dabef86) + + +### How Linear Regression Works: +1. **Data Collection**: + Gather a dataset with one or more features (independent variables) and the corresponding target variable (dependent variable). + +2. **Model Training**: + The algorithm attempts to find the best-fitting line by optimizing the parameters (intercept and slopes). This is achieved using **Ordinary Least Squares** (OLS), which minimizes the sum of squared residuals (the differences between actual and predicted values). + +3. **Making Predictions**: + Once trained, the model can predict the target value \( y \) for new data points by applying the learned linear equation. + +4. **Residuals**: + The residual is the difference between the actual and predicted value: +![image](https://github.com/user-attachments/assets/883e638f-3a8f-49e8-abfa-46c5295dd923) + + The goal is to minimize these residuals. + +### Problem Statement: +Given a dataset with independent variables (features), the objective is to learn a linear regression model that can predict the target variable based on new input values. + +### Key Concepts: +- **Slope (Coefficient)**: + The slope represents how much the target variable changes when the corresponding feature increases by one unit. In multiple regression, each feature has its own slope. + +- **Intercept**: + The intercept is the predicted value of the target when all feature values are zero. + +- **Best-Fit Line**: + Linear regression aims to find the line (or hyperplane for multiple regression) that best fits the data, meaning it minimizes the overall distance between the data points and the line. + +### Loss Function: +The loss function used in linear regression is the **Mean Squared Error (MSE)**, which calculates the average of the squared differences between the actual and predicted values: + +![image](https://github.com/user-attachments/assets/8cfd9f8a-5473-4492-aeb3-d6cdcb10cf37) + +Where: +- ![image](https://github.com/user-attachments/assets/5d2a3123-9c81-4843-b8d4-1dffec0c55a0) + is the actual target value of the \(i\)-th data point. +- ![image](https://github.com/user-attachments/assets/c811a466-140c-4a76-8c2a-a0e5df20a57c) + is the predicted target value. +- \( n \) is the total number of samples. + +### Gradient Descent (Alternative Training Method): +Another approach to finding the best-fit line is **gradient descent**, which iteratively updates the model parameters by moving in the direction of the steepest decrease in the loss function. + +- **Update rule** for each parameter: +![image](https://github.com/user-attachments/assets/99d5d6c9-fb83-4e6e-b3cf-ba19b29c9127) + + Where: + - ![image](https://github.com/user-attachments/assets/1395eba3-d492-465c-879c-5f7ce406beb3) + is the learning rate (controls step size). + - ![image](https://github.com/user-attachments/assets/6493a7af-6685-47d9-b9a3-70f5cd8abc8b) + is the loss function (MSE). + + The parameters are updated in each iteration to reduce the error. + +### Time Complexity: +- **Best, Average, and Worst Case: $O(n)$** + The time complexity for training a linear regression model is linear with respect to the number of samples \( n \) and features \( p \), making it efficient for large datasets. + +### Space Complexity: +- **Space Complexity: $O(p)$** + The space complexity is proportional to the number of features \( p \), as the model stores one coefficient per feature, plus the intercept. + +### Example: +Consider a dataset for predicting the price of a house based on **square footage**: + +- Dataset: + ``` + | Square Footage | Price ($) | + |----------------|--------------| + | 1500 | 200,000 | + | 1700 | 230,000 | + | 1800 | 250,000 | + | 1900 | 270,000 | + ``` + +Step-by-Step Execution: + +1. **Fit the model**: + Linear regression will learn the relationship between **square footage** (independent variable) and **price** (dependent variable). + +2. **Equation**: + The model will output an equation like: + ![image](https://github.com/user-attachments/assets/8061012e-d2b6-46be-b51b-a1889207eac8) + + +3. **Predict price**: + For a new house with 2000 square feet, the model will predict the price using the equation. + +### Python Implementation: +Here is a basic implementation of Linear Regression in Python using **scikit-learn**: + +```python +from sklearn.linear_model import LinearRegression +import numpy as np + +# Sample data +X = np.array([[1500], [1700], [1800], [1900]]) # Features (Square Footage) +y = np.array([200000, 230000, 250000, 270000]) # Target (Price) + +# Create linear regression model +model = LinearRegression() + +# Train the model +model.fit(X, y) + +# Make predictions +predicted_price = model.predict([[2000]]) # Predict price for 2000 square footage +print(f"Predicted price: ${predicted_price[0]:,.2f}") + +# Display the model's coefficients +print(f"Intercept: {model.intercept_}") +print(f"Coefficient: {model.coef_[0]}") +``` + +### Summary: +The **Linear Regression Algorithm** is one of the most fundamental techniques for predicting continuous outcomes. Its simplicity and interpretability make it a powerful tool for many real-world applications, particularly in finance, economics, and engineering. However, it assumes a linear relationship between variables and may not work well for datasets with non-linear patterns. + +--- diff --git a/docs/machine-learning/LogisticRegression.md b/docs/machine-learning/LogisticRegression.md new file mode 100644 index 000000000..5bdd713d7 --- /dev/null +++ b/docs/machine-learning/LogisticRegression.md @@ -0,0 +1,159 @@ +--- +id: logistic-regression +title: Logistic Regression Algorithm +sidebar_label: Logistic Regression +description: "In this post, we'll explore the Logistic Regression Algorithm, a widely used classification model in machine learning." +tags: [machine learning, algorithms, logistic regression, classification] + +--- + +### Definition: +**Logistic Regression** is a supervised learning algorithm primarily used for **binary classification** tasks (where the target variable has two categories). It models the relationship between the independent variables (features) and the probability of a particular outcome (class). Unlike linear regression, logistic regression predicts the **probability** that a given input belongs to a specific class using the **logistic function** (also known as the sigmoid function). + +### Characteristics: +- **Classification Model**: + Although it contains "regression" in its name, logistic regression is a **classification** algorithm used to assign observations to discrete categories. + +- **Probabilistic Output**: + The model outputs a probability value between 0 and 1, which is then thresholded to classify data points. + +- **Linear Decision Boundary**: + It assumes a linear relationship between the features and the log-odds of the outcome. + +### Types of Logistic Regression: +1. **Binary Logistic Regression**: + Used when the target variable has two classes (e.g., yes/no, spam/ham). + +2. **Multinomial Logistic Regression**: + Used when the target variable has more than two classes but they are not ordinal (e.g., types of fruits). + +3. **Ordinal Logistic Regression**: + Used when the target variable has more than two categories that follow a natural order (e.g., ranking systems like low/medium/high). + +### Logistic Function: +The logistic function, also called the **sigmoid function**, is the mathematical function used to map any real-valued number into the [0, 1] range. It’s expressed as: + +![image](https://github.com/user-attachments/assets/acf5be45-0958-4690-82a7-1c625da800c4) + + +Where: +- \( z \) is a linear combination of input features ![image](https://github.com/user-attachments/assets/bbcb200b-70f8-4382-a81a-88d8745f298a) + +- ![image](https://github.com/user-attachments/assets/4aa2ba43-52c0-4335-a353-23814ac64404) + is the predicted probability that the given input belongs to class 1 ![image](https://github.com/user-attachments/assets/b4b0c5fb-c213-4e9c-959e-e7c0ba2dfa8a) + + +### How Logistic Regression Works: +1. **Linear Model**: + The model starts by calculating a weighted sum of the input features plus a bias term. This is similar to linear regression: + + ![image](https://github.com/user-attachments/assets/565ec3e9-903c-4899-a3d8-71769063d786) + + +2. **Sigmoid Transformation**: + The linear output \( z \) is passed through the sigmoid function to produce a probability: + + ![image](https://github.com/user-attachments/assets/f14f0028-0e70-4695-beb9-223e02a6d210) + + where ![image](https://github.com/user-attachments/assets/7b28ac13-1992-40ec-80e6-944db5890bbd) + is the predicted probability that the data point belongs to the positive class (class 1). + +3. **Classification**: + A threshold (commonly 0.5) is applied to the predicted probability to determine the class label: + +![image](https://github.com/user-attachments/assets/d58eb745-7d6d-4ca4-b58d-6acb4f470a22) + + +4. **Model Training**: + Logistic regression is trained by **maximum likelihood estimation** (MLE), which optimizes the model parameters (weights) to maximize the likelihood of correctly classifying the data. + +### Problem Statement: +Given a dataset with features and a binary target variable, the goal is to learn a logistic regression model that can **classify** new data points into one of two categories by predicting the probability of each category. + +### Key Concepts: +- **Odds**: + The odds of an event is the ratio of the probability of the event occurring to the probability of it not occurring: + +![image](https://github.com/user-attachments/assets/d40a0cd4-d56a-49af-8785-0effc31b0f47) + + +- **Log-Odds (Logit)**: + Logistic regression models the log-odds of the target variable as a linear function of the input features: + +![image](https://github.com/user-attachments/assets/88fe176a-2cee-4d85-96b7-93cd0577c02e) + + +### Loss Function: +The **loss function** for logistic regression is the **log loss** (also known as the negative log-likelihood or binary cross-entropy). It’s given by: + +![image](https://github.com/user-attachments/assets/5d3f5412-545d-4eff-82cd-0bdde328c843) + + +Where: +- ![image](https://github.com/user-attachments/assets/1f48df37-fe70-4430-96fd-2e8b2aa08703) + is the actual label of the \(i\)-th data point +- ![image](https://github.com/user-attachments/assets/49b0688a-3005-4199-989a-a1cf859747a1) + is the predicted probability of class 1 for the \(i\)-th data point +- \( n \) is the total number of samples + +### Time Complexity: +- **Best, Average, and Worst Case: $O(n)$** + The time complexity for training logistic regression is linear with respect to the number of samples \( n \) and features \( p \), making it efficient for large datasets. + +### Space Complexity: +- **Space Complexity: $O(p)$** + The space complexity depends on the number of features, as the model needs to store a weight for each feature plus a bias term. + +### Example: +Consider a dataset for predicting whether a user will click on an ad based on their **age** and **daily time spent on site**: + +- Dataset: + ``` + | Age | Daily Time Spent | Clicked (Yes/No) | + |-------|------------------|------------------| + | 25 | 65.5 | Yes | + | 45 | 80.3 | No | + | 35 | 45.2 | Yes | + | 22 | 50.1 | No | + ``` + +Step-by-Step Execution: + +1. **Fit the model**: + Logistic regression will learn the relationship between features (Age, Daily Time Spent) and the target (Clicked or not). + +2. **Sigmoid transformation**: + The linear combination of the features is transformed into a probability using the sigmoid function. + +3. **Predict class**: + A threshold (e.g., 0.5) is applied to classify whether the user will click the ad (Yes or No). + +### Python Implementation: +Here is a basic implementation of Logistic Regression in Python using **scikit-learn**: + +```python +from sklearn.datasets import load_iris +from sklearn.linear_model import LogisticRegression +import numpy as np + +# Load dataset +iris = load_iris() +X, y = iris.data, (iris.target == 2).astype(np.int) # Convert to binary classification (target=2 vs rest) + +# Create logistic regression model +clf = LogisticRegression() + +# Train model +clf.fit(X, y) + +# Make predictions +predictions = clf.predict(X) + +# Display the model's coefficients +print(f"Model coefficients: {clf.coef_}") +``` + +### Summary: +The **Logistic Regression Algorithm** is a simple yet powerful method for binary classification tasks. It is widely used in scenarios where interpretability is important, as the model outputs probabilities for each class. Logistic regression is suitable for linearly separable datasets, but it may struggle with non-linear patterns. **Regularization techniques** like L1 and L2 can help prevent overfitting in logistic regression. + +--- diff --git a/docs/machine-learning/Long_Short_Term_Memory.md b/docs/machine-learning/Long_Short_Term_Memory.md new file mode 100644 index 000000000..e08a3d7df --- /dev/null +++ b/docs/machine-learning/Long_Short_Term_Memory.md @@ -0,0 +1,162 @@ +--- + +id: long-short-term-memory +title: Long Short-Term Memory (LSTM) +sidebar_label: LSTM +description: "This post delves into Long Short-Term Memory (LSTM), a type of recurrent neural network designed to overcome the vanishing gradient problem, enabling better learning of long-term dependencies in sequential data." +tags: [machine learning, deep learning, lstm, rnn, neural networks, time series, NLP] + +--- + +### Definition: +**Long Short-Term Memory (LSTM)** is a special type of Recurrent Neural Network (RNN) architecture designed to learn long-term dependencies. It addresses the vanishing gradient problem inherent in vanilla RNNs by introducing gates that regulate the flow of information through the network. LSTMs are particularly effective for tasks involving sequential data, such as time-series prediction, language modeling, and speech recognition. + +### Characteristics: +- **Gated Architecture**: + LSTMs utilize gates (input, forget, output) to control which information is remembered, forgotten, or passed on to the next time step. This allows them to maintain relevant information over long sequences. + +- **Memory Cell**: + The key feature of an LSTM is the memory cell, which retains information over arbitrary time intervals. The network can decide whether to keep or discard information at each time step. + +- **Efficient Learning of Long-term Dependencies**: + Unlike vanilla RNNs, which struggle to retain long-term dependencies due to the vanishing gradient problem, LSTMs are explicitly designed to remember information over longer time periods. + +### Components of LSTM: +1. **Cell State**: + The cell state is the LSTM’s "memory," which flows through the network with only minor linear interactions. It retains information over long sequences. + +2. **Forget Gate**: + The forget gate decides what information from the cell state should be discarded. It uses a sigmoid function to output values between 0 and 1, where 0 means "completely forget" and 1 means "completely retain." + +3. **Input Gate**: + The input gate controls which new information should be stored in the cell state. It consists of a sigmoid layer that decides which values to update and a tanh layer that creates new candidate values for updating the cell state. + +4. **Output Gate**: + The output gate determines the output of the LSTM at each time step. It uses the updated cell state to compute the next hidden state, which is passed on to the next time step. + +5. **Hidden State**: + The hidden state is the output of the LSTM for the current time step. It’s influenced by the output gate and the updated cell state. + +### LSTM Architecture: +1. **Input Layer**: + Sequential data (e.g., words in a sentence, time-series data) is provided as input to the LSTM one time step at a time. + +2. **LSTM Cell**: + Each time step is processed by an LSTM cell, which updates the hidden state and cell state based on the current input, the previous hidden state, and the previous cell state. + +3. **Output Layer**: + The output can be generated at each time step (e.g., language translation or generation tasks) or after processing the entire sequence (e.g., sentiment analysis or time-series prediction). + +### Types of LSTMs: +1. **Vanilla LSTM**: + The most basic form of LSTM, where information flows sequentially through the input, forget, and output gates for each time step. + +2. **Bidirectional LSTM (BiLSTM)**: + This architecture consists of two LSTM layers that process the input in both forward and backward directions. It is especially useful for tasks where future context is as important as past context. + +3. **Stacked LSTM**: + Multiple LSTM layers are stacked on top of each other, enabling the network to learn more complex and hierarchical patterns in the data. + +4. **Peephole LSTM**: + In Peephole LSTMs, the gates also receive input from the cell state, allowing them to "peek" into the cell state during updates. + +### Problem Statement: +Given sequential data such as time-series, text, or audio, the goal of an LSTM is to make accurate predictions by effectively capturing long-term dependencies while mitigating issues like vanishing gradients. + +### Key Concepts: +- **Memory Cell**: + LSTMs maintain a memory cell that persists over time and can store relevant information while discarding irrelevant information through its gates. + +- **Vanishing Gradient Problem**: + LSTMs help mitigate the vanishing gradient problem in vanilla RNNs, which makes them better suited for learning long-term dependencies. + +- **Gates**: + LSTMs employ three main gates (forget, input, and output gates) to regulate the flow of information, ensuring that important information is remembered and unimportant information is forgotten. + +- **Backpropagation Through Time (BPTT)**: + LSTMs use BPTT to update weights by propagating gradients back through the entire sequence. Due to the gating mechanism, LSTMs avoid the vanishing gradient problem better than traditional RNNs. + +### Steps Involved: +1. **Input Data**: + Sequential data is fed into the LSTM one time step at a time. + +2. **Gate Calculations**: + The forget, input, and output gates compute which information to retain, update, and output at each time step. + +3. **Cell State Update**: + The cell state is updated using the information from the forget and input gates, deciding which information to keep or discard. + +4. **Hidden State Calculation**: + The output gate computes the hidden state, which is used as the output for the current time step and passed to the next LSTM cell. + +5. **Final Output**: + After processing the entire sequence, the final hidden state can be used for tasks like sequence classification, or intermediate outputs can be used for tasks like sequence generation. + +### Split Criteria: +LSTMs process data in sequential order, using the previous hidden state and cell state at each time step to inform the current step’s calculations. They are particularly useful for tasks where maintaining information over long sequences is critical. + +### Time Complexity: +- **Training Complexity**: + The time complexity of training an LSTM is proportional to the sequence length $T$, the size of the input $n$, and the number of hidden units $h$, and is approximately $O(T \cdot n \cdot h^2)$. + +- **Prediction Complexity**: + For inference, the complexity depends on the sequence length, as LSTMs must process each time step sequentially. + +### Space Complexity: +- **Space Complexity**: + LSTMs need memory proportional to the sequence length $T$ and the number of hidden units $h$, resulting in a space complexity of $O(T \cdot h)$. + +### Example: +Consider an example where we use an LSTM to perform sentiment analysis on text data: + +```python +import numpy as np +import tensorflow as tf +from tensorflow.keras import layers, models + +# Sample input data (e.g., text sequence for sentiment analysis) +text = "This movie was fantastic" +char_to_idx = {ch: idx for idx, ch in enumerate(set(text))} +idx_to_char = {idx: ch for ch, idx in char_to_idx.items()} +input_seq = [char_to_idx[ch] for ch in text] + +# Prepare input data +input_seq = np.array(input_seq).reshape(1, -1) + +# LSTM Model +model = models.Sequential() + +# LSTM Layer +model.add(layers.LSTM(50, input_shape=(None, len(char_to_idx)))) +model.add(layers.Dense(1, activation='sigmoid')) # Binary sentiment classification + +# Compile model +model.compile(optimizer='adam', loss='binary_crossentropy') + +# Train the model (for illustration, usually requires more training) +model.fit(input_seq, np.array([1]), epochs=100) # Example of positive sentiment + +# Predict sentiment +prediction = model.predict(input_seq) +predicted_sentiment = "Positive" if prediction > 0.5 else "Negative" +print(f"Predicted Sentiment: {predicted_sentiment}") +``` + +### Applications of LSTMs: +- **Natural Language Processing (NLP)**: + LSTMs are widely used in NLP tasks such as text generation, language translation, and sentiment analysis due to their ability to capture long-term dependencies in text. + +- **Time-series Forecasting**: + LSTMs can predict future values in time-series data, making them valuable for financial forecasting, stock price prediction, and weather forecasting. + +- **Speech Recognition**: + LSTMs process sequential audio data to recognize speech patterns and convert them into text. + +- **Music Generation**: + LSTMs can generate new music by learning patterns from existing music sequences. + +- **Video Analysis**: + LSTMs can analyze video sequences by processing frames in order and learning patterns over time. + +### Conclusion: +Long Short-Term Memory (LSTM) networks are a powerful type of recurrent neural network that can capture long-term dependencies in sequential data. With their gated architecture, LSTMs overcome the vanishing diff --git a/docs/machine-learning/PC_Visualizations.md b/docs/machine-learning/PC_Visualizations.md new file mode 100644 index 000000000..24bb41ac4 --- /dev/null +++ b/docs/machine-learning/PC_Visualizations.md @@ -0,0 +1,145 @@ +--- + +id: pca-visualizations +title: PCA Visualizations +sidebar_label: PCA +description: "Implement Principal Component Analysis (PCA) to reduce the dimensionality of high-dimensional data while preserving its essential features. Visualize the transformed data to gain insights into underlying patterns." +tags: [data science, dimensionality reduction, PCA, data visualization, machine learning] + +--- + +### Definition: +**Principal Component Analysis (PCA)** is a statistical technique used for dimensionality reduction. It transforms high-dimensional data into a lower-dimensional space, capturing the most variance in the data while minimizing loss of information. PCA helps simplify complex datasets, making them easier to visualize and analyze. + +### Characteristics: +- **Dimensionality Reduction**: + PCA reduces the number of variables (dimensions) in a dataset while retaining the essential patterns and structures. + +- **Eigenvalues and Eigenvectors**: + PCA identifies principal components by calculating the eigenvalues and eigenvectors of the covariance matrix of the data. + +- **Variance Explained**: + Each principal component captures a portion of the total variance, allowing users to understand how much information is retained. + +### Components of PCA: +1. **Data Standardization**: + Standardize the dataset to have a mean of zero and a standard deviation of one to ensure each feature contributes equally. + +2. **Covariance Matrix**: + Compute the covariance matrix to examine the relationships between different features in the dataset. + +3. **Eigen Decomposition**: + Calculate the eigenvalues and eigenvectors of the covariance matrix to determine the principal components. + +4. **Projection**: + Transform the original data onto the new principal component axes, reducing its dimensionality. + +### Steps Involved: +1. **Standardize the Data**: + Center and scale the data to prepare it for PCA. + +2. **Compute the Covariance Matrix**: + Analyze the relationships between features by calculating the covariance matrix. + +3. **Calculate Eigenvalues and Eigenvectors**: + Find the eigenvalues and eigenvectors to determine the direction of the principal components. + +4. **Sort Eigenvalues**: + Sort the eigenvalues and their corresponding eigenvectors in descending order to identify the most significant components. + +5. **Select Principal Components**: + Choose the top k eigenvectors (principal components) based on the desired level of variance explained. + +6. **Project the Data**: + Transform the original data onto the selected principal components to achieve dimensionality reduction. + +### Key Concepts: +- **Variance Explained Ratio**: + Indicates how much of the total variance is captured by each principal component, helping determine how many components to retain. + +- **Scree Plot**: + A graphical representation of the eigenvalues that helps visualize the importance of each principal component. + +- **Biplot**: + A visualization that combines the principal component scores and the loading vectors, providing insights into the relationships between variables. + +### Advantages of PCA: +- **Reduces Complexity**: + Simplifies high-dimensional datasets, making them easier to visualize and interpret. + +- **Improves Model Performance**: + By reducing noise and redundancy, PCA can enhance the performance of machine learning models. + +- **Facilitates Visualization**: + Enables effective visualization of complex datasets by projecting them into two or three dimensions. + +### Limitations of PCA: +- **Linear Assumption**: + PCA assumes linear relationships among features, which may not hold in all datasets. + +- **Loss of Information**: + Some information is inevitably lost during dimensionality reduction, potentially impacting analysis. + +- **Interpretability**: + The transformed components may not have clear meanings, making it difficult to interpret results in context. + +### Popular Applications of PCA: +1. **Data Visualization**: + Reduce dimensions for visual exploration of high-dimensional data. + +2. **Image Compression**: + Compress images by retaining only the most significant principal components. + +3. **Genomics**: + Analyze genetic data to identify patterns and relationships among genes. + +4. **Market Research**: + Explore customer data to uncover underlying factors influencing purchasing behavior. + +5. **Anomaly Detection**: + Detect outliers in high-dimensional datasets by examining the variance captured by principal components. + +### Example of PCA in Python: +```python +import numpy as np +import pandas as pd +from sklearn.decomposition import PCA +import matplotlib.pyplot as plt + +# Sample dataset +data = pd.DataFrame(np.random.rand(100, 5), columns=['A', 'B', 'C', 'D', 'E']) + +# Standardize the data +data_standardized = (data - data.mean()) / data.std() + +# Apply PCA +pca = PCA(n_components=2) # Reduce to 2 dimensions +pca_result = pca.fit_transform(data_standardized) + +# Create a DataFrame for the PCA results +pca_df = pd.DataFrame(data=pca_result, columns=['Principal Component 1', 'Principal Component 2']) + +# Visualize the PCA results +plt.figure(figsize=(8, 6)) +plt.scatter(pca_df['Principal Component 1'], pca_df['Principal Component 2'], alpha=0.7) +plt.title('PCA Result') +plt.xlabel('Principal Component 1') +plt.ylabel('Principal Component 2') +plt.grid() +plt.show() +``` + +### Time and Space Complexity: +- **Time Complexity**: + The dominant factor is the eigen decomposition, which typically runs in $O(n^3)$, where $n$ is the number of features. + +- **Space Complexity**: + The space required is $O(n^2)$ for storing the covariance matrix and eigenvectors. + +### Summary & Applications: +- **PCA** is a powerful technique for simplifying data analysis and visualization by reducing dimensionality while retaining essential information. + +- **Applications**: + Widely used in exploratory data analysis, image processing, and machine learning to enhance interpretability and model performance. + +--- diff --git a/docs/machine-learning/Recurrent_Neural_Network.md b/docs/machine-learning/Recurrent_Neural_Network.md new file mode 100644 index 000000000..46faaea07 --- /dev/null +++ b/docs/machine-learning/Recurrent_Neural_Network.md @@ -0,0 +1,174 @@ +--- + +id: recurrent-neural-networks +title: Recurrent Neural Networks (RNN) +sidebar_label: RNNs +description: "This post explores Recurrent Neural Networks (RNN), a class of neural networks designed to handle sequential data and time-series information, commonly used for tasks involving natural language processing, speech recognition, and more." +tags: [machine learning, deep learning, rnn, neural networks, time series, NLP] + +--- + +### Definition: +**Recurrent Neural Networks (RNNs)** are a class of artificial neural networks designed for modeling sequential data by introducing loops that allow information to persist across time steps. They are widely used for tasks like time-series forecasting, natural language processing (NLP), and speech recognition because of their ability to process and maintain information from previous inputs. + +### Characteristics: +- **Sequential Data Handling**: + RNNs excel at learning from and making predictions based on sequential data, where the order and context of the input are crucial. + +- **Shared Weights**: + Unlike traditional neural networks, RNNs share the same parameters (weights) across different time steps, which allows them to process variable-length sequences without increasing the number of parameters. + +- **Memory**: + RNNs have internal memory due to their recurrent connections, which allows them to store information about previous inputs and use it to influence future predictions. + +### Components of RNN: +1. **Hidden State**: + RNNs maintain a hidden state that captures information from previous time steps. At each time step, the hidden state is updated based on the current input and the previous hidden state. + +2. **Recurrent Connection**: + The recurrent connection is the key feature of RNNs. It enables information to flow from one time step to the next, creating a loop in the network's structure. + +3. **Activation Function**: + The hidden state is passed through an activation function, typically **tanh** or **ReLU**, to introduce non-linearity into the network and allow it to model complex patterns in sequential data. + +4. **Output Layer**: + The output at each time step is computed based on the current hidden state and can be used for predictions, classification, or further processing. + +### RNN Architecture: +1. **Input Layer**: + Sequential data, such as a series of time steps (e.g., words in a sentence or stock prices over time), is provided as input to the RNN. + +2. **Recurrent Hidden Layer(s)**: + The hidden layer(s) process the input data one time step at a time, updating the hidden state based on both the current input and the previous hidden state. + +3. **Output Layer**: + Depending on the task, RNNs can produce output at each time step (e.g., for translation or generation tasks) or at the end of the sequence (e.g., for sentiment analysis or time-series prediction). + +### Types of RNNs: +1. **Vanilla RNN**: + The simplest form of RNN, where the hidden state is updated using the same weights at each time step. However, vanilla RNNs struggle with learning long-term dependencies due to the vanishing gradient problem. + +2. **Long Short-Term Memory (LSTM)**: + LSTMs are a more advanced form of RNN designed to overcome the vanishing gradient problem. They use gates (input, forget, output) to control the flow of information and can learn long-term dependencies. + +3. **Gated Recurrent Unit (GRU)**: + GRUs are a simplified version of LSTMs that combine the input and forget gates into a single update gate. GRUs are computationally cheaper while still addressing the vanishing gradient problem. + +4. **Bidirectional RNN (BiRNN)**: + In a bidirectional RNN, two RNNs are run in parallel: one processes the sequence from left to right, and the other processes it from right to left. This architecture is useful for tasks where future context is as important as past context. + +### Problem Statement: +Given a sequential dataset (e.g., a sentence for language modeling or a time-series for prediction), the goal of an RNN is to predict the next element in the sequence or classify the entire sequence based on its content. + +### Key Concepts: +- **Sequential Processing**: + RNNs process input sequences step by step, maintaining a hidden state that is updated at each step based on both the current input and previous hidden state. + +- **Vanishing Gradient Problem**: + In vanilla RNNs, gradients may become very small (vanish) during backpropagation through time (BPTT), making it difficult to learn long-term dependencies. This is alleviated by architectures like LSTM and GRU. + +- **Backpropagation Through Time (BPTT)**: + RNNs use BPTT to train the network, where gradients are propagated backward through each time step in the sequence. + +- **Long-term Dependencies**: + RNNs struggle with learning long-term dependencies (i.e., when the gap between relevant inputs and outputs is large), but LSTMs and GRUs address this challenge by incorporating gating mechanisms. + +### Steps Involved: +1. **Input Data**: + Sequential data, such as a series of time steps (e.g., stock prices, words in a sentence), is fed into the RNN one time step at a time. + +2. **Hidden State Update**: + At each time step, the hidden state is updated based on the current input and the previous hidden state, capturing information from earlier time steps. + +3. **Output Generation**: + The output can be generated at each time step or at the end of the sequence, depending on the task. In tasks like language modeling, the RNN predicts the next word at each step. + +4. **Loss Calculation and Backpropagation**: + The loss is calculated based on the predicted output and the true target. Backpropagation through time (BPTT) is used to update the weights. + +5. **Final Prediction**: + The RNN produces a final prediction, which could be a classification of the entire sequence (e.g., sentiment analysis) or a prediction for the next time step in the sequence (e.g., time-series forecasting). + +### Split Criteria: +RNNs handle sequential data where each input depends on the previous elements. The network processes the data one time step at a time, updating the hidden state with each new input. + +### Time Complexity: +- **Training Complexity**: + The time complexity of training an RNN depends on the number of time steps $T$, the size of the input $n$, and the number of hidden units $h$. It is roughly $O(T \cdot n \cdot h^2)$. + +- **Prediction Complexity**: + For inference, the time complexity is also dependent on the sequence length, as each time step requires an update to the hidden state. + +### Space Complexity: +- **Space Complexity**: + The space complexity depends on the number of hidden units and time steps. Since RNNs store the hidden state at each time step, they require memory proportional to $O(T \cdot h)$, where $T$ is the number of time steps and $h$ is the size of the hidden state. + +### Example: +Consider an example where we use an RNN to perform text generation: + +```python +import numpy as np +import tensorflow as tf +from tensorflow.keras import layers, models + +# Sample training data (e.g., text sequence) +text = "hello world" +char_to_idx = {ch: idx for idx, ch in enumerate(set(text))} +idx_to_char = {idx: ch for ch, idx in char_to_idx.items()} +input_seq = [char_to_idx[ch] for ch in text] + +# Prepare input data +input_seq = np.array(input_seq).reshape(1, -1) + +# RNN Model +model = models.Sequential() + +# Recurrent Layer (Simple RNN) +model.add(layers.SimpleRNN(50, input_shape=(None, len(char_to_idx)), return_sequences=True)) +model.add(layers.Dense(len(char_to_idx), activation='softmax')) + +# Compile model +model.compile(optimizer='adam', loss='categorical_crossentropy') + +# Train the model (for illustration, usually longer training is needed) +model.fit(input_seq, input_seq, epochs=100) + +# Predict the next character +prediction = model.predict(input_seq) +predicted_char = idx_to_char[np.argmax(prediction[0])] +print(f"Predicted next character: {predicted_char}") +``` + +### Applications of RNNs: +- **Natural Language Processing (NLP)**: + RNNs are widely used in tasks like machine translation, text generation, sentiment analysis, and speech recognition due to their ability to model sequential dependencies in text and speech data. + +- **Time-series Forecasting**: + RNNs can predict future values in time-series data by learning patterns from historical data, making them useful in finance, weather forecasting, and more. + +- **Speech Recognition**: + RNNs are used to transcribe speech to text by processing sequential audio data and predicting the corresponding textual output. + +- **Sequence Generation**: + RNNs can generate new sequences based on learned patterns, such as generating text, music, or even video frames. + +- **Handwriting Recognition**: + RNNs can recognize handwritten text by processing sequential strokes or pixels in an image. + +- **Video Analysis**: + RNNs are applied to video data to analyze sequences of frames, often combined with convolutional layers for extracting spatial features from each frame. + +### Advantages: +- Can process sequences of varying lengths. +- Maintain information from previous inputs, making them well-suited for sequential tasks. +- LSTMs and GRUs help overcome the vanishing gradient problem, making RNNs capable of learning long-term dependencies. + +### Disadvantages: +- Vanilla RNNs struggle with long-term dependencies due to the vanishing gradient problem. +- Training can be slow and challenging, especially for very long sequences. +- Computationally expensive compared to feedforward neural networks. + +### Conclusion: +Recurrent Neural Networks (RNNs) are powerful tools for modeling sequential data. By maintaining a hidden state that captures information from previous time steps, RNNs can learn patterns in time-series data, text, and more. Advanced variants like LSTMs and GRUs address the shortcomings of vanilla RNNs, making them more effective for tasks requiring long-term memory. + +--- diff --git a/docs/machine-learning/Reinforcement_Learning.md b/docs/machine-learning/Reinforcement_Learning.md new file mode 100644 index 000000000..39231e5b5 --- /dev/null +++ b/docs/machine-learning/Reinforcement_Learning.md @@ -0,0 +1,150 @@ +--- + +id: reinforcement-learning +title: Reinforcement Learning +sidebar_label: Reinforcement Learning +description: "In this post, we'll explore Reinforcement Learning, a type of machine learning used for decision-making and optimizing actions." +tags: [machine learning, reinforcement learning, decision-making, AI] + +--- + +### Definition: +**Reinforcement Learning (RL)** is a type of machine learning where an **agent** learns to make decisions by interacting with an **environment** to achieve a specific goal. The agent takes actions, receives feedback in the form of rewards or penalties, and adjusts its behavior to maximize cumulative rewards over time. It is commonly used for tasks involving **sequential decision-making**. + +### Characteristics: +- **Trial-and-Error Learning**: + The agent learns through a process of trial and error, exploring different strategies to maximize rewards. + +- **Exploration vs. Exploitation**: + The agent balances between exploring new actions (exploration) and using known actions that give high rewards (exploitation). + +- **Delayed Rewards**: + In RL, rewards might not be immediate. The agent needs to consider future rewards when making decisions. + +### Key Components: +1. **Agent**: + The decision-maker in the RL system. The agent interacts with the environment, learns from it, and takes actions. + +2. **Environment**: + The external system the agent interacts with. It provides feedback to the agent in the form of rewards or penalties. + +3. **State**: + A representation of the current situation or environment that the agent observes. + +4. **Action**: + The set of all possible moves the agent can take to interact with the environment. + +5. **Reward**: + The feedback the agent receives from the environment after taking an action. The goal is to maximize cumulative rewards. + +6. **Policy**: + A strategy or mapping from states to actions that the agent follows to decide its next action. + +7. **Value Function**: + A function that estimates the expected long-term reward for a given state or state-action pair. + +### Reinforcement Learning Process: +1. **Observation**: + The agent observes the current state of the environment. + +2. **Action Selection**: + Based on the observation, the agent selects an action using its policy. + +3. **Interaction with Environment**: + The action affects the environment, transitioning it to a new state. + +4. **Reward**: + The agent receives a reward (positive or negative) based on the action taken. + +5. **Learning**: + The agent updates its knowledge (policy or value function) to improve future decisions. + +### Types of Reinforcement Learning: +1. **Model-Free RL**: + The agent learns directly from interactions with the environment without having any prior model of the environment. Examples include Q-learning and SARSA. + +2. **Model-Based RL**: + The agent builds a model of the environment and uses it to plan actions. It tries to predict future states and rewards. + +3. **On-Policy vs. Off-Policy RL**: + - **On-Policy**: The agent learns from the actions taken by the current policy (e.g., SARSA). + - **Off-Policy**: The agent learns from actions taken by a different policy (e.g., Q-learning). + +### Exploration vs. Exploitation: +One of the key challenges in RL is balancing between: +- **Exploration**: Trying out new actions to discover their potential rewards. +- **Exploitation**: Choosing actions that are known to yield high rewards based on the agent’s current knowledge. + +### Q-Learning: +**Q-Learning** is a popular model-free RL algorithm where the agent learns a **Q-value function** that represents the expected reward for taking an action in a given state. The update rule for Q-learning is: + +![image](https://github.com/user-attachments/assets/44d29298-4002-4fe2-8b87-a53e38f03c1a) + + +Where: +- $Q(s, a)$ is the Q-value of taking action $( a )$ in state $(s)$ +- $( r )$ is the reward received after taking action $( a )$ +- $α$ is the learning rate +- $γ$ is the discount factor (the weight of future rewards) +- ![image](https://github.com/user-attachments/assets/36e1cfa7-aa4f-457e-8b7f-ba485f205cc5) + is the maximum Q-value for the next state $s'$ + +### Policy Gradient Methods: +In **policy gradient** methods, the policy is parameterized, and the goal is to directly optimize the policy parameters. These methods are well-suited for high-dimensional action spaces and continuous control tasks. + +### Reward Signal: +The **reward signal** is crucial in RL. The agent's goal is to maximize the **cumulative reward** over time. It must learn which actions lead to higher rewards, even if the rewards are delayed. + +### Discount Factor: +The **discount factor** $γ$ controls the importance of future rewards. A discount factor close to 1 makes the agent prioritize long-term rewards, while a lower value emphasizes immediate rewards. + +### Example: +Consider a simple game where an agent has to move through a maze to reach the goal. The agent receives positive rewards for moving closer to the goal and negative rewards for hitting walls. + +Steps: +1. **State**: The current position of the agent in the maze. +2. **Action**: Move up, down, left, or right. +3. **Reward**: +10 for reaching the goal, -1 for hitting a wall. +4. **Learning**: The agent learns which actions lead it closer to the goal based on rewards. + +### Python Implementation: +Here is a basic implementation of Q-Learning for solving a simple gridworld problem: + +```python +import numpy as np + +# Define environment +grid_size = 4 +Q = np.zeros((grid_size, grid_size, 4)) # Q-table: (state, action) + +# Hyperparameters +alpha = 0.1 # Learning rate +gamma = 0.9 # Discount factor +epsilon = 0.1 # Exploration rate + +# Define actions (0: up, 1: right, 2: down, 3: left) +actions = [(0, 1), (1, 0), (0, -1), (-1, 0)] + +def choose_action(state): + if np.random.uniform(0, 1) < epsilon: + return np.random.choice(4) # Explore + else: + return np.argmax(Q[state[0], state[1]]) # Exploit + +# Example loop for training the agent +for episode in range(1000): + state = (0, 0) # Starting state + while state != (3, 3): # Goal state + action = choose_action(state) + next_state = (state[0] + actions[action][0], state[1] + actions[action][1]) + reward = -1 if next_state == (1, 1) else 10 if next_state == (3, 3) else 0 + Q[state[0], state[1], action] = (1 - alpha) * Q[state[0], state[1], action] + alpha * (reward + gamma * np.max(Q[next_state[0], next_state[1]])) + state = next_state +``` + +### Summary: +**Reinforcement Learning (RL)** is a powerful framework for solving complex decision-making tasks where an agent must learn to maximize cumulative rewards. By interacting with an environment, the agent learns from experience, balancing exploration and exploitation to improve its performance. RL is widely used in robotics, game playing, and automated control systems. + +--- + +This file explains the concept of reinforcement learning in the same structure as the logistic regression file, providing definitions, characteristics, examples, and code implementation. diff --git a/docs/machine-learning/RidgeRegression.md b/docs/machine-learning/RidgeRegression.md new file mode 100644 index 000000000..45da90716 --- /dev/null +++ b/docs/machine-learning/RidgeRegression.md @@ -0,0 +1,86 @@ +--- +id: ridge-regression +title: Ridge Regression Algorithm +sidebar_label: Ridge Regression +descriptin: "In this post, we'll explore the Ridge Regression Algorithm, it is a type of linear regression that addresses some of the limitations of Ordinary Least Squares (OLS) regression." +tags: [machine learning, algorithms, linear regression, regression] + +--- + +### Definition: +**Ridge Regression** addresses some of the limitations of Ordinary Least Squares (OLS) regression, particularly when dealing with multicollinearity or highly correlated features. + +### Characteristics: +- **Regularization (L2 Penalty)** +Ridge Regression applies an L2 regularization penalty, which adds the square of the coefficient magnitudes to the cost function. This penalty term is what differentiates it from standard linear regression. + +- **Bias-Variance Tradeoff** +Ridge Regression helps to balance the bias-variance tradeoff by adjusting the regularization parameter 𝜆 + +- **Handling Multicollinearity** +Ridge Regression performs well when there is multicollinearity (high correlation between features). + +- **Continuous Shrinking of Coefficients** +Ridge Regression shrinks all coefficients continuously toward zero but does not set any coefficient to zero exactly, unlike Lasso regression. + +### How Ridge Regression Works: +1. **Regularization**: + The penalty term reduces the complexity of the model by shrinking the regression coefficients, which can help prevent overfitting. + +2. **Multicollinearity**: +When features are highly correlated, OLS estimates become unstable. Ridge Regression handles this by imposing a constraint on the size of the coefficients, making them more reliable. + +3. **Bias-Variance Tradeoff**: Increasing 𝜆 introduces bias but reduces variance, creating a tradeoff between the model’s accuracy and generalizability. + +### Choosing the Regularization Parameter (λ) +The regularization parameter λ is usually selected using cross-validation. Common techniques include grid search or randomized search to find the optimal value for λ that minimizes the error on a validation set. + +### Example: +Suppose we have a dataset with one feature 𝑥 and a target variable 𝑦: + +``` +| x | y | +|-------|-------| +| 1 | 1 | +| 2 | 2 | +| 3 | 3 | +| 4 | 4 | +| 5 | 5 | +``` + +Step-by-Step Execution: + +1. **Define the Problem**: +We want to fit a linear model of the form: + 𝑦 = β0 + β1*𝑥 + +where 𝛽0 is the intercept, and 𝛽1 is the coefficient for 𝑥. + +2. **Set Up the Ridge Regression Model in Python** +Using Python, we can compute the Ridge Regression model for this data. We'll use scikit-learn for simplicity and compare it to ordinary least squares (OLS) regression to see the effect of Ridge regularization. + +### Python Implementation: +Here is a basic implementation of Linear Regression in Python using **scikit-learn**: + +```python +from sklearn.linear_model import Ridge +from sklearn.model_selection import train_test_split +from sklearn.metrics import mean_squared_error +import numpy as np + +# Assume X and y are the features and target variables +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# Initialize the Ridge model with alpha as the regularization parameter (lambda) +ridge_reg = Ridge(alpha=1.0) +ridge_reg.fit(X_train, y_train) + +# Predictions and evaluation +y_pred = ridge_reg.predict(X_test) +mse = mean_squared_error(y_test, y_pred) +print("Mean Squared Error:", mse) +``` + +### Summary: +The **Ridge Regression Algorithm** is a powerful technique for addressing multicollinearity and overfitting in linear regression models. By introducing a penalty term, it stabilizes the estimates of regression coefficients, leading to more reliable and interpretable models. Ridge regression finds applications in various fields, including machine learning, genetic studies, econometrics, and engineering, making it an essential tool in the arsenal of statisticians and data scientists. + diff --git a/docs/machine-learning/SDG.md b/docs/machine-learning/SDG.md new file mode 100644 index 000000000..b267be28c --- /dev/null +++ b/docs/machine-learning/SDG.md @@ -0,0 +1,86 @@ +--- +id: stochastic-gradient-descent +title: "Stochastic Gradient Descent (SGD)" +sidebar_label: SGD +description: "Stochastic Gradient Descent (SGD) is an optimization algorithm used to minimize the loss function in machine learning and deep learning models." +tags: [optimization, machine learning, deep learning] + +--- + +### Overview +Stochastic Gradient Descent (SGD) is an optimization algorithm used to minimize the loss function in machine learning and deep learning models. Unlike standard gradient descent, which calculates the gradient of the loss function for the entire dataset, SGD updates the model parameters for each training example one at a time, making it faster and more suitable for large datasets. + +### How It Works + +1. **Initialize Parameters**: Start with some initial values for the model parameters (weights and biases). +2. **Shuffle Data**: Randomly shuffle the training data. +3. **Parameter Update**: + - For each training example \( x_i \), compute the gradient of the loss function with respect to the model parameters. + - Update the parameters using the formula: + $\[\theta = \theta - \eta \cdot \nabla J(\theta; x_i, y_i)\]$ + where: + - \( \theta \) represents the model parameters (weights and biases). + - \( \eta \) is the learning rate (step size). + - \( \nabla J(\theta; x_i, y_i) \) is the gradient of the loss function for the training example \( (x_i, y_i) \). + +4. **Repeat**: Continue this process for multiple epochs (iterations over the entire dataset). + +### Advantages and Disadvantages + +#### Advantages +- **Faster convergence for large datasets**: Because SGD updates parameters for each training example, it can converge faster than batch gradient descent. +- **Better generalization**: The noisy updates can help escape local minima, potentially leading to better generalization on test data. + +#### Disadvantages +- **Noisy updates**: The parameter updates can be noisy because they are based on a single example, which can cause the loss function to fluctuate. +- **Sensitive to learning rate**: Choosing the right learning rate is crucial for proper convergence. + +### Example Code in Python + +Below is an example implementation of SGD to minimize a simple quadratic loss function using NumPy. + +#### Quadratic Loss Function Example + +Let's say we have a simple linear model \( y = wx + b \), and we want to minimize the mean squared error loss function. + +```python +import numpy as np + +# Generate some synthetic data +np.random.seed(0) +X = 2 * np.random.rand(100, 1) +y = 4 + 3 * X + np.random.randn(100, 1) + +# Hyperparameters +learning_rate = 0.01 +n_iterations = 1000 + +# Initialize weights (w) and bias (b) +w = np.random.randn(1) +b = np.random.randn(1) + +# Stochastic Gradient Descent +for iteration in range(n_iterations): + # Randomly select one data point + random_index = np.random.randint(0, len(X)) + x_i = X[random_index:random_index+1] + y_i = y[random_index:random_index+1] + + # Compute the prediction + y_pred = w * x_i + b + + # Compute the gradients + gradient_w = 2 * (y_pred - y_i) * x_i + gradient_b = 2 * (y_pred - y_i) + + # Update weights and bias + w -= learning_rate * gradient_w + b -= learning_rate * gradient_b + + # Print the progress every 100 iterations + if iteration % 100 == 0: + loss = np.mean((y - (w * X + b)) ** 2) + print(f"Iteration {iteration}: Loss = {loss}") + +print(f"Trained weight: {w[0]}, Trained bias: {b[0]}") +``` diff --git a/docs/machine-learning/SVM.md b/docs/machine-learning/SVM.md new file mode 100644 index 000000000..9770c42b6 --- /dev/null +++ b/docs/machine-learning/SVM.md @@ -0,0 +1,167 @@ +--- + +id: svm-visualization +title: Support Vector Machines (SVM) Visualization Algorithm +sidebar_label: SVM +description: "This post explores Support Vector Machines (SVM), a powerful classification algorithm that finds the optimal hyperplane to separate different classes in high-dimensional datasets." +tags: [classification, data visualization, machine learning, SVM, hyperplane, support vectors] + +--- + +### Definition: +**Support Vector Machine (SVM)** is a supervised machine learning algorithm primarily used for classification tasks. It aims to find the optimal hyperplane that maximally separates different classes in the dataset. By using kernel tricks, SVM can also handle non-linearly separable data in higher dimensions. + +### Characteristics: +- **Linear and Non-Linear Classification**: + SVM can perform both linear and non-linear classification by choosing appropriate kernel functions. Linear SVMs are faster but less flexible, while non-linear SVMs (using kernels) can handle complex data structures. + +- **Optimal Hyperplane**: + SVM finds a hyperplane that separates data points of different classes with the maximum possible margin. The data points closest to the hyperplane are called *support vectors* and determine the position of the hyperplane. + +- **Kernel Trick**: + SVM can transform input data into higher dimensions using kernel functions, making it possible to separate data that is not linearly separable in its original space. + +### Components of SVM: +1. **Hyperplane**: + A decision boundary that separates data points of different classes. In 2D, it's a line; in 3D, it's a plane; in higher dimensions, it's called a hyperplane. + +2. **Support Vectors**: + These are the critical data points that lie closest to the hyperplane. They define the margin of the classifier and are pivotal in calculating the optimal hyperplane. + +3. **Margin**: + The margin is the distance between the hyperplane and the closest support vectors from any class. SVM aims to maximize this margin to improve classification accuracy. + +### Steps Involved: +1. **Input Data**: + Provide the high-dimensional input data consisting of features and corresponding class labels. + +2. **Choosing a Kernel**: + Decide whether to use a linear or non-linear SVM. If non-linear, choose an appropriate kernel (e.g., polynomial, RBF). + +3. **Hyperplane Calculation**: + The SVM algorithm finds the optimal hyperplane that maximizes the margin between classes. + +4. **Optimization**: + Use quadratic programming to find the support vectors and the corresponding hyperplane parameters, minimizing classification errors. + +5. **Classification**: + Once trained, the SVM can classify new data points based on which side of the hyperplane they fall. + +### Key Concepts: +- **Hyperplane**: + A decision boundary that splits the data into different classes. SVM selects the hyperplane that maximizes the margin from the nearest data points of each class. + +- **Kernel**: + A function that transforms data into higher dimensions. Popular kernels include: + - **Linear**: Suitable for linearly separable data. + - **Polynomial**: A non-linear kernel using polynomial features. + - **Radial Basis Function (RBF)**: Maps data into an infinite-dimensional space, handling complex relationships. + - **Sigmoid**: Functions like a neural network layer. + +- **Regularization Parameter (C)**: + A hyperparameter that controls the trade-off between maximizing the margin and minimizing classification errors. A lower value allows a larger margin but more misclassification, while a higher value focuses on correctly classifying all training examples. + +### SVM Algorithm Architecture: +1. **Input Layer**: + Input data with features and corresponding class labels. Each observation is a data point in a high-dimensional space. + +2. **Kernel Transformation Layer**: + (Optional) If using a non-linear SVM, the data is transformed into a higher-dimensional space using a kernel function. + +3. **Hyperplane Calculation Layer**: + SVM calculates the optimal hyperplane, which separates data points by maximizing the margin. + +4. **Optimization Layer**: + A cost function is minimized to find the best position for the hyperplane, identifying support vectors that contribute to the decision boundary. + +5. **Classification Layer**: + After training, the model classifies new data points based on their position relative to the hyperplane. + +### Advantages of SVM: +- **Effective in High-Dimensional Spaces**: + SVM performs well in datasets with many features, making it suitable for high-dimensional spaces. + +- **Robust to Overfitting**: + With an appropriate choice of the regularization parameter, SVM is less prone to overfitting, especially in high-dimensional data. + +- **Versatile Kernel Choices**: + The ability to select from a variety of kernels makes SVM adaptable to different types of data distributions. + +### Limitations of SVM: +- **Computational Complexity**: + Training an SVM, especially with non-linear kernels, can be computationally expensive, particularly for large datasets. + +- **Choice of Kernel**: + Selecting the correct kernel and its parameters can be challenging, requiring domain knowledge and experimentation. + +- **No Probabilistic Output**: + SVM doesn’t inherently provide probability estimates, though methods like Platt scaling can add this functionality. + +### Use Cases: +1. **Binary Classification**: + SVM excels in binary classification problems, such as spam detection, where data is divided into two distinct categories. + +2. **Image Classification**: + SVM is commonly used in image recognition tasks due to its ability to handle high-dimensional feature spaces effectively. + +3. **Text Categorization**: + In Natural Language Processing (NLP), SVM can classify documents or sentiments by mapping word features into high dimensions. + +4. **Bioinformatics**: + SVM is popular in bioinformatics for gene classification and protein structure prediction due to its accuracy in high-dimensional biological data. + +### Example of SVM in Python: +```python +import numpy as np +import matplotlib.pyplot as plt +from sklearn import datasets +from sklearn.model_selection import train_test_split +from sklearn.svm import SVC + +# Load dataset +iris = datasets.load_iris() +X = iris.data[:, :2] # Use only the first two features for visualization +y = iris.target + +# Split dataset +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) + +# Train SVM +svm_model = SVC(kernel='linear', C=1) +svm_model.fit(X_train, y_train) + +# Plot decision boundary +plt.figure(figsize=(10, 6)) + +# Create a mesh to plot decision boundary +h = 0.02 +x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 +y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 +xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) +Z = svm_model.predict(np.c_[xx.ravel(), yy.ravel()]) + +# Put the result into a color plot +Z = Z.reshape(xx.shape) +plt.contourf(xx, yy, Z, alpha=0.4, cmap='coolwarm') +plt.scatter(X[:, 0], X[:, 1], c=y, edgecolor='k', s=50) +plt.title("SVM Decision Boundary for Iris Dataset (Linear Kernel)") +plt.xlabel('Feature 1') +plt.ylabel('Feature 2') +plt.show() +``` + +### Time and Space Complexity: +- **Time Complexity**: + The time complexity of SVM varies: + - **Linear SVM**: Approximately $O(n \cdot d)$, where $n$ is the number of samples and $d$ is the number of features. + - **Non-linear SVM**: Approximately $O(n^2)$ for training due to the quadratic programming involved. + +- **Space Complexity**: + The space complexity is $O(n^2)$ due to the storage of pairwise similarities between support vectors. + +### Summary & Applications: +- **SVM** is a powerful tool for classification, known for its ability to find the optimal decision boundary in high-dimensional data. It is versatile, capable of handling both linear and non-linear relationships with the help of kernels, making it widely used in various fields like text categorization, image classification, and bioinformatics. + +- **Applications**: + SVM is utilized in industries like finance, healthcare, and e-commerce for tasks such as fraud detection, medical diagnosis, and customer segmentation, offering a reliable solution for complex classification problems. + diff --git a/docs/machine-learning/Singular_Value_Decomposition_Algorithm.md b/docs/machine-learning/Singular_Value_Decomposition_Algorithm.md new file mode 100644 index 000000000..bda107de4 --- /dev/null +++ b/docs/machine-learning/Singular_Value_Decomposition_Algorithm.md @@ -0,0 +1,129 @@ +--- + +id: singular-value-decomposition +title: Singular Value Decomposition (SVD) Algorithm +sidebar_label: Singular Value Decomposition +description: "In this post, we'll delve into Singular Value Decomposition (SVD), a matrix factorization technique used in linear algebra with applications in dimensionality reduction, image processing, and recommendation systems." +tags: [machine learning, linear algebra, SVD, dimensionality reduction, matrix factorization] + +--- + +### Definition: +**Singular Value Decomposition (SVD)** is a matrix factorization technique used in linear algebra to decompose a matrix into three other matrices. SVD is commonly used in dimensionality reduction, noise reduction, and feature extraction in data analysis and machine learning. + +### Characteristics: +- **Matrix Factorization**: + SVD decomposes a matrix $A$ into three matrices: $U$, $Σ$, and $V^T$, making it possible to analyze matrix properties and reduce dimensionality. + +- **Dimensionality Reduction**: + SVD is frequently used in applications like recommendation systems and image compression to reduce data dimensions while retaining important information. + +- **Orthogonality**: + The matrices $U$ and $V$ in SVD are orthogonal, allowing the representation of data with minimal redundancy. + +### Key Concepts: +1. **Decomposition**: + SVD decomposes a matrix $A$ (of size $m \times n$) into three matrices: + + ![image](https://github.com/user-attachments/assets/af1893e5-c973-472c-b40d-36a68efc6294) + + where: + - $U$ is an $m \times m$ orthogonal matrix (left singular vectors). + - $Σ$ is an $m \times n$ diagonal matrix containing singular values. + - $V^T$ is an $n \times n$ orthogonal matrix (right singular vectors). + +2. **Singular Values**: + The diagonal entries of $Σ$ are known as singular values of $A$. These values indicate the strength or importance of each dimension in the data. + +3. **Rank and Reconstruction**: + SVD can approximate a matrix by keeping only the largest singular values, helping reduce noise and dimensionality. The rank of $A$ corresponds to the number of non-zero singular values in $Σ$. + +4. **Truncated SVD**: + In practice, a truncated version of SVD can be used by retaining only the top $k$ singular values, which significantly reduces data size and is useful for noise reduction. + +### Singular Value Decomposition Process: +1. **Decompose the Matrix**: + Perform SVD on matrix $A$ to obtain $U$, $Σ$, and $V^T$. + +2. **Select Components**: + Choose the top $k$ singular values in $Σ$ for dimensionality reduction. + +3. **Reconstruct Matrix** (optional): + Use the truncated matrices $U_k$, $Σ_k$, and $V_k^T$ to approximate the original matrix $A$ while retaining most of the variance. + +### SVD Algorithm Steps: +1. **Calculate Singular Values**: + Compute the singular values of $A$ by solving for the eigenvalues of $A^T A$ or $A A^T$. + +2. **Form Matrices $U$, $Σ$, and $V^T$**: + The eigenvectors corresponding to the eigenvalues form $U$ and $V$, while $Σ$ holds the singular values. + +3. **Truncate if Necessary**: + For dimensionality reduction, use only the top $k$ singular values and the corresponding columns in $U$ and $V$. + +### Parameters: +- **Matrix $A$**: + The original matrix to be decomposed, often representing data or images. + +- **Rank $k$**: + The number of singular values to retain in truncated SVD, balancing dimensionality reduction and information retention. + +### Advantages of SVD: +- **Efficient Data Compression**: + SVD provides a way to reduce data size without significant loss of information, useful for applications like image compression. + +- **Noise Reduction**: + By omitting smaller singular values, SVD can reduce the noise in data, improving clarity or interpretability. + +- **Feature Extraction**: + SVD can uncover hidden features in data, useful in tasks like topic modeling in natural language processing. + +### Disadvantages of SVD: +- **Computationally Intensive**: + For large matrices, SVD computation can be expensive, as it involves solving eigenvalue problems. + +- **Sensitivity to Outliers**: + SVD can be affected by outliers in the data, potentially impacting the decomposition. + +### Python Implementation: +Here is an example implementation of SVD using **NumPy**: + +```python +import numpy as np + +# Define a sample matrix +A = np.array([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] +]) + +# Perform SVD +U, S, Vt = np.linalg.svd(A, full_matrices=False) + +print("U matrix:\n", U) +print("Singular values:\n", S) +print("Vt matrix:\n", Vt) + +# Reconstruct matrix +reconstructed_A = np.dot(U, np.dot(np.diag(S), Vt)) +print("Reconstructed Matrix:\n", reconstructed_A) +``` + +### SVD Parameters: +In the example above: +- `U`: Contains the left singular vectors. +- `S`: Holds the singular values. +- `Vt`: Contains the right singular vectors transposed. + +### Choosing Parameters: +1. **Rank $k$**: + Select a rank $k$ to retain based on the largest singular values that capture most of the data variance. + +2. **Thresholding Small Singular Values**: + Remove smaller singular values (in $Σ$) to reduce noise, especially in tasks like image or text processing. + +### Summary: +**Singular Value Decomposition (SVD)** is a powerful tool in linear algebra that decomposes a matrix into three simpler matrices, facilitating tasks like dimensionality reduction, noise reduction, and data compression. With applications across machine learning, data science, and signal processing, SVD enables efficient handling of high-dimensional data by capturing essential features while discarding noise. + +--- diff --git a/docs/machine-learning/Statistical_Anomaly_Detection.md b/docs/machine-learning/Statistical_Anomaly_Detection.md new file mode 100644 index 000000000..adf7247f9 --- /dev/null +++ b/docs/machine-learning/Statistical_Anomaly_Detection.md @@ -0,0 +1,184 @@ +--- + +id: statistical-anomaly-detection +title: Statistical Anomaly Detection Algorithm +sidebar_label: Statistical Anomaly Detection +description: "This post covers Statistical Anomaly Detection, a technique used to identify data points that deviate significantly from the norm based on statistical models and methods." +tags: [anomaly detection, statistics, machine learning, outliers, data analysis] + +--- + +### Definition: +**Statistical Anomaly Detection** refers to methods used to detect data points, events, or observations that deviate significantly from the norm, based on statistical models and distributions. These anomalous points, often called *outliers*, may indicate unusual events or errors and are crucial in areas such as fraud detection, network security, quality control, and more. + +### Characteristics: +- **Model-Based**: + Statistical anomaly detection relies on statistical models such as normal distributions, moving averages, or more complex probabilistic models to define what is considered “normal” behavior. + +- **Data-Driven**: + It uses historical data to define normal ranges, thresholds, or patterns and flags any data point that falls outside these boundaries as an anomaly. + +- **Univariate and Multivariate**: + Anomalies can be detected in both univariate data (single variable) or multivariate data (multiple variables or features), depending on the complexity of the problem. + +### Types of Anomalies: +1. **Point Anomalies**: + A single data point is significantly different from the rest of the data (e.g., a temperature reading far beyond the normal range). + +2. **Contextual Anomalies**: + A data point is anomalous within a specific context, but may appear normal in a different context (e.g., a high temperature might be normal in summer but anomalous in winter). + +3. **Collective Anomalies**: + A group of data points is collectively anomalous, even if the individual points may not be (e.g., a sudden, unexpected trend in stock market prices). + +### Components of Statistical Anomaly Detection: +1. **Statistical Model**: + A statistical model is built to define the expected behavior of the data. This could involve normal distribution assumptions, Gaussian processes, or more complex probabilistic models. + +2. **Threshold Setting**: + Once the statistical model is established, thresholds are set. These can be based on standard deviations, percentiles, or confidence intervals that help determine the bounds for normal behavior. + +3. **Outlier Detection**: + Data points that fall outside the normal range or violate the statistical rules are flagged as anomalies. + +4. **Evaluation**: + After detection, the flagged anomalies are reviewed to determine whether they represent true anomalies (e.g., fraud, system malfunction) or false positives (normal data misclassified as anomalous). + +### Common Statistical Techniques for Anomaly Detection: +1. **Z-Score (Standard Score)**: + Measures how many standard deviations a data point is from the mean. A Z-score greater than a set threshold (e.g., |Z| > 3) indicates an anomaly. +![image](https://github.com/user-attachments/assets/da027485-d853-472f-93e4-84b1884fb977) + + where: + - $X$ = data point + - $\mu$ = mean of the data + - $\sigma$ = standard deviation + +2. **Moving Average**: + Anomalies are detected by calculating the moving average of data over a window and flagging points that deviate significantly from it. + +3. **Grubbs' Test**: + A statistical test used to detect outliers in a dataset that follows a normal distribution. Grubbs' Test compares the extreme value to the rest of the dataset, identifying whether it's significantly different. + +4. **IQR (Interquartile Range)**: + Based on the spread of the middle 50% of the data, points are flagged as anomalies if they fall below the 1st quartile or above the 3rd quartile by more than 1.5 times the interquartile range (IQR). +![image](https://github.com/user-attachments/assets/9d8d6719-26ae-465c-a0f5-003040975278) + + Points outside $(Q_1 - 1.5 \times \text{IQR}$ or $Q_3 + 1.5 \times \text{IQR})$ are considered outliers. + +5. **Chi-Square Test**: + For categorical data, this test checks if the observed frequencies differ from expected frequencies. Anomalies are detected if the difference is statistically significant. + +6. **Density Estimation (Gaussian)**: + The likelihood of a data point being part of a known distribution is estimated. Data points with low probability according to the fitted Gaussian distribution are flagged as anomalies. + +### Steps Involved in Statistical Anomaly Detection: +1. **Data Collection**: + Gather the data to be analyzed, which can be univariate or multivariate in nature, depending on the problem. + +2. **Statistical Modeling**: + Fit a statistical model to the data, such as a normal distribution, to understand its expected behavior. + +3. **Threshold Calculation**: + Determine thresholds or cutoff points that define the boundary between normal and anomalous behavior, often using confidence intervals or standard deviations. + +4. **Anomaly Detection**: + Compare incoming data points against the statistical model and thresholds to detect anomalies. Flag any data points that fall outside of the predefined range. + +5. **Post-Processing**: + Evaluate the flagged anomalies to determine if they represent true anomalies or if they are false positives, requiring further investigation or model tuning. + +### Key Concepts: +- **Z-Score**: + A measure of how far a data point is from the mean in terms of standard deviations, used to detect outliers. + +- **P-Value**: + In hypothesis testing, a p-value helps determine whether to reject the null hypothesis (normal behavior). Small p-values indicate anomalies. + +- **Threshold Setting**: + Thresholds define when a data point is considered anomalous, based on statistical rules such as being more than three standard deviations from the mean. + +- **Seasonality and Trend**: + In time series data, statistical models often account for seasonality (repeating patterns) and trends, as anomalies may be detected based on deviations from these patterns. + +### Statistical Anomaly Detection Architecture: +1. **Input Layer**: + The algorithm accepts the input data, which can be univariate (e.g., stock prices) or multivariate (e.g., sensor data). + +2. **Statistical Model Layer**: + The data is modeled using statistical methods like normal distribution, moving average, or hypothesis tests. + +3. **Anomaly Detection Layer**: + The model applies statistical tests or threshold-based rules to identify data points that are anomalous. + +4. **Flagging and Alerting Layer**: + Detected anomalies are flagged and often passed to a downstream system for further investigation or alerting. + +5. **Post-Processing Layer**: + False positives are filtered out, and true anomalies are prioritized for action. + +### Advantages of Statistical Anomaly Detection: +- **Simplicity**: + Statistical methods are easy to understand and implement, often providing a simple and interpretable framework for anomaly detection. + +- **Data-Agnostic**: + These methods can be applied to a wide range of datasets, from time series to categorical data, without needing complex feature engineering. + +- **Real-Time Detection**: + Statistical methods can be used in real-time systems to detect anomalies as new data arrives, enabling rapid response to unusual events. + +### Limitations of Statistical Anomaly Detection: +- **Assumptions About Data Distribution**: + Many statistical techniques assume that the data follows a normal distribution, which may not always be true in real-world scenarios. + +- **Sensitivity to Noise**: + Statistical methods can be sensitive to noise in the data, leading to false positives if the model is not tuned carefully. + +- **Scalability**: + For large datasets or high-dimensional data, statistical methods may become computationally expensive and require optimization. + +### Use Cases: +1. **Fraud Detection**: + In banking or e-commerce, statistical anomaly detection can be used to identify unusual transactions that may indicate fraud. + +2. **Network Intrusion Detection**: + Monitoring network traffic for patterns that deviate from the norm can help detect potential security breaches. + +3. **Quality Control**: + In manufacturing, anomalies detected in sensor data or production metrics can indicate defects or equipment malfunctions. + +4. **Medical Diagnosis**: + Detecting abnormal health metrics in patient data can help identify early signs of medical conditions or anomalies in diagnostic tests. + +### Example of Statistical Anomaly Detection in Python: +```python +import numpy as np +import matplotlib.pyplot as plt +from scipy import stats + +# Generate sample data +np.random.seed(42) +data = np.random.normal(loc=50, scale=5, size=1000) + +# Z-Score calculation +z_scores = np.abs(stats.zscore(data)) + +# Define threshold for anomalies +threshold = 3 +anomalies = np.where(z_scores > threshold) + +# Plot data with anomalies highlighted +plt.figure(figsize=(8, 6)) +plt.plot(data, label='Data') +plt.scatter(anomalies, data[anomalies], color='red', label='Anomalies') +plt.legend() +plt.title("Anomaly Detection using Z-Score") +plt.show() +``` + +### Time and Space Complexity: +- **Time Complexity**: + The time complexity depends on the statistical method used. For example, calculating the Z-score has a linear time complexity of $O(n)$ for n data points. + +- **Space Complexity**: + Space complexity is typically linear, $O(n)$, as the data points need to be stored and diff --git a/docs/machine-learning/Time_Series_Forecasting_Algo.md b/docs/machine-learning/Time_Series_Forecasting_Algo.md new file mode 100644 index 000000000..58dc46257 --- /dev/null +++ b/docs/machine-learning/Time_Series_Forecasting_Algo.md @@ -0,0 +1,199 @@ +--- + +id: time-series-forecasting +title: Time Series Forecasting Algorithms +sidebar_label: Time Series Forecasting +description: "This post covers Time Series Forecasting, a method used to predict future data points in a time-ordered sequence based on past data." +tags: [time series, forecasting, machine learning, ARIMA, LSTM, statistics, predictive analysis] + +--- + +### Definition: +**Time Series Forecasting** is a technique used to predict future values based on previously observed time-ordered data. Time series data are sequences of data points collected or recorded at specific time intervals. Forecasting techniques attempt to model the underlying patterns such as trend, seasonality, and noise to make accurate future predictions. + +### Characteristics: +- **Temporal Dependency**: + Time series forecasting depends heavily on the sequential nature of the data, with future values influenced by past observations. + +- **Pattern Recognition**: + Models identify patterns like trends (long-term increases or decreases), seasonality (cyclic behaviors), and random noise to make predictions. + +- **Extrapolation**: + The goal is to extrapolate the future behavior of the data based on patterns found in historical data. + +- **Real-Time or Batch Predictions**: + Time series models can be applied in real-time scenarios (e.g., stock prices) or for batch forecasting (e.g., sales forecasting for the next quarter). + +### Types of Time Series Components: +1. **Trend**: + A long-term increase or decrease in the data. + +2. **Seasonality**: + A repeating pattern of behavior at regular intervals (e.g., daily, weekly, monthly). + +3. **Cyclical**: + Fluctuations that occur but are not as regular as seasonal patterns, often linked to economic or business cycles. + +4. **Residual (Noise)**: + Irregular, random variations that are not captured by trend or seasonal components. + +### Common Time Series Forecasting Techniques: +1. **ARIMA (AutoRegressive Integrated Moving Average)**: + A widely used statistical method that combines autoregression (AR), differencing to make the data stationary (I), and moving average (MA) to handle the noise in the data. ARIMA is suitable for univariate time series data. + + $y_t = c + \phi_1 y_{t-1} + \phi_2 y_{t-2} + \dots + \theta_1 e_{t-1} + \theta_2 e_{t-2} + \dots + e_t$ + +3. **SARIMA (Seasonal ARIMA)**: + Extends ARIMA by accounting for seasonal effects, which can occur in time series data with repeating cycles over time. + +4. **Exponential Smoothing (ETS Models)**: + Assigns exponentially decreasing weights to past observations, placing more importance on recent data. Variants include Simple Exponential Smoothing, Holt’s Linear Trend Model, and Holt-Winters Seasonal Model. + +5. **Prophet**: + Developed by Facebook, Prophet is an additive model suitable for forecasting time series with daily, weekly, and yearly seasonality. It’s designed to handle missing data and outliers. + +6. **LSTM (Long Short-Term Memory Networks)**: + A type of Recurrent Neural Network (RNN) used for time series forecasting due to its ability to remember long-term dependencies and patterns in sequential data. LSTM is particularly useful for complex, non-linear patterns. + +7. **VAR (Vector AutoRegression)**: + A multivariate time series forecasting method where each variable is predicted using a linear combination of its own past values and the past values of other variables. + +8. **TBATS (Exponential Smoothing State Space Model)**: + A method used for time series with complex seasonalities, such as hourly, daily, and yearly patterns, combining trend, seasonality, and a Box-Cox transformation. + +9. **XGBoost for Time Series**: + Although traditionally used for classification and regression, XGBoost can be adapted for time series forecasting by engineering features such as lags, rolling means, and other relevant variables. + +### Steps in Time Series Forecasting: +1. **Data Collection**: + Gather historical time series data relevant to the problem, ensuring data is consistently spaced in time. + +2. **Data Preprocessing**: + Handle missing values, smooth noisy data, and scale or transform variables if needed. Differencing can be applied to remove trends. + +3. **Stationarity Check**: + Check whether the time series data is stationary (i.e., its statistical properties do not change over time). Techniques like the Augmented Dickey-Fuller (ADF) test can be used. + +4. **Model Selection**: + Choose an appropriate model (e.g., ARIMA, LSTM, Prophet) based on the nature of the time series data and its components (trend, seasonality, etc.). + +5. **Model Training and Validation**: + Split the data into training and validation sets, then train the model on the historical data and evaluate its performance on the validation set. + +6. **Hyperparameter Tuning**: + Adjust model hyperparameters to improve accuracy, such as the order of ARIMA components (p, d, q) or the number of LSTM units. + +7. **Forecasting**: + Generate future predictions based on the trained model, extrapolating the patterns it has learned from the historical data. + +8. **Evaluation**: + Use metrics such as Mean Absolute Error (MAE), Mean Squared Error (MSE), or Mean Absolute Percentage Error (MAPE) to evaluate the model's accuracy on unseen data. + +### Common Metrics for Forecast Accuracy: +- **Mean Absolute Error (MAE)**: + The average of the absolute differences between predicted and actual values. It provides a direct measure of error. +![image](https://github.com/user-attachments/assets/5753d782-2b4d-41d1-9233-1df8440ee3e3) + + +- **Mean Squared Error (MSE)**: + The average of the squared differences between predicted and actual values. It penalizes larger errors more than MAE. +![image](https://github.com/user-attachments/assets/a94b022d-48cf-4a05-8d6f-7baba9315c42) + + +- **Root Mean Squared Error (RMSE)**: + The square root of the MSE, providing an error metric in the same units as the target variable. +![image](https://github.com/user-attachments/assets/61e63777-6a25-43a8-9475-9a92853ece4f) + + +- **Mean Absolute Percentage Error (MAPE)**: + The average of the percentage errors between predicted and actual values. It’s useful for understanding the error in relative terms. +![image](https://github.com/user-attachments/assets/888a2a78-2423-475d-ac4c-b9c9cd270e89) + + +### Time Series Forecasting Algorithms Architecture: +1. **Input Layer**: + The historical time series data is fed into the model, which could be univariate (a single series) or multivariate (multiple series). + +2. **Transformation Layer**: + The data is preprocessed and transformed (e.g., differenced, scaled) to make it suitable for model training. + +3. **Model Layer**: + The chosen model (ARIMA, LSTM, etc.) is applied to capture patterns like trend, seasonality, and noise from the data. + +4. **Prediction Layer**: + The model forecasts future values based on the learned patterns. + +5. **Evaluation Layer**: + Forecasted values are compared against actual values to measure performance and accuracy. + +### Advantages of Time Series Forecasting: +- **Temporal Awareness**: + Time series models are designed to handle sequential data and temporal dependencies, making them ideal for forecasting problems. + +- **Predictive Power**: + With the right model, time series forecasting can produce highly accurate predictions that capture trends, seasonality, and other patterns. + +- **Wide Applicability**: + These methods can be applied in various domains such as finance, sales, weather forecasting, and operations management. + +### Simple Python Implementation for Time Series Forecasting using ARIMA + + ```python + +import pandas as pd +import matplotlib.pyplot as plt +from statsmodels.tsa.arima.model import ARIMA +from sklearn.metrics import mean_squared_error + +#Load sample time series dataset +#Dataset should have a 'Date' column and a 'Value' column (e.g., stock prices, sales data) +data = pd.read_csv('sample_time_series.csv', parse_dates=['Date'], index_col='Date') + +#Split the data into training and testing sets +train_size = int(len(data) * 0.8) +train, test = data[0:train_size], data[train_size:] + +#Fit the ARIMA model +model = ARIMA(train['Value'], order=(5, 1, 0)) # (p, d, q) parameters +model_fit = model.fit() + +#Forecast the next values (based on the test size) +forecast = model_fit.forecast(steps=len(test)) + +#Plot the forecast vs actual values +plt.figure(figsize=(10,6)) +plt.plot(train.index, train['Value'], label='Training Data') +plt.plot(test.index, test['Value'], label='Actual Data', color='green') +plt.plot(test.index, forecast, label='Forecasted Data', color='red') +plt.legend() +plt.title('Time Series Forecasting - ARIMA') +plt.show() + +#Evaluate the model with MSE +mse = mean_squared_error(test['Value'], forecast) +print(f'Mean Squared Error: {mse}') + +``` + +### Explanation of the Code: +1. **Data Loading**: + Load a time series dataset that includes a 'Date' column and a 'Value' column (e.g., stock prices, sales data). + +2. **Train-Test Split**: + The dataset is split into a training set (80% of the data) and a testing set (20%). + +3. **ARIMA Model**: + The ARIMA model is fitted to the training data. The `(5, 1, 0)` parameters are the ARIMA model’s hyperparameters: `p`, `d`, and `q`. These need to be tuned for your specific dataset. + +4. **Forecasting**: + The model forecasts values for the test period. + +5. **Plotting**: + The forecasted data is plotted against the actual test data to visualize the performance. + +6. **Model Evaluation**: + The Mean Squared Error (MSE) is calculated to quantify the forecast accuracy. + +### Conclusion: +Time series forecasting provides essential insights and predictive power for data that follows a sequential or time-dependent structure. Whether using traditional models like ARIMA or advanced models like LSTM, these methods help extract patterns from historical data to forecast future values. + diff --git a/docs/machine-learning/XGBoost.md b/docs/machine-learning/XGBoost.md new file mode 100644 index 000000000..4836aebd7 --- /dev/null +++ b/docs/machine-learning/XGBoost.md @@ -0,0 +1,102 @@ +--- + +id: xgboost +title: XGBoost Algorithm +sidebar_label: XGBoost +description: "XGBoost is a highly efficient and scalable machine learning algorithm known for its accuracy and speed in solving both classification and regression problems." +tags: [machine learning, algorithms, xgboost, classification, regression] + +--- + +### Definition: +**XGBoost (eXtreme Gradient Boosting)** is a supervised learning algorithm that implements gradient boosting for classification and regression tasks. It builds an ensemble of decision trees in a sequential manner, where each subsequent tree aims to reduce the errors of the previous trees, improving accuracy through boosting techniques. + +### Characteristics: +- **Boosting Technique**: + XGBoost uses a boosting method where weak learners (shallow trees) are combined iteratively to create a strong predictive model. Each tree tries to correct the errors made by the previous one, focusing on harder-to-predict instances. + +- **Highly Efficient**: + XGBoost is known for its speed and performance optimizations, utilizing techniques such as parallel tree boosting and hardware optimization to handle large-scale datasets efficiently. + +- **Regularization**: + Unlike traditional boosting, XGBoost includes regularization parameters to prevent overfitting, making it a robust choice even for noisy data. + + +### Steps Involved: +1. **Initialize the Model**: + XGBoost starts by initializing predictions with a base value (such as the average of the target values in regression). + +2. **Fit Gradient-Boosted Trees**: + Sequentially add decision trees, each one trained to reduce the residual errors of the model’s predictions from the previous iteration. + +3. **Update Weights**: + At each step, the algorithm updates the weights of misclassified instances, assigning higher weights to the harder-to-predict instances in classification or high-error instances in regression. + +4. **Predict and Aggregate**: + The final model aggregates the predictions of all trees, weighted by their learning rates, to output the final classification or regression prediction. + +### Problem Statement: +Given a dataset, the goal of XGBoost is to iteratively build a model that minimizes the prediction error by adding trees that improve upon the mistakes of previous ones, effectively handling both classification and regression tasks. + +### Key Concepts: +- **Boosting**: + A technique that combines multiple weak learners (e.g., shallow decision trees) into a strong predictive model. + +- **Learning Rate**: + A parameter that scales the contribution of each new tree added to the model, balancing the trade-off between the speed of learning and generalization. + +- **Max Depth**: + Limits the depth of the trees to prevent overfitting, controlling model complexity. + +### Objective Function: +The objective function minimized by XGBoost is defined as: + +$Obj(\Theta) = \sum_{i=1}^{n} L(y_i, \hat{y}) + \sum_{k=1}^{K} \Omega(f_k)$ + + + +Where: +- $L(y_i, \hat{y}_i)$ is the loss function measuring the difference between true values ($y_i$) and predicted values \($\hat{y}_i$). +- $\Omega(f_k)$ is the regularization term penalizing the complexity of the model. + +### Time Complexity: +- **Best, Average, and Worst Case: $O(n \log n)$** + XGBoost optimizes tree construction with a greedy algorithm, achieving logarithmic time complexity for each tree based on the number of training instances `n`. + +### Space Complexity: +- **Space Complexity: $O(n)$** + The memory footprint grows with the number of data points, as XGBoost needs to store gradient and Hessian information for each instance during training. + +### Python Implementation: +Here is a basic implementation of XGBoost in Python using the **XGBoost** library: + +```python +import xgboost as xgb +from sklearn.model_selection import train_test_split +from sklearn.datasets import load_boston +from sklearn.metrics import mean_squared_error + +# Load dataset +data = load_boston() +X, y = data.data, data.target + +# Split into training and testing sets +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# Create XGBoost model +model = xgb.XGBRegressor(objective='reg:squarederror', n_estimators=100, learning_rate=0.1) + +# Train model +model.fit(X_train, y_train) + +# Make predictions +predictions = model.predict(X_test) + +# Calculate mean squared error +mse = mean_squared_error(y_test, predictions) +print(f'Mean Squared Error: {mse}') +``` + +### Summary: +**XGBoost** is a powerful, efficient, and scalable machine learning algorithm. Its regularization capabilities, combined with its use of gradient boosting, make it a popular choice for a wide range of tasks. + diff --git a/docs/machine-learning/decisionTree.md b/docs/machine-learning/decisionTree.md new file mode 100644 index 000000000..974370c0c --- /dev/null +++ b/docs/machine-learning/decisionTree.md @@ -0,0 +1,135 @@ +--- +id: decision-tree +title: Decision Tree Algorithm +sidebar_label: Decision Tree +description: "In this post, we'll explore the Decision Tree Algorithm, a popular machine learning model used for classification and regression tasks." +tags: [machine learning, algorithms, decision tree, classification, regression] + +--- + +### Definition: +The **Decision Tree Algorithm** is a supervised machine learning algorithm used for both **classification** and **regression** tasks. It splits data into subsets based on feature values, creating a tree-like structure where each internal node represents a decision based on a feature, and each leaf node represents an outcome (class label or continuous value). + +### Characteristics: +- **Recursive Partitioning**: + A decision tree recursively splits the dataset based on specific conditions (features) to form a tree structure that leads to a prediction at each leaf node. + +- **Interpretability**: + Decision trees are highly interpretable because the decision-making process is clear and transparent. You can easily follow the path of decisions from root to leaf to understand how a prediction is made. + +- **Non-parametric**: + This algorithm doesn’t make any assumptions about the underlying data distribution, making it suitable for a variety of datasets. + +### Types of Decision Trees: +1. **Classification Tree**: + Used when the target variable is categorical (e.g., yes/no, spam/ham). It predicts the class label based on the features. + +2. **Regression Tree**: + Used when the target variable is continuous (e.g., predicting a price). It predicts a real number based on the features. + +### Steps Involved: +1. **Choose the Best Split**: + The dataset is split based on the feature that maximizes some criteria. For classification, **Gini Index** or **Entropy** (used in information gain) is commonly used. For regression, **mean squared error** is often the criterion. + +2. **Recursively Split**: + The process is repeated recursively for each subset, creating branches until no further meaningful splits can be made (e.g., when the data is perfectly classified or a stopping criterion like maximum depth is reached). + +3. **Assign Leaf Nodes**: + Once the splitting stops, the leaf nodes are assigned a class label (for classification) or a value (for regression). + +### Problem Statement: +Given a dataset with features and target values, the goal is to build a decision tree that can **classify** data points into categories or **predict** continuous values based on the features. + +### Key Concepts: +- **Root Node**: + The top-most node in the tree, where the first feature split occurs. + +- **Internal Nodes**: + Nodes where further feature splits occur based on the conditions. + +- **Leaf Nodes**: + Terminal nodes that hold the final prediction (class or value). + +### Split Criteria: +- **Gini Impurity** (for classification): + Measures the probability of a randomly chosen element being misclassified. + +![image](https://github.com/user-attachments/assets/505d8d21-3f41-4bba-9120-4ad98beec8c1) + + + Where \( p_i \) is the probability of the class label at node \( i \). + +- **Entropy** (for classification): + Measures the disorder or impurity in the dataset. + +![image](https://github.com/user-attachments/assets/954fa9ab-f3d6-4055-8c12-7630dd8e6a50) + + + Where \( p_i \) is the proportion of data points in class \( i \). + +- **Information Gain**: + Measures the reduction in entropy after a dataset is split on a feature. + +![image](https://github.com/user-attachments/assets/e0eecef3-6e4d-414c-a963-19708922ed91) + + +- **Mean Squared Error (MSE)** (for regression): + Measures the variance between the predicted and actual values at each node. + +### Time Complexity: +- **Best, Average, and Worst Case: $O(n \log n)$** + The time complexity depends on sorting the dataset at each node. For `n` data points, the overall complexity is logarithmic in depth with respect to the size of the dataset. + +### Space Complexity: +- **Space Complexity: $O(n)$** + The space complexity arises from storing the tree structure and the data used for training. + +### Example: +Consider a dataset for predicting whether someone buys a product based on their **age** and **income**: + +- Dataset: + ``` + | Age | Income | Buys Product | + |-------|---------|--------------| + | 25 | High | Yes | + | 45 | Medium | No | + | 35 | Low | Yes | + | 22 | Low | Yes | + ``` + +Step-by-Step Execution: + +1. **Choose the best split**: + Using a criterion like Gini Impurity or Information Gain, the algorithm will decide which feature (Age or Income) provides the best split. + +2. **Recursively split**: + It splits the data and continues until leaf nodes are formed, which represent the final decision (Yes/No for classification). + +### Python Implementation: +Here is a basic implementation of a Decision Tree in Python using **scikit-learn**: + +```python +from sklearn.datasets import load_iris +from sklearn.tree import DecisionTreeClassifier +from sklearn import tree +import matplotlib.pyplot as plt + +# Load dataset +iris = load_iris() +X, y = iris.data, iris.target + +# Create Decision Tree classifier +clf = DecisionTreeClassifier() + +# Train model +clf = clf.fit(X, y) + +# Plot the tree +plt.figure(figsize=(12,8)) +tree.plot_tree(clf, filled=True, feature_names=iris.feature_names, class_names=iris.target_names) +plt.show() +``` + +### Summary: +The **Decision Tree Algorithm** is a simple yet powerful model that can be used for both classification and regression tasks. Its ease of interpretation, ability to handle both categorical and numerical data, and non-parametric nature make it a versatile choice for many machine learning problems. However, decision trees are prone to **overfitting**, which can be mitigated by techniques like **pruning**, **random forests**, or **ensemble methods**. + diff --git a/docs/machine-learning/hierarchical-clustering-visualizations.md b/docs/machine-learning/hierarchical-clustering-visualizations.md new file mode 100644 index 000000000..4e82312d5 --- /dev/null +++ b/docs/machine-learning/hierarchical-clustering-visualizations.md @@ -0,0 +1,129 @@ +--- + +id: hierarchical-clustering-visualizations +title: Hierarchical Clustering Visualizations +sidebar_label: Hierarchical Clustering +description: "Implement hierarchical clustering algorithms that build a hierarchy of clusters using either agglomerative or divisive methods. This feature will include visualizations to help users understand the clustering process." +tags: [data science, clustering, hierarchical clustering, data visualization, machine learning] + +--- + +### Definition: +**Hierarchical Clustering** is an unsupervised machine learning technique that creates a hierarchy of clusters, allowing data points to be grouped based on their similarities. This method can be performed in two ways: agglomeratively (bottom-up) and divisively (top-down). + +### Characteristics: +- **Dendrogram Representation**: + Hierarchical clustering can be visualized using a dendrogram, which illustrates the relationships between clusters at various levels of granularity. + +- **Flexible Number of Clusters**: + Unlike K-Means, hierarchical clustering does not require specifying the number of clusters in advance. + +- **Distance Metrics**: + Various distance metrics (e.g., Euclidean, Manhattan) and linkage criteria (e.g., single, complete, average) can be used to determine how clusters are formed. + +### Components of Hierarchical Clustering: +1. **Clusters**: + Groups of similar data points that are merged or split during the clustering process. + +2. **Dendrogram**: + A tree-like diagram that shows the arrangement of clusters and the distances at which merges or splits occur. + +3. **Linkage Criteria**: + Methods used to define the distance between clusters, affecting the shape and size of the resulting clusters. + +### Steps Involved: +1. **Choose a Distance Metric**: + Select a method to measure the distance between data points. + +2. **Build the Dendrogram**: + Start with each data point as its own cluster and iteratively merge clusters based on the selected distance metric and linkage criteria. + +3. **Cut the Dendrogram**: + Determine the number of clusters by cutting the dendrogram at a specified height. + +4. **Assign Clusters**: + Based on the cuts, assign data points to their respective clusters. + +### Key Concepts: +- **Agglomerative Clustering**: + A bottom-up approach where each data point starts as a separate cluster and clusters are merged based on distance. + +- **Divisive Clustering**: + A top-down approach that starts with one cluster and recursively splits it into smaller clusters. + +- **Linkage Methods**: + Common methods include single linkage (minimum distance), complete linkage (maximum distance), and average linkage (mean distance). + +### Advantages of Hierarchical Clustering: +- **Intuitive Visualization**: + The dendrogram provides a clear visual representation of the clustering process and relationships. + +- **No Need for Predefined K**: + Users can choose the number of clusters after inspecting the dendrogram. + +- **Handles Different Cluster Shapes**: + Can capture clusters of various shapes and sizes, unlike K-Means. + +### Limitations of Hierarchical Clustering: +- **Computationally Intensive**: + The time complexity can be high, especially for large datasets, making it less suitable for very large datasets. + +- **Sensitive to Noise**: +Outliers can distort the clustering structure and affect results. + +- **Linkage Dependency**: +The choice of linkage method can significantly influence the resulting clusters. + +### Popular Applications of Hierarchical Clustering: +1. **Genomics**: + Used to group genes or samples based on expression data to identify biological patterns. + +2. **Market Research**: + Helps in segmenting customers based on purchasing behavior for targeted marketing strategies. + +3. **Document Clustering**: + Groups similar documents for efficient retrieval and organization. + +4. **Image Segmentation**: + Clusters similar pixels to delineate objects within images. + +5. **Social Network Analysis**: + Identifies communities or groups within social networks based on interaction patterns. + +### Example of Hierarchical Clustering in Python: +```python +import numpy as np +import matplotlib.pyplot as plt +import seaborn as sns +from sklearn.datasets import make_blobs +from scipy.cluster.hierarchy import dendrogram, linkage + +# Create a sample dataset +X, _ = make_blobs(n_samples=100, centers=3, cluster_std=0.60, random_state=0) + +# Perform hierarchical clustering +linked = linkage(X, method='ward') + +# Create a dendrogram +plt.figure(figsize=(10, 7)) +dendrogram(linked, orientation='top', distance_sort='descending', show_leaf_counts=True) +plt.title('Hierarchical Clustering Dendrogram') +plt.xlabel('Sample Index') +plt.ylabel('Distance') +plt.show() +``` + +### Time and Space Complexity: +- **Time Complexity**: + The time complexity is generally $O(n^3)$ for the basic implementation, but more efficient methods exist. + +- **Space Complexity**: + The space required is $O(n^2)$ for storing distance matrices. + +### Summary & Applications: +- **Hierarchical Clustering** is a versatile technique that provides valuable insights into data structures and relationships, making it essential for exploratory data analysis. + +- **Applications**: + Effective in various fields such as genomics, marketing, and image processing, helping uncover patterns and facilitate decision-making. + +--- \ No newline at end of file diff --git a/docs/machine-learning/naive-bayes.md b/docs/machine-learning/naive-bayes.md new file mode 100644 index 000000000..ecf4fe56a --- /dev/null +++ b/docs/machine-learning/naive-bayes.md @@ -0,0 +1,176 @@ +--- +id: naive-bayes-theorem +title: Naive Bayes Algorithm +sidebar_label: Naive Bayes +description: "In this post, we’ll explore the Naive Bayes Theorem, a fundamental probabilistic algorithm used for classification tasks based on Bayes' Theorem and the assumption of conditional independence." +tags: [machine learning, algorithms, naive bayes, classification, bayes theorem, probability] +--- + +### Definition: +The **Naive Bayes** algorithm is a probabilistic classifier based on **Bayes' Theorem** with the assumption that the features are conditionally independent given the class label. Despite the "naive" assumption of feature independence, it is highly effective for various real-world applications such as spam filtering, text classification, and recommendation systems. + + + +### Characteristics: +- **Probabilistic Model**: + Naive Bayes predicts the class label by calculating the posterior probability of each class based on the input features and selecting the class with the highest probability. + +- **Conditional Independence Assumption**: + Naive Bayes assumes that each feature is independent of others given the class label, which simplifies the calculation of probabilities but may not always hold in practice. + +- **Efficient and Scalable**: + Naive Bayes is computationally efficient and can scale well to large datasets with multiple features. + +### Types of Naive Bayes: +1. **Gaussian Naive Bayes**: + Used when the features are continuous and follow a Gaussian (normal) distribution. Commonly applied in cases where the data can be assumed to be normally distributed. + +2. **Multinomial Naive Bayes**: + Used for discrete data, often applied in text classification, where the features represent counts or frequencies of words (e.g., spam detection). + +3. **Bernoulli Naive Bayes**: + Applied to binary data, where the features take on binary values (e.g., presence or absence of a word in text classification). + + + +### Steps Involved: +1. **Input the Data**: + The algorithm receives labelled training data, where each example consists of a set of features and a corresponding class label. + +2. **Calculate Prior Probabilities**: + The prior probability of each class is computed based on the frequency of each class in the training data. + +3. **Calculate Likelihood**: + For each feature and class, the likelihood is calculated by determining how likely it is to observe a particular feature value given the class. + +4. **Apply Bayes' Theorem**: + Using Bayes' Theorem, the posterior probability of each class is calculated based on the priors and likelihoods: + + $$ + P(y|X) = \frac{P(X|y) \cdot P(y)}{P(X)} + $$ + + where $P(y|X)$ is the posterior probability of the class given the feature vector, $P(X|y)$ is the likelihood, $P(y)$ is the prior, and $P(X)$ is the evidence. + +5. **Classify New Data**: + For a new data point, the algorithm computes the posterior probability for each class and assigns the label of the class with the highest probability. + + + +### Problem Statement: +Given a dataset with multiple features and corresponding class labels, the objective is to train a Naive Bayes classifier that can predict the class label for new, unseen data based on the calculated probabilities. + +### Key Concepts: +- **Bayes' Theorem**: + Bayes' Theorem is a mathematical formula used to calculate conditional probabilities. It is expressed as: + + $$ + P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} + $$ + + where: + - $P(A|B)$ is the posterior probability of event $A$ given that $B$ is true. + - $P(B|A)$ is the likelihood of observing $B$ given that $A$ is true. + - $P(A)$ is the prior probability of event $A$. + - $P(B)$ is the total probability of event $B$. + +- **Prior Probability**: + The prior probability represents the initial belief about the class labels before considering any feature values, based on the distribution of classes in the training data. + +- **Likelihood**: + The likelihood is the probability of observing the feature values given a specific class label. + +- **Posterior Probability**: + The posterior probability is the probability of a class label after considering the observed feature values, which is what Naive Bayes uses to make predictions. + +- **Naive Assumption**: + Naive Bayes assumes that all features are independent given the class, simplifying the probability calculations. This assumption, although unrealistic in many cases, allows for efficient computation and often leads to good results. + + + +### Split Criteria: +Naive Bayes splits data based on the **highest posterior probability** for each class, assigning the class label that maximizes this probability. + +### Time Complexity: +- **Training Complexity**: + Training involves calculating probabilities for each feature and class, resulting in a time complexity of $ O(n \cdot k) $, where $ n $ is the number of features and $ k $ is the number of classes. + +- **Prediction Complexity**: + For predicting the class of a new data point, the time complexity is $ O(n \cdot k) $, as it requires computing the posterior probability for each class. + +### Space Complexity: +- **Space Complexity**: + The space complexity is mainly determined by storing the calculated probabilities, which depends on the number of features, classes, and their possible values. + +### Example: +Consider a spam detection system that classifies emails as "spam" or "not spam" based on features such as the presence of certain words (binary features). + +**Dataset:** + +| Word 'Free' | Word 'Money' | Spam | +|-------------|--------------|------| +| Yes | Yes | Yes | +| Yes | No | No | +| No | Yes | Yes | +| No | No | No | + +Step-by-Step Execution: + +1. **Input Data**: + The model receives training data with features (words) and labels (spam/not spam). + +2. **Calculate Priors**: + The prior probabilities of the classes (spam and not spam) are calculated based on the class distribution: + + $$ + P(\text{Spam}) = \frac{\text{Number of spam emails}}{\text{Total number of emails}} + $$ + + $$ + P(\text{Not Spam}) = \frac{\text{Number of non-spam emails}}{\text{Total number of emails}} + $$ + +3. **Calculate Likelihoods**: + For each word (feature) and class, the likelihood is calculated. For example: + + $$ + P(\text{Free}|\text{Spam}) = \frac{\text{Number of spam emails containing 'Free'}}{\text{Total number of spam emails}} + $$ + +4. **Apply Bayes' Theorem**: + Using Bayes' Theorem, the posterior probabilities for new emails are calculated. + +5. **Make Predictions**: + The class with the highest posterior probability is predicted (spam or not spam). + + + +### Python Implementation: +Here is a basic implementation of Naive Bayes using **scikit-learn**: + +```python +from sklearn.datasets import load_iris +from sklearn.model_selection import train_test_split +from sklearn.naive_bayes import GaussianNB +from sklearn.metrics import accuracy_score + +# Load dataset +iris = load_iris() +X, y = iris.data, iris.target + +# Split dataset +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# Create Gaussian Naive Bayes model +nb = GaussianNB() + +# Train model +nb.fit(X_train, y_train) + +# Predict +y_pred = nb.predict(X_test) + +# Evaluate +accuracy = accuracy_score(y_test, y_pred) +print(f"Accuracy: {accuracy:.2f}") +``` diff --git a/docs/machine-learning/neuralNetworks.md b/docs/machine-learning/neuralNetworks.md new file mode 100644 index 000000000..9fb24dfad --- /dev/null +++ b/docs/machine-learning/neuralNetworks.md @@ -0,0 +1,178 @@ +--- + +id: neural-networks-visualizations +title: Neural Networks Visualizations +sidebar_label: Neural Networks +description: "Build and visualize neural networks with support for feedforward, convolutional, and recurrent architectures. Explore how these models learn from data using backpropagation and gradient descent." +tags: [machine learning, neural networks, deep learning, data visualization, feedforward networks, CNN, RNN] + +--- + +### Definition: +**Neural Networks** are a class of machine learning algorithms inspired by the human brain. They consist of interconnected layers of nodes (neurons) that process data by learning patterns and relationships from examples. Neural networks are the foundation of deep learning, used in various domains, including computer vision, natural language processing, and reinforcement learning. + +### Characteristics: +- **Layered Architecture**: + Neural networks are typically organized into layers — an input layer, one or more hidden layers, and an output layer. + +- **Activation Functions**: + Each neuron uses an activation function (e.g., sigmoid, ReLU, softmax) to determine the output, adding non-linearity to the network. + +- **Backpropagation**: + A key algorithm used for training neural networks, where the error is propagated back through the layers to update the weights. + +### Components of Neural Networks: +1. **Neurons**: + The basic units that receive input, apply an activation function, and pass the output to the next layer. + +2. **Weights and Biases**: + Parameters that determine the strength of connections between neurons. Weights are adjusted during training to minimize the error. + +3. **Activation Functions**: + Functions applied to the weighted sum of inputs to introduce non-linearity (e.g., ReLU, sigmoid, tanh). + +4. **Loss Function**: + A function that quantifies the difference between the predicted and actual outputs, guiding the learning process. + +5. **Optimizer**: + An algorithm (e.g., SGD, Adam) that adjusts the weights during training to minimize the loss function. + +### Steps Involved: +1. **Initialize the Model**: + Define the architecture, including the number of layers, neurons per layer, activation functions, and initialization of weights. + +2. **Forward Propagation**: + Input data passes through each layer, and neurons apply their activation functions to produce the output. + +3. **Compute Loss**: + Calculate the difference between the predicted and actual output using a loss function. + +4. **Backpropagation**: + Compute gradients of the loss function concerning weights and biases, adjusting them to minimize the error. + +5. **Update Weights**: + Adjust weights using an optimizer algorithm to improve the network's predictions iteratively. + +6. **Iterate**: + Repeat the forward and backward propagation steps for multiple iterations (epochs) until convergence. + +### Key Concepts: +- **Feedforward Networks (FFNN)**: + Data flows unidirectionally from input to output. Often used for regression and classification tasks. + +- **Convolutional Neural Networks (CNN)**: + Specialized for image processing, CNNs use convolutional layers to detect patterns such as edges, shapes, and textures. + +- **Recurrent Neural Networks (RNN)**: + Designed for sequential data, RNNs have connections that loop, allowing them to maintain memory of previous inputs — ideal for time-series or language data. + +- **Deep Learning**: + Refers to neural networks with many hidden layers (deep networks) that can capture complex relationships in data. + +### Neural Networks Architecture: +1. **Input Layer**: + Accepts raw input data, such as images, text, or numerical values, and passes it to the first hidden layer. + +2. **Hidden Layers**: + Each hidden layer processes the data using weights, biases, and activation functions. These layers extract features or patterns from the data. + +3. **Output Layer**: + Produces the final prediction, often using a softmax (classification) or linear activation (regression) function. + +4. **Connections**: + Fully connected, convolutional, or recurrent connections between neurons define how data flows through the network. + +### Advantages of Neural Networks: +- **High Accuracy**: + Neural networks can achieve state-of-the-art results in various domains, particularly with deep architectures. + +- **Versatility**: + They can handle different data types — images, text, audio, video, and time-series. + +- **Feature Learning**: + Automatically learn features from raw data, reducing the need for manual feature engineering. + +### Limitations of Neural Networks: +- **Computationally Intensive**: + Neural networks, especially deep ones, require significant computational resources (GPU/TPU) for training. + +- **Data Hungry**: + Large amounts of labeled data are often necessary for training effective models. + +- **Interpretability**: + Neural networks are sometimes seen as "black boxes," making it difficult to interpret how they make decisions. + +### Popular Neural Network Architectures: +1. **Feedforward Neural Networks (FFNN)**: + The simplest form of neural networks with no cycles. Each layer's output is passed directly to the next layer. + +2. **Convolutional Neural Networks (CNN)**: + Use convolutional layers for feature extraction, making them powerful for tasks like image classification, object detection, and segmentation. + +3. **Recurrent Neural Networks (RNN)**: + Designed to handle sequential data, RNNs are commonly used for tasks like language modeling, time-series forecasting, and machine translation. + +4. **Generative Adversarial Networks (GANs)**: + Consist of two networks — a generator and a discriminator — working against each other to produce realistic data, such as images. + +5. **Transformers**: + Advanced architecture that uses self-attention mechanisms, revolutionizing natural language processing tasks like translation, summarization, and sentiment analysis. + +### Use Cases: +1. **Image Classification**: + CNNs are used to classify images into categories (e.g., identifying objects in photos). + +2. **Natural Language Processing (NLP)**: + RNNs, LSTMs, and Transformers are used for tasks like sentiment analysis, machine translation, and chatbots. + +3. **Speech Recognition**: + Deep neural networks process audio data for speech-to-text conversion and voice assistants. + +4. **Time-Series Prediction**: + RNNs are employed for forecasting future trends based on past data in finance, weather, or inventory management. + +5. **Autonomous Driving**: + CNNs analyze images from cameras to detect lanes, vehicles, and pedestrians. + +### Example of Neural Networks in Python: +```python +import numpy as np +import tensorflow as tf +from tensorflow.keras.models import Sequential +from tensorflow.keras.layers import Dense + +# Create a simple Feedforward Neural Network using TensorFlow +model = Sequential([ + Dense(32, activation='relu', input_shape=(10,)), # Hidden Layer 1 + Dense(16, activation='relu'), # Hidden Layer 2 + Dense(1, activation='sigmoid') # Output Layer for Binary Classification +]) + +# Compile the model +model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) + +# Sample training data +X_train = np.random.rand(100, 10) # 100 samples, 10 features +y_train = np.random.randint(2, size=100) # Binary target + +# Train the model +model.fit(X_train, y_train, epochs=10, batch_size=8) + +# Summary of the model architecture +model.summary() +``` + +### Time and Space Complexity: +- **Time Complexity**: + Forward and backward propagation in a neural network is roughly $O(d \cdot n \cdot k)$, where $d$ is the number of layers, $n$ is the number of neurons per layer, and $k$ is the number of training samples. + +- **Space Complexity**: + The memory required is $O(d \cdot n)$ for storing weights, biases, and intermediate activations. + +### Summary & Applications: +- **Neural Networks** are powerful algorithms capable of learning complex patterns from data. They have revolutionized many fields, including computer vision, natural language processing, and autonomous systems. + +- **Applications**: + Widely used in image recognition, speech synthesis, language translation, game playing, and anomaly detection. + +--- diff --git a/docs/machine-learning/random-forest.md b/docs/machine-learning/random-forest.md new file mode 100644 index 000000000..ed06157da --- /dev/null +++ b/docs/machine-learning/random-forest.md @@ -0,0 +1,131 @@ +--- +id: random-forest +title: Random Forest Algorithm +sidebar_label: Random Forest +description: "In this post, we’ll dive into the Random Forest Algorithm, an ensemble learning model used for classification and regression tasks, known for its robustness and versatility." +tags: [machine learning, algorithms, random forest, classification, regression] +--- + +### Definition: +The **Random Forest Algorithm** is a versatile and widely-used ensemble learning technique that builds multiple decision trees during training and combines their predictions to improve accuracy and robustness. This algorithm is applicable to both **classification** and **regression** tasks. The core idea behind random forests is that by averaging or "voting" across many decision trees, the overall prediction is more reliable and less prone to overfitting compared to individual trees. + +### Characteristics: +- **Ensemble Learning**: + Random forest is an ensemble method, meaning it aggregates the outputs of many decision trees to make a final prediction, which helps to enhance performance and reduce overfitting. + +- **Randomness in Trees**: + The algorithm introduces randomness in two main ways: it selects random subsets of features at each split, and it trains each tree on a random subset of the training data (with replacement, known as **bootstrap sampling**). This leads to diverse trees, improving model accuracy. + +- **Robustness**: + Random forest is robust against overfitting, especially when compared to single decision trees. It can handle missing values, and because it averages predictions, it is less sensitive to noise in the data. + +### Types of Random Forest: +1. **Classification Forest**: + Used when the target variable is categorical (e.g., yes/no, dog/cat). It uses majority voting across multiple trees to assign a class label. + +2. **Regression Forest**: + Used when the target variable is continuous (e.g., predicting a price). It takes the average of the predictions from all the trees to generate a final output. + +### Steps Involved: +1. **Bootstrap Sampling**: + For each tree, the algorithm randomly selects a subset of the training data with replacement (bootstrapping). This ensures each tree is trained on different data, promoting diversity among the trees. + +2. **Feature Randomness**: + At each node of a tree, a random subset of features is selected to find the best possible split. This further diversifies the trees and prevents overfitting. + +3. **Grow Decision Trees**: + Each tree is grown to its maximum depth without pruning. However, individual trees may be weak, but the ensemble (forest) of many trees is strong. + +4. **Aggregate Results**: + For classification tasks, the forest takes a majority vote across all trees to decide the final class. For regression tasks, it takes the average of the predictions from all trees. + +### Problem Statement: +Given a dataset with features and target values, the goal is to build a random forest that can **classify** data points into categories or **predict** continuous values by leveraging the power of multiple decision trees. + +### Key Concepts: +- **Bootstrap Aggregation (Bagging)**: + This technique trains each tree on a randomly selected subset of the dataset (with replacement), promoting diversity in the ensemble. + +- **Out-of-Bag (OOB) Error**: + Since each tree is trained on a random subset of the data, about one-third of the data is not used during training and can be used to estimate the model’s accuracy (out-of-bag error) without the need for a separate validation set. + +- **Majority Voting (for Classification)**: + The final prediction for a classification task is based on the class that gets the most votes from the trees. + +- **Averaging (for Regression)**: + The final prediction for a regression task is the average of the predictions from all trees. + +### Split Criteria: +- **Gini Impurity**: + Like in decision trees, Gini impurity is used for evaluating splits in classification problems. It measures how often a randomly chosen element would be misclassified if it was randomly labeled. + +- **Mean Squared Error (MSE)**: + For regression tasks, the mean squared error is used to find the optimal splits that minimize the variance between predicted and actual values. + +### Time Complexity: +- **Training Complexity**: + For a random forest of `T` trees, each trained on `n` samples and with `d` features, the time complexity for training is approximately $O(T \cdot n \cdot d \cdot \log n)$. + +- **Prediction Complexity**: + For making predictions, each tree in the forest contributes, so the complexity is $O(T \cdot \log n)$ for a forest with `T` trees and `n` data points. + +### Space Complexity: +- **Space Complexity**: + The space complexity is $O(T \cdot n \cdot d)$ due to the storage of `T` trees, each with `n` samples and `d` features. + +### Example: +Consider a dataset to classify whether a customer will churn based on factors like age, income, and customer activity: + +- Dataset: +| Age | Income | Active | Churned | +|-----|--------|--------|---------| +| 25 | High | Yes | No | +| 45 | Medium | No | Yes | +| 35 | Low | Yes | No | +| 22 | Low | No | Yes | + + + +Step-by-Step Execution: + +1. **Bootstrap Sampling**: + Each tree gets a random sample of the data to train on, with some data points potentially appearing multiple times in the sample. + +2. **Random Feature Selection**: + At each node, a random subset of features (e.g., Age or Income) is selected to find the best split. + +3. **Grow Trees**: + Each tree grows fully, creating a deep structure that may not generalize well individually but contributes to the overall accuracy when combined. + +4. **Aggregate Predictions**: + After all trees are grown, the final prediction is made based on the majority vote for classification tasks or averaging for regression tasks. + +### Python Implementation: +Here is a basic implementation of a Random Forest in Python using **scikit-learn**: + +```python +from sklearn.datasets import load_iris +from sklearn.ensemble import RandomForestClassifier +from sklearn.model_selection import train_test_split +from sklearn.metrics import accuracy_score + +# Load dataset +iris = load_iris() +X, y = iris.data, iris.target + +# Split dataset +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# Create Random Forest classifier +clf = RandomForestClassifier(n_estimators=100, random_state=42) + +# Train model +clf.fit(X_train, y_train) + +# Predict +y_pred = clf.predict(X_test) + +# Evaluate +accuracy = accuracy_score(y_test, y_pred) +print(f"Accuracy: {accuracy:.2f}") +``` diff --git a/docs/machine-learning/regression_algorithm.md b/docs/machine-learning/regression_algorithm.md new file mode 100644 index 000000000..ff17f3195 --- /dev/null +++ b/docs/machine-learning/regression_algorithm.md @@ -0,0 +1,177 @@ +--- +id: regression +title: "Regression Algorithm (Supervised learning)" +sidebar_label: Regression Algorithms +description: "In this post, we’ll explore the concept of regression in supervised learning, a fundamental approach used for predicting continuous outcomes based on input features." +tags: [machine learning, algorithms, supervised learning, regression] +--- + +### Definition: +**Regression** is a type of supervised learning algorithm used to predict continuous outcomes based on one or more input features. The model learns from labeled training data to establish a relationship between the input variables and the target variable. + + + +### Characteristics: +- **Continuous Output**: + Regression algorithms are used when the output variable is continuous, such as predicting prices, temperatures, or scores. + +- **Predictive Modeling**: + The primary goal is to create a model that can accurately predict numerical values for new, unseen data based on learned relationships. + +- **Evaluation Metrics**: + Regression models are evaluated using metrics such as Mean Squared Error (MSE), R-squared (R²), and Root Mean Squared Error (RMSE). + +### Types of Regression Algorithms: +1. **Linear Regression**: + A simple approach that models the relationship between one or more independent variables and a dependent variable by fitting a linear equation. + +2. **Polynomial Regression**: + Extends linear regression by fitting a polynomial equation to the data, allowing for more complex relationships. + +3. **Ridge and Lasso Regression**: + Regularization techniques that add penalties to the loss function to prevent overfitting. Ridge uses L2 regularization, while Lasso uses L1 regularization. + +4. **Support Vector Regression (SVR)**: + An extension of Support Vector Machines (SVM) that can be used for regression tasks by finding a hyperplane that best fits the data. + +5. **Decision Tree Regression**: + Uses decision trees to model relationships between features and target values by splitting data into subsets based on feature values. + +6. **Random Forest Regression**: + An ensemble method that combines multiple decision trees to improve prediction accuracy and control overfitting. + + + +### Steps Involved: +1. **Input the Data**: + The algorithm receives labeled training data consisting of features and corresponding target values. + +2. **Preprocess the Data**: + Data cleaning and preprocessing steps may include handling missing values, normalizing or scaling features, and encoding categorical variables. + +3. **Split the Dataset**: + The dataset is typically split into training and testing sets to evaluate model performance. + +4. **Select a Model**: + Choose an appropriate regression algorithm based on the problem type and data characteristics. + +5. **Train the Model**: + Fit the model to the training data using an optimization algorithm to minimize error. + +6. **Evaluate Model Performance**: + Use metrics such as MSE or R² score to assess how well the model performs on unseen data. + +7. **Make Predictions**: + Use the trained model to make predictions on new data points. + + + +### Problem Statement: +Given a labeled dataset with multiple features and corresponding continuous target values, the objective is to train a regression model that can accurately predict target values for new, unseen data based on learned patterns. + +### Key Concepts: +- **Training Set**: + The portion of the dataset used to train the model. + +- **Test Set**: + The portion of the dataset used to evaluate model performance after training. + +- **Overfitting and Underfitting**: + Overfitting occurs when a model learns noise in the training data rather than general patterns. Underfitting occurs when a model is too simple to capture underlying trends. + +- **Evaluation Metrics**: + Metrics used to assess model performance include MSE for regression tasks and R² score for measuring explained variance. + + + +### Split Criteria: +Regression algorithms typically split data based on minimizing prediction error or maximizing explained variance in predictions. + +### Time Complexity: +- **Training Complexity**: + Varies by algorithm; can range from linear time complexity for simple models like Linear Regression to polynomial time complexity for more complex models. + +- **Prediction Complexity**: +Also varies by algorithm; some algorithms allow for faster predictions after training (e.g., linear models). + +### Space Complexity: +- **Space Complexity**: +Depends on how much information about the training set needs to be stored (e.g., decision trees may require more space than linear models). + +### Example: +Consider a scenario where we want to predict house prices based on features such as size, number of bedrooms, and location. + +**Dataset Example:** + +| Size (sq ft) | Bedrooms | Price ($) | +|---------------|----------|-----------| +| 1500 | 3 | 300000 | +| 2000 | 4 | 400000 | +| 1200 | 2 | 250000 | +| 1800 | 3 | 350000 | + +Step-by-Step Execution: + +1. **Input Data**: + The model receives training data with features (size and bedrooms) and labels (price). + +2. **Preprocess Data**: + Handle any missing values or outliers if necessary. + +3. **Split Dataset**: + Divide the dataset into training and testing sets (e.g., 80% train, 20% test). + +4. **Select Model**: + Choose an appropriate regression algorithm like Linear Regression. + +5. **Train Model**: + Fit the model using the training set. + +6. **Evaluate Performance**: + Use metrics like R² score or mean squared error on the test set. + +7. **Make Predictions**: + Predict prices for new houses based on their features. + + + +### Python Implementation: +Here’s a basic implementation of Linear Regression using **scikit-learn**: + +```python +from sklearn.model_selection import train_test_split +from sklearn.linear_model import LinearRegression +from sklearn.metrics import mean_squared_error + +# Sample dataset +data = { + 'Size': [1500, 2000, 1200, 1800], + 'Bedrooms': [3, 4, 2, 3], + 'Price': [300000, 400000, 250000, 350000] +} + +# Convert to DataFrame +import pandas as pd +df = pd.DataFrame(data) + +# Features and target variable +X = df[['Size', 'Bedrooms']] +y = df['Price'] + +# Split dataset +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# Create Linear Regression model +model = LinearRegression() + +# Train model +model.fit(X_train, y_train) + +# Predict +y_pred = model.predict(X_test) + +# Evaluate +mse = mean_squared_error(y_test, y_pred) +print(f"Mean Squared Error: {mse:.2f}") +``` + diff --git a/docs/machine-learning/supervised_learning_algo.md b/docs/machine-learning/supervised_learning_algo.md new file mode 100644 index 000000000..db31ce1ac --- /dev/null +++ b/docs/machine-learning/supervised_learning_algo.md @@ -0,0 +1,164 @@ +--- +id: supervised-learning-algorithm +title: Supervised Learning Algorithm +sidebar_label: Supervised Learning +description: "In this post, we’ll explore the concept of supervised learning, a fundamental approach in machine learning where models are trained using labeled data." +tags: [machine learning, algorithms, supervised learning] +--- + +### Definition: +**Supervised Learning** is a type of machine learning where an algorithm learns from labeled training data to make predictions or classifications on unseen data. The model is trained using input-output pairs, allowing it to learn the relationship between features and target labels. + + + +### Characteristics: +- **Labeled Data**: + Supervised learning requires a dataset that includes both input features and corresponding output labels. + +- **Predictive Modeling**: + The primary goal is to build a model that can accurately predict the output for new, unseen data based on the learned relationships. + +- **Feedback Mechanism**: + The model is evaluated based on its performance on a validation set, allowing for adjustments and improvements. + +### Types of Supervised Learning Algorithms: +1. **Regression Algorithms**: + Used when the output variable is continuous. Examples include Linear Regression and Polynomial Regression. + +2. **Classification Algorithms**: + Used when the output variable is categorical. Examples include Logistic Regression, Decision Trees, and Support Vector Machines (SVM). + + + +### Steps Involved: +1. **Input the Data**: + The algorithm receives labeled training data consisting of features and corresponding target labels. + +2. **Preprocess the Data**: + Data cleaning and preprocessing steps may include handling missing values, normalizing or scaling features, and encoding categorical variables. + +3. **Split the Dataset**: + The dataset is typically split into training and testing sets to evaluate model performance. + +4. **Select a Model**: + Choose an appropriate supervised learning algorithm based on the problem type (regression or classification). + +5. **Train the Model**: + Fit the model to the training data using an optimization algorithm to minimize error. + +6. **Evaluate Model Performance**: + Use metrics such as accuracy, precision, recall, or mean squared error (MSE) to assess how well the model performs on unseen data. + +7. **Make Predictions**: + Use the trained model to make predictions on new data points. + + + +### Problem Statement: +Given a labeled dataset with multiple features and corresponding target labels, the objective is to train a supervised learning model that can accurately predict target labels for new, unseen data based on learned patterns. + +### Key Concepts: +- **Training Set**: + The portion of the dataset used to train the model. + +- **Test Set**: + The portion of the dataset used to evaluate model performance after training. + +- **Overfitting and Underfitting**: + Overfitting occurs when a model learns noise in the training data rather than general patterns. Underfitting occurs when a model is too simple to capture underlying trends. + +- **Evaluation Metrics**: + Metrics used to assess model performance include accuracy for classification tasks and mean squared error for regression tasks. + + + +### Split Criteria: +Supervised learning algorithms typically split data based on minimizing prediction error or maximizing classification accuracy. + +### Time Complexity: +- **Training Complexity**: + Varies by algorithm; can range from linear to polynomial time complexity depending on data size and algorithm choice. + +- **Prediction Complexity**: + Also varies by algorithm; some algorithms allow for faster predictions after training (e.g., k-NN can be slower during prediction). + +### Space Complexity: +- **Space Complexity**: + Depends on how much information about the training set needs to be stored (e.g., decision trees may require more space than linear models). + +### Example: +Consider a scenario where we want to predict house prices based on features such as size, number of bedrooms, and location. + +**Dataset Example:** + +| Size (sq ft) | Bedrooms | Price ($) | +|---------------|----------|-----------| +| 1500 | 3 | 300000 | +| 2000 | 4 | 400000 | +| 1200 | 2 | 250000 | +| 1800 | 3 | 350000 | + +Step-by-Step Execution: + +1. **Input Data**: + The model receives training data with features (size and bedrooms) and labels (price). + +2. **Preprocess Data**: + Handle any missing values or outliers if necessary. + +3. **Split Dataset**: + Divide the dataset into training and testing sets (e.g., 80% train, 20% test). + +4. **Select Model**: + Choose an appropriate regression algorithm like Linear Regression. + +5. **Train Model**: + Fit the model using the training set. + +6. **Evaluate Performance**: + Use metrics like R² score or mean squared error on the test set. + +7. **Make Predictions**: + Predict prices for new houses based on their features. + + + +### Python Implementation: +Here’s a basic implementation of a supervised learning algorithm using **scikit-learn**, specifically Linear Regression: + +```python +from sklearn.model_selection import train_test_split +from sklearn.linear_model import LinearRegression +from sklearn.metrics import mean_squared_error + +# Sample dataset +data = { + 'Size': [1500, 2000, 1200, 1800], + 'Bedrooms': [3, 4, 2, 3], + 'Price': [300000, 400000, 250000, 350000] +} + +# Convert to DataFrame +import pandas as pd +df = pd.DataFrame(data) + +# Features and target variable +X = df[['Size', 'Bedrooms']] +y = df['Price'] + +# Split dataset +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# Create Linear Regression model +model = LinearRegression() + +# Train model +model.fit(X_train, y_train) + +# Predict +y_pred = model.predict(X_test) + +# Evaluate +mse = mean_squared_error(y_test, y_pred) +print(f"Mean Squared Error: {mse:.2f}") +``` diff --git a/docs/machine-learning/support-vector-machine.md b/docs/machine-learning/support-vector-machine.md new file mode 100644 index 000000000..f06f6c750 --- /dev/null +++ b/docs/machine-learning/support-vector-machine.md @@ -0,0 +1,126 @@ +--- + +id: support-vector-machine +title: Support Vector Machine (SVM) Algorithm +sidebar_label: Support Vector Machine +description: "SVM is a powerful machine learning model known for its effectiveness in classification tasks and its ability to handle high-dimensional data." +tags: [machine learning, algorithms, SVM, classification, regression] + +--- + +### Definition: +The **Support Vector Machine (SVM)** is a supervised machine learning algorithm commonly used for **classification** and sometimes for **regression**. It works by finding the optimal hyperplane that separates different classes in the feature space, ensuring that the margin between the nearest points (support vectors) of each class is maximized. + +### Characteristics: +- **Margin Maximization**: + SVM aims to maximize the distance between the hyperplane and the nearest data points from each class (support vectors). This helps in achieving better generalization. + +- **Kernel Trick**: + SVM uses kernel functions to project data into higher dimensions where a linear separation between classes may be easier to achieve. Common kernels include linear, polynomial, and radial basis function (RBF). + +- **Effective in High-Dimensional Spaces**: + SVM is particularly effective in cases where the number of dimensions exceeds the number of samples, making it suitable for complex datasets. + +### Types of SVM: +1. **Binary SVM**: + The most common type, where the algorithm separates data into two distinct classes. + +2. **Multiclass SVM**: + By using strategies like one-vs-one or one-vs-all, SVM can handle multiple classes. + +3. **Support Vector Regression (SVR)**: + A version of SVM that handles regression tasks by finding a margin of tolerance (epsilon) and minimizing the prediction error outside of this margin. + +### Steps Involved: +1. **Select the Kernel**: + Choose a kernel function (e.g., linear, RBF) that can help separate the data points in the feature space. + +2. **Maximize the Margin**: + SVM computes the hyperplane that maximizes the margin between the closest data points of each class (support vectors). + +3. **Handle Non-Linearly Separable Data**: + If data is not linearly separable, SVM applies the **kernel trick** to project the data into higher-dimensional space where it becomes separable. + +4. **Regularization**: + Introduce a regularization parameter (C) to control the trade-off between maximizing the margin and allowing some misclassifications (soft margin). + +### Problem Statement: +Given a dataset with features and target labels, the objective of SVM is to find a hyperplane that best separates the different classes in the feature space, while maximizing the margin and minimizing classification error. + +### Key Concepts: +- **Hyperplane**: + A decision boundary that separates different classes in the feature space. + +- **Support Vectors**: + The data points that are closest to the hyperplane, which directly influence its position and orientation. + +- **Margin**: + The distance between the hyperplane and the nearest data points from each class. A wider margin leads to better generalization. + +### Kernel Functions: +- **Linear Kernel**: + Used when the data is linearly separable. The decision boundary is a straight line (or hyperplane). + + $$K(x, y) = x \cdot y$$ + +- **Polynomial Kernel**: + Creates a non-linear decision boundary by raising the dot product of input vectors to a specified degree. + + $$K(x, y) = (x \cdot y + c)^d$$ + +- **Radial Basis Function (RBF)**: + A popular kernel for non-linearly separable data, mapping data points into higher-dimensional space. + + $$K(x, y) = \exp(-\gamma ||x - y||^2)$$ + +### Time Complexity: +- **Training Time Complexity: $O(n^2)$ to $O(n^3)$** + Training an SVM can be computationally expensive, especially for large datasets, due to the quadratic or cubic time complexity with respect to the number of samples (n). + +### Space Complexity: +- **Space Complexity: $O(n)$** + The space complexity depends on the number of support vectors, which are usually a subset of the data points. + +### Example: +Consider a dataset of people’s heights and weights to predict whether they are athletes or not: + +- Dataset: + ``` + | Height (cm) | Weight (kg) | Athlete | + |-------------|-------------|---------| + | 170 | 70 | Yes | + | 160 | 60 | No | + | 180 | 85 | Yes | + | 155 | 55 | No | + ``` + +Step-by-Step Execution: + +1. **Choose the kernel**: + Select the appropriate kernel (e.g., linear or RBF) based on the data's distribution. + +2. **Maximize the margin**: + SVM computes the hyperplane and support vectors, ensuring the widest possible margin between the classes (Athlete/Not Athlete). + +### Python Implementation: +Here is a basic implementation of SVM in Python using **scikit-learn**: + +```python +from sklearn import datasets +from sklearn.svm import SVC +import matplotlib.pyplot as plt + +# Load dataset +iris = datasets.load_iris() +X, y = iris.data[:, :2], iris.target # Using only two features for simplicity + +# Create SVM classifier +clf = SVC(kernel='linear') + +# Train model +clf.fit(X, y) + +``` + +### Summary: +The **Support Vector Machine (SVM)** is a robust and versatile algorithm, particularly well-suited for classification tasks with high-dimensional data. Its ability to maximize margins and its use of kernel functions make it a powerful tool, though it can be computationally intensive for large datasets. Careful selection of kernels and regularization parameters is key to achieving good results. diff --git a/docs/machine-learning/t-SNE_Dimensionality_Reduction.md b/docs/machine-learning/t-SNE_Dimensionality_Reduction.md new file mode 100644 index 000000000..dcfa28858 --- /dev/null +++ b/docs/machine-learning/t-SNE_Dimensionality_Reduction.md @@ -0,0 +1,154 @@ +--- + +id: tsne-dimensionality-reduction +title: t-SNE Dimensionality Reduction Algorithm +sidebar_label: t-SNE +description: "This post explores t-SNE (t-distributed Stochastic Neighbor Embedding), a popular dimensionality reduction technique used to visualize high-dimensional data in a low-dimensional space." +tags: [dimensionality reduction, data visualization, machine learning, tsne, high-dimensional data] + +--- + +### Definition: +**t-SNE (t-distributed Stochastic Neighbor Embedding)** is a non-linear dimensionality reduction technique commonly used for the visualization of high-dimensional datasets. Unlike linear techniques like PCA, t-SNE excels at preserving the local structure of data, making it highly effective for visualizing clusters or groups in lower dimensions (typically 2D or 3D). + +### Characteristics: +- **Non-linear Mapping**: + t-SNE captures non-linear relationships in high-dimensional data, making it suitable for datasets where linear techniques like PCA fall short. + +- **Emphasis on Local Structure**: + t-SNE preserves the local structure of the data by ensuring that similar data points in the high-dimensional space remain close together in the lower-dimensional representation. + +- **Perplexity as a Key Parameter**: + t-SNE uses a parameter called *perplexity*, which influences the balance between local and global aspects of the data. Higher perplexity values tend to focus on global structure, while lower values emphasize local details. + +### Components of t-SNE: +1. **High-Dimensional Pairwise Similarities**: + t-SNE starts by calculating the pairwise similarities between all points in the high-dimensional space using a probability distribution (Gaussian distribution). + +2. **Low-Dimensional Mapping**: + The algorithm then aims to find a low-dimensional representation of the data by minimizing the difference (KL divergence) between the high-dimensional and low-dimensional distributions. In the lower-dimensional space, it uses a *t-distribution* to handle the long tails, ensuring that distant points don’t get overly compressed. + +3. **Gradient Descent Optimization**: + The optimization process uses gradient descent to iteratively adjust the low-dimensional embedding, ensuring that similar points in the high-dimensional space remain close together while dissimilar points are further apart. + +### Steps Involved: +1. **High-Dimensional Input Data**: + The algorithm accepts data in high-dimensional space (e.g., a dataset with hundreds of features). + +2. **Pairwise Similarity Calculation**: + It computes the pairwise similarities between all points in the high-dimensional space using a Gaussian distribution. + +3. **Low-Dimensional Embedding Initialization**: + The low-dimensional space (usually 2D or 3D) is initialized, and points are randomly positioned. + +4. **KL Divergence Minimization**: + t-SNE minimizes the Kullback-Leibler (KL) divergence between the distributions of pairwise similarities in the high- and low-dimensional spaces. + +5. **Iteration & Optimization**: + Using gradient descent, the algorithm iteratively updates the positions of points in the low-dimensional space to better represent the structure of the high-dimensional data. + +6. **Final Low-Dimensional Representation**: + The final output is a low-dimensional mapping that preserves the local relationships of the data, which can be used for visualization. + +### Key Concepts: +- **Perplexity**: + Perplexity controls the balance between the attention t-SNE gives to local versus global structure. It's a measure of how many neighbors each point should consider when calculating pairwise similarities. + +- **KL Divergence**: + A measure of the difference between two probability distributions. In t-SNE, KL divergence is used to minimize the difference between the high-dimensional and low-dimensional representations of the data. + +- **Learning Rate**: + The learning rate controls the step size during gradient descent optimization. Too high a value may result in poor convergence, while too low a value may cause slow optimization. + +- **Early Exaggeration**: + In the early stages of the t-SNE optimization, distances between points are exaggerated to help the algorithm find a meaningful structure before settling into the final low-dimensional representation. + +### t-SNE Algorithm Architecture: +1. **Input Layer**: + The input data consists of high-dimensional points (e.g., each point representing an observation with hundreds of features). + +2. **Pairwise Similarity Layer**: + For each point, t-SNE calculates pairwise similarities to other points using a Gaussian distribution in the high-dimensional space. + +3. **Low-Dimensional Embedding Layer**: + Points are placed randomly in the low-dimensional space (usually 2D or 3D), and the layout is iteratively adjusted using gradient descent. + +4. **Optimization Layer**: + The positions of points in the low-dimensional space are updated to minimize the KL divergence between the high-dimensional and low-dimensional similarities. + +5. **Output Layer**: + The final low-dimensional representation, suitable for visualization, is produced, preserving the local neighborhood structure of the original data. + +### Advantages of t-SNE: +- **Visualization Power**: + t-SNE is exceptionally good at visualizing high-dimensional data, especially when the data exhibits clusters or subgroups. + +- **Captures Non-Linear Structures**: + Unlike linear methods like PCA, t-SNE captures complex, non-linear structures, which is essential for many real-world datasets. + +- **User-Friendly Parameters**: + While t-SNE has a few key parameters like perplexity and learning rate, they are relatively easy to tune and often produce meaningful results across a wide range of values. + +### Limitations of t-SNE: +- **Computational Complexity**: + t-SNE can be computationally expensive for very large datasets due to the pairwise similarity calculations and iterative optimization. + +- **No Preserved Global Structure**: + While t-SNE does a great job preserving local structure, it often sacrifices global relationships in the data, making it less ideal for tasks where global geometry is important. + +- **Sensitive to Parameter Tuning**: + The choice of perplexity and learning rate can significantly impact the resulting embedding, requiring careful experimentation. + +### Use Cases: +1. **Data Visualization**: + t-SNE is widely used for visualizing high-dimensional datasets in machine learning, helping to identify clusters or patterns in the data. + +2. **Exploratory Data Analysis**: + t-SNE is effective for uncovering hidden structures, making it a valuable tool for exploratory data analysis before more formal modeling. + +3. **Dimensionality Reduction for Feature Engineering**: + t-SNE can be used as a pre-processing step to reduce the number of features in a dataset while preserving important relationships. + +4. **Biological Data**: + t-SNE is commonly applied to gene expression and single-cell RNA sequencing data to explore the relationships between different cell types. + +### Example of t-SNE in Python: +```python +import matplotlib.pyplot as plt +from sklearn.manifold import TSNE +from sklearn.datasets import load_digits +from sklearn.preprocessing import StandardScaler + +# Load dataset +digits = load_digits() +X = digits.data +y = digits.target + +# Standardize the features +X_scaled = StandardScaler().fit_transform(X) + +# Perform t-SNE +tsne = TSNE(n_components=2, perplexity=30, random_state=42) +X_tsne = tsne.fit_transform(X_scaled) + +# Plot the result +plt.figure(figsize=(8, 6)) +plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap='jet', s=30) +plt.colorbar() +plt.title("t-SNE Visualization of Digits Dataset") +plt.show() +``` + +### Time and Space Complexity: +- **Time Complexity**: + The time complexity of t-SNE is approximately $O(n^2)$, where $n$ is the number of data points. This makes it slow for large datasets. + +- **Space Complexity**: + The space complexity of t-SNE is also $O(n^2)$ due to the storage requirements for pairwise similarities. + +### Summary & Applications: +- **t-SNE** is a powerful tool for visualizing high-dimensional data in a lower-dimensional space, making it widely used in tasks involving clustering, pattern recognition, and exploratory data analysis. It is particularly popular in fields like genomics, image processing, and text mining. + +- **Applications**: + t-SNE is used in various industries for data visualization, including finance, healthcare, e-commerce, and bioinformatics, enabling professionals to gain insights into complex datasets. + diff --git a/docs/machine-learning/unsupervised_learning_algo.md b/docs/machine-learning/unsupervised_learning_algo.md new file mode 100644 index 000000000..6da62152c --- /dev/null +++ b/docs/machine-learning/unsupervised_learning_algo.md @@ -0,0 +1,163 @@ +--- +id: unsupervised-learning-algorithms +title: Unsupervised Learning Algorithms +sidebar_label: Unsupervised Learning +description: "In this post, we’ll explore the concept of unsupervised learning, a fundamental approach in machine learning where models are trained using unlabeled data." +tags: [machine learning, algorithms, unsupervised learning] +--- + +### Definition: +**Unsupervised Learning** is a type of machine learning where an algorithm learns from unlabeled data to identify patterns, groupings, or structures within the data. Unlike supervised learning, there are no predefined labels or outcomes to guide the learning process. + + + +### Characteristics: +- **Unlabeled Data**: + Unsupervised learning requires a dataset that does not include output labels; the algorithm must discover the inherent structure of the data on its own. + +- **Pattern Recognition**: + The primary goal is to uncover hidden patterns or groupings in the data without prior knowledge of what those patterns may be. + +- **Exploratory Analysis**: + Often used for exploratory data analysis to understand the underlying distribution and relationships in data. + +### Types of Unsupervised Learning Algorithms: + +1. **Clustering Algorithms**: + Used to group similar data points together. Examples include: + - **K-Means Clustering**: Partitions data into K clusters based on feature similarity. + - **Hierarchical Clustering**: Builds a hierarchy of clusters using either agglomerative or divisive approaches. + - **DBSCAN (Density-Based Spatial Clustering of Applications with Noise)**: Groups points that are closely packed together while marking outliers. + +2. **Dimensionality Reduction Algorithms**: + Used to reduce the number of features in a dataset while preserving its essential structure. Examples include: + - **Principal Component Analysis (PCA)**: Transforms data into a lower-dimensional space while retaining variance. + - **t-SNE (t-distributed Stochastic Neighbor Embedding)**: A technique for visualizing high-dimensional data in two or three dimensions. + +3. **Association Rule Learning**: + A method for discovering interesting relations between variables in large databases. An example is: + - **Apriori Algorithm**: Used for mining frequent itemsets and relevant association rules. + + + +### Steps Involved: +1. **Input the Data**: + The algorithm receives unlabeled training data consisting of features without corresponding target labels. + +2. **Preprocess the Data**: + Data cleaning and preprocessing steps may include handling missing values, normalizing or scaling features, and encoding categorical variables. + +3. **Select an Algorithm**: + Choose an appropriate unsupervised learning algorithm based on the problem type (clustering, dimensionality reduction, etc.). + +4. **Fit the Model**: + Apply the chosen algorithm to the dataset to identify patterns or groupings. + +5. **Evaluate Results**: + Use metrics such as silhouette score for clustering or explained variance for dimensionality reduction to assess how well the model performs. + +6. **Interpret Findings**: + Analyze the results to draw insights or make decisions based on identified patterns. + + + +### Problem Statement: +Given an unlabeled dataset with multiple features, the objective is to identify patterns, group similar observations, or reduce dimensionality to facilitate further analysis. + +### Key Concepts: +- **Clustering**: + The process of grouping a set of objects in such a way that objects in the same group (or cluster) are more similar than those in other groups. + +- **Dimensionality Reduction**: + Techniques used to reduce the number of input variables in a dataset while preserving important information. + +- **Association Rules**: + Rules that describe how items are associated with each other in transactional datasets. + + + +### Split Criteria: +Unsupervised learning algorithms typically split data based on inherent structures or distances between points rather than minimizing prediction error. + +### Time Complexity: +- **Training Complexity**: + Varies by algorithm; can range from linear time complexity for simple clustering methods to polynomial time complexity for more complex algorithms. + +- **Prediction Complexity**: +Also varies by algorithm; some algorithms allow for faster predictions after training (e.g., K-Means can be efficient during prediction). + +### Space Complexity: +- **Space Complexity**: +Depends on how much information about the training set needs to be stored (e.g., clustering algorithms may require more space than dimensionality reduction techniques). + +### Example: +Consider a scenario where we want to segment customers based on purchasing behavior without labeled outcomes. + +**Dataset Example:** + +| Customer ID | Age | Annual Income | Spending Score | +|-------------|-----|---------------|----------------| +| 1 | 25 | 50K | 39 | +| 2 | 30 | 60K | 81 | +| 3 | 22 | 45K | 6 | +| 4 | 35 | 70K | 77 | + +Step-by-Step Execution: + +1. **Input Data**: + The model receives training data with features (age, income, spending score). + +2. **Preprocess Data**: + Handle any missing values and scale features if necessary. + +3. **Select Algorithm**: + Choose K-Means for clustering customers based on their spending behavior. + +4. **Fit Model**: + Apply K-Means to group customers into clusters based on their features. + +5. **Evaluate Performance**: + Use silhouette score to evaluate how well-defined the clusters are. + +6. **Interpret Findings**: + Analyze customer segments to tailor marketing strategies accordingly. + + + +### Python Implementation: +Here’s a basic implementation of K-Means clustering using **scikit-learn**: + +```python +from sklearn.cluster import KMeans +import pandas as pd +import matplotlib.pyplot as plt + +# Sample dataset +data = { + 'Age': [25, 30, 22, 35], + 'Annual Income': [50000, 60000, 45000, 70000], + 'Spending Score': [39, 81, 6, 77] +} + +# Convert to DataFrame +df = pd.DataFrame(data) + +# Create KMeans model +kmeans = KMeans(n_clusters=2, random_state=42) + +# Fit model +kmeans.fit(df) + +# Predict cluster labels +labels = kmeans.predict(df) + +# Visualize results +plt.scatter(df['Annual Income'], df['Spending Score'], c=labels) +plt.scatter(kmeans.cluster_centers_[:, 1], kmeans.cluster_centers_[:, 2], s=300, c='red', label='Centroids') +plt.title('Customer Segmentation using K-Means') +plt.xlabel('Annual Income') +plt.ylabel('Spending Score') +plt.legend() +plt.show() +``` + diff --git a/docs/programming-fundamentals/Arrays.md b/docs/programming-fundamentals/Arrays.md new file mode 100644 index 000000000..8e4f08e32 --- /dev/null +++ b/docs/programming-fundamentals/Arrays.md @@ -0,0 +1,147 @@ +--- +id: Arrays +title: Introduction to Arrays fundamentals +sidebar_label: Arrays +sidebar_position: 1 +description: "Information About Arrays in progamming" +tags: [arrays,fundamentals] +--- + + +# Arrays in C + +## What is an Array? +An array is a collection of elements of the same type, stored in contiguous memory locations. It allows you to store multiple values in a single variable, making it easier to manage and access data efficiently. + +## Characteristics of Arrays +- **Homogeneous**: All elements in an array must be of the same data type. +- **Fixed Size**: The size of an array is defined at the time of declaration and cannot be changed during runtime. +- **Contiguous Memory**: The elements of an array are stored in consecutive memory locations. + +## Declaration of Arrays +To declare an array in C, you specify the data type followed by the array name and size in square brackets. + +### Syntax: +```c +data_type array_name[array_size]; +``` +### Example: +```C +int numbers[5]; // Declaration of an integer array of size 5 +``` + +## Initialization of Arrays +You can initialize an array at the time of declaration using curly braces. + +### Syntax: +```C +data_type array_name[array_size] = {value1, value2, ..., valueN}; +``` + +### Example: +```C +int numbers[5] = {1, 2, 3, 4, 5}; // Initialization with values +``` +If the size is omitted, the compiler counts the number of initializers: + +```C +int numbers[] = {1, 2, 3, 4, 5}; // Compiler determines the size (5 in this case) +``` + +## Accessing Array Elements +Array elements can be accessed using the index, which starts from 0. + +### Syntax: +```C +array_name[index]; +``` + +### Example: +```C +int firstElement = numbers[0]; // Accessing the first element (1) +``` + +## Modifying Array Elements +You can modify an element of the array using its index. + +### Example: +```C +numbers[0] = 10; // Changing the first element from 1 to 10 +``` + +## Multidimensional Arrays +C also supports multidimensional arrays, such as two-dimensional arrays (like matrices). + +### Declaration: +```C +data_type array_name[row_size][column_size]; +``` + +#### Example: +```C +int matrix[3][3]; // Declaration of a 3x3 integer matrix +``` + +### Initialization: +```C +int matrix[3][3] = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} +}; // Initialization of a 3x3 matrix +``` + +### Accessing Elements: +```C +int element = matrix[1][2]; // Accessing the element in the second row and third column (6) +``` + +## Common Operations on Arrays +1. Traversing an Array +You can iterate through an array using a loop to access or modify each element. + +``` +for (int i = 0; i < 5; i++) { + printf("%d ", numbers[i]); // Prints each element +} +``` + +2. Searching an Array +You can search for an element using linear or binary search. + +Linear Search Example: +```C +int search(int arr[], int size, int key) { + for (int i = 0; i < size; i++) { + if (arr[i] == key) { + return i; // Return the index if found + } + } + return -1; // Return -1 if not found +} +``` + +3. Sorting an Array +You can sort an array using various algorithms like bubble sort, selection sort, or quicksort. + +Bubble Sort Example: +```C +void bubbleSort(int arr[], int size) { + for (int i = 0; i < size - 1; i++) { + for (int j = 0; j < size - i - 1; j++) { + if (arr[j] > arr[j + 1]) { + // Swap arr[j] and arr[j+1] + int temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } +} +``` + +## Summary +- An array is a collection of elements of the same type stored in contiguous memory locations. +- Arrays can be one-dimensional or multi-dimensional. +- Elements can be accessed and modified using their index. +- Common operations on arrays include traversing, searching, and sorting. diff --git a/docs/programming-fundamentals/Conditionals.md b/docs/programming-fundamentals/Conditionals.md new file mode 100644 index 000000000..00be5153d --- /dev/null +++ b/docs/programming-fundamentals/Conditionals.md @@ -0,0 +1,146 @@ +--- +id: Conditionals +title: Introduction to conditinols fundamentals +sidebar_label: Conditionals +sidebar_position: 2 +description: "Information About conditionals in progamming" +tags: [conditionals,fundamentals] +--- + + +# Conditionals in C + +## What are Conditionals? +Conditionals in C allow you to execute different parts of your code based on certain conditions. They help control the flow of the program by making decisions. + +## Types of Conditional Statements + +### 1. `if` Statement +The `if` statement executes a block of code if a specified condition is true. + +#### Syntax: +```c +if (condition) { + // code to be executed if condition is true +} +``` + +### Example: +```C +int num = 10; +if (num > 0) { + printf("Number is positive.\n"); +} +``` + +### 2. if-else Statement +The if-else statement executes one block of code if the condition is true and another block if the condition is false. + +### Syntax: +```C +if (condition) { + // code to be executed if condition is true +} else { + // code to be executed if condition is false +} +``` + +### Example: +```C +int num = -5; +if (num > 0) { + printf("Number is positive.\n"); +} else { + printf("Number is non-positive.\n"); +} +``` + +### 3. else if Statement +You can chain multiple conditions using else if to check multiple conditions in sequence. + +### Syntax: +```C +if (condition1) { + // code for condition1 +} else if (condition2) { + // code for condition2 +} else { + // code if none of the above conditions are true +} +``` + +### Example: +```C +int num = 0; +if (num > 0) { + printf("Number is positive.\n"); +} else if (num < 0) { + printf("Number is negative.\n"); +} else { + printf("Number is zero.\n"); +} +``` + +### 4. switch Statement +The switch statement is used to select one of many blocks of code to be executed. It is often used as a more readable alternative to a series of if-else statements. + +### Syntax: +```C +switch (expression) { + case constant1: + // code to be executed if expression equals constant1 + break; + case constant2: + // code to be executed if expression equals constant2 + break; + default: + // code to be executed if expression doesn't match any constant +} +``` + +### Example: +```C +int day = 3; +switch (day) { + case 1: + printf("Monday\n"); + break; + case 2: + printf("Tuesday\n"); + break; + case 3: + printf("Wednesday\n"); + break; + default: + printf("Not a valid day\n"); +} +``` + +## Conditional Operators +C also provides several operators that can be used to form conditions. + +### 1. Relational Operators +- == : Equal to +- != : Not equal to +- > : Greater than +- < : Less than +- >= : Greater than or equal to +- <= : Less than or equal to + +### 2. Logical Operators +- && : Logical AND +- || : Logical OR +- ! : Logical NOT + +### Example: +```C +int a = 5, b = 10; +if (a < b && a > 0) { + printf("a is positive and less than b.\n"); +} +``` + +Summary +- Conditionals allow you to control the flow of your program based on certain conditions. +- The primary conditional statements are if, if-else, else if, and switch. +- Relational and logical operators are used to create complex conditions. diff --git a/docs/programming-fundamentals/Data_Structures.md b/docs/programming-fundamentals/Data_Structures.md new file mode 100644 index 000000000..953b8b58a --- /dev/null +++ b/docs/programming-fundamentals/Data_Structures.md @@ -0,0 +1,155 @@ +--- +id: Data Structures +title: Introduction to Data Structures fundamentals +sidebar_label: Data Structures +sidebar_position: 3 +description: "Information About Data structures in progamming" +tags: [Data structures,fundamentals] +--- + + +# Data Structures in C + +## What are Data Structures? +Data structures are specialized formats for organizing, processing, and storing data. They provide a way to manage large amounts of data efficiently for various operations such as searching, inserting, updating, and deleting. + +## Types of Data Structures + +### 1. Primitive Data Structures +Primitive data structures are the basic building blocks of data handling in C. They include: + +- **Integers (`int`)**: Used to store whole numbers. +- **Floats (`float`)**: Used to store single-precision floating-point numbers. +- **Doubles (`double`)**: Used to store double-precision floating-point numbers. +- **Characters (`char`)**: Used to store single characters. +- **Boolean (`_Bool`)**: Used to store true/false values. + +### 2. Non-Primitive Data Structures +Non-primitive data structures are more complex structures built from primitive data types. They include: + +#### a. Arrays +An array is a collection of elements of the same type, stored in contiguous memory locations. + +- **Declaration**: + ```c + int arr[10]; // Array of integers + ``` + +- **Initialization**: + ```c + int arr[5] = {1, 2, 3, 4, 5}; + ``` + +- **Accessing Elements**: + ```c + int first = arr[0]; // Accessing the first element + ``` + +#### b. Structures +Structures allow you to group different data types under a single name. + +- **Declaration**: + ```c + struct Person { + char name[50]; + int age; + }; + ``` + +- **Initialization**: + ```c + struct Person person1 = {"Alice", 30}; + ``` + +- **Accessing Members**: + ```c + printf("%s is %d years old.", person1.name, person1.age); + ``` + +#### c. Unions +Unions allow you to store different data types in the same memory location. Only one member can hold a value at any given time. + +- **Declaration**: + ```c + union Data { + int intVal; + float floatVal; + char charVal; + }; + ``` + +- **Initialization**: + ```c + union Data data; + data.intVal = 5; // Only intVal holds a value at this moment + ``` + +#### d. Enumerations +An enumeration is a user-defined data type consisting of a set of named integer constants. + +- **Declaration**: + ```c + enum Day { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; + ``` + +- **Using Enumerations**: + ```c + enum Day today = Friday; + ``` + +### 3. Abstract Data Types (ADTs) +ADTs are data structures defined by their behavior (operations) rather than their implementation. + +#### a. Linked Lists +A linked list is a collection of nodes where each node contains data and a pointer to the next node. + +- **Node Structure**: + ```c + struct Node { + int data; + struct Node* next; + }; + ``` + +- **Example of Inserting a Node**: + ```c + void insert(struct Node** head, int newData) { + struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); + newNode->data = newData; + newNode->next = (*head); + (*head) = newNode; + } + ``` + +#### b. Stacks +A stack is a linear data structure that follows the Last In First Out (LIFO) principle. + +- **Operations**: + - **Push**: Add an element to the top. + - **Pop**: Remove an element from the top. + - **Peek**: Get the top element without removing it. + +#### c. Queues +A queue is a linear data structure that follows the First In First Out (FIFO) principle. + +- **Operations**: + - **Enqueue**: Add an element to the rear. + - **Dequeue**: Remove an element from the front. + +### 4. Trees +A tree is a hierarchical data structure consisting of nodes. The top node is called the root, and each node can have child nodes. + +- **Binary Tree**: Each node has at most two children. +- **Binary Search Tree (BST)**: A binary tree where the left child is less than the parent and the right child is greater. + +### 5. Graphs +A graph is a collection of nodes (vertices) connected by edges. Graphs can be directed or undirected. + +- **Representation**: + - **Adjacency Matrix**: A 2D array to represent the graph. + - **Adjacency List**: An array of lists to represent the graph. + +## Summary +- Data structures are crucial for organizing and managing data effectively. +- C provides both primitive and non-primitive data structures. +- Understanding various data structures helps optimize algorithms and enhances programming skills. diff --git a/docs/programming-fundamentals/Loops.md b/docs/programming-fundamentals/Loops.md new file mode 100644 index 000000000..1bc300d69 --- /dev/null +++ b/docs/programming-fundamentals/Loops.md @@ -0,0 +1,117 @@ +--- +id: Loops +title: Introduction to loops fundamentals +sidebar_label: Loops +sidebar_position: 5 +description: "Information About loops in progamming" +tags: [loops,fundamentals] +--- + +# Loops in C + +## What are Loops? +Loops in C are used to execute a block of code repeatedly until a specified condition is met. They are essential for performing repetitive tasks efficiently. + +## Types of Loops + +### 1. `for` Loop +The `for` loop is used when the number of iterations is known beforehand. It consists of three parts: initialization, condition, and increment/decrement. + +#### Syntax: +```c +for (initialization; condition; increment/decrement) { + // code to be executed +} +``` + +#### Example: +```C +for (int i = 0; i < 5; i++) { + printf("Iteration: %d\n", i); +} +``` + +### 2. while Loop +The while loop is used when the number of iterations is not known, and the loop continues until the condition is false. + +#### Syntax: +```C +while (condition) { + // code to be executed +} +``` + +#### Example: +```C +int i = 0; +while (i < 5) { + printf("Iteration: %d\n", i); + i++; +} +``` + +### 3. do-while Loop +The do-while loop is similar to the while loop, but it guarantees that the loop body will be executed at least once, as the condition is checked after the execution of the loop body. + +#### Syntax: +```C +do { + // code to be executed +} while (condition); +``` + +#### Example: +```C +int i = 0; +do { + printf("Iteration: %d\n", i); + i++; +} while (i < 5); +``` + +## Loop Control Statements +Loop control statements allow you to control the flow of the loop. + +### 1. break +The break statement is used to exit a loop prematurely. + +#### Example: +```C +for (int i = 0; i < 10; i++) { + if (i == 5) { + break; // Exit the loop when i is 5 + } + printf("%d\n", i); +} +```` + +### 2. continue +The continue statement is used to skip the current iteration of the loop and move to the next iteration. + +#### Example: +```C +for (int i = 0; i < 10; i++) { + if (i % 2 == 0) { + continue; // Skip even numbers + } + printf("%d\n", i); +} +``` + +### Nested Loops +You can use loops inside other loops, known as nested loops. This is useful for working with multi-dimensional data structures. + +#### Example: +```C +for (int i = 0; i < 3; i++) { + for (int j = 0; j < 2; j++) { + printf("i: %d, j: %d\n", i, j); + } +} +``` + +### Summary +- Loops allow you to execute a block of code repeatedly based on a condition. +- The primary types of loops are for, while, and do-while. +- Loop control statements like break and continue help manage the flow of loops. +- Nested loops can be used for working with multi-dimensional data. diff --git a/docs/programming-fundamentals/OOPS/oops-01.md b/docs/programming-fundamentals/OOPS/oops-01.md new file mode 100644 index 000000000..f250fcd4d --- /dev/null +++ b/docs/programming-fundamentals/OOPS/oops-01.md @@ -0,0 +1,47 @@ +--- +id: intro-to-oops +title: Introduction to Object-Oriented Programming (OOP) +sidebar_label: Introduction to OOP +sidebar_position: 1 +description: "Object-Oriented Programming (OOP) is a programming paradigm based on the concept of objects, which can contain data and code to manipulate that data. It promotes concepts like encapsulation, inheritance, and polymorphism." +tags: [oops, object-oriented-programming] +--- + +# **Introduction to Object-Oriented Programming (OOPs)** + +Object-Oriented Programming (OOPs) is a **programming paradigm** that organizes software design around data, or objects, rather than functions and logic. It helps in breaking down complex problems into smaller, manageable units by representing real-world entities as objects. + +## **Key Concepts of OOPs** + +OOPs is built on four main pillars: +1. **Encapsulation** +2. **Abstraction** +3. **Inheritance** +4. **Polymorphism** + + +These core concepts help developers create software that is more modular, reusable, and scalable. We will explore these in detail in the following sections. + +--- + +## **Advantages of OOPs over Procedure-Oriented Programming** + +Object-oriented programming (OOP) offers several key advantages over procedural programming: + +- **Code Reusability**: OOP promotes code reusability by using objects and classes. This leads to less duplication and more efficient development, as you can create reusable components that can be leveraged in different parts of your application. + +- **Enhanced Code Organization**: OOP provides a clear and logical structure, making the code easier to understand, maintain, and debug. By organizing code into objects, related functionalities are grouped together. + +- **Support for DRY Principle**: OOP supports the DRY (Don’t Repeat Yourself) principle, encouraging the minimization of code repetition. This leads to cleaner, more maintainable code, as common functionalities are placed in a single location and reused, reducing redundancy. + +- **Faster Development**: OOP enables faster development by reusing existing code and creating modular components. This allows for quicker and more efficient application development, as developers can build upon already existing codebases. + +--- + +## **Why OOPs is Important?** + +OOPs mirrors real-world entities and their interactions, making it a natural way to structure code for many applications. This approach is widely used in designing software systems that require high levels of flexibility and extensibility, such as video games, graphical user interfaces (GUIs), and complex enterprise applications. + +--- + +The next sections will delve deeper into each of these principles and other related concepts like **Classes and Objects**, **Constructors**, **Interfaces**, and **Real-World Examples**. diff --git a/docs/programming-fundamentals/OOPS/oops-02.md b/docs/programming-fundamentals/OOPS/oops-02.md new file mode 100644 index 000000000..23582f43a --- /dev/null +++ b/docs/programming-fundamentals/OOPS/oops-02.md @@ -0,0 +1,161 @@ +--- +id: classes-and-objects +title: "Classes and Objects in OOP" +sidebar_label: Classes and Objects +sidebar_position: 2 +description: "In OOP, a class is a blueprint for creating objects (instances), providing initial values for state (member variables) and implementations of behavior (member functions or methods)." +tags: [oops, classes, objects] +--- + +# **Classes and Objects in Object-Oriented Programming** + +In Object-Oriented Programming (OOP), **classes** and **objects** are fundamental concepts that help structure your code. + +## **What is a Class?** + +A **class** is a blueprint or template for creating objects. It defines a datatype by bundling data and methods that work on the data. Classes encapsulate data for the object and define methods for manipulating that data. + +### **Key Components of a Class:** +- **Attributes**: Variables that hold data for the class. +- **Methods**: Functions defined inside the class that can manipulate the attributes. + +### **Example of a Class** + +

    +C++ Code + +```cpp +class Car { +private: + string model; + int year; + +public: + // Constructor + Car(string m, int y) : model(m), year(y) {} + + // Method to display car details + void display() { + cout << "Model: " << model << ", Year: " << year << endl; + } +}; +``` +
    + +
    +Java Code + +```java +class Car { + private String model; + private int year; + + // Constructor + Car(String m, int y) { + model = m; + year = y; + } + + // Method to display car details + void display() { + System.out.println("Model: " + model + ", Year: " + year); + } +} +``` +
    + +
    +JavaScript Code + +```js +class Car { + #model; // Private field + #year; // Private field + + // Constructor + constructor(model, year) { + this.#model = model; + this.#year = year; + } + + // Method to display car details + display() { + console.log(`Model: ${this.#model}, Year: ${this.#year}`); + } +} + +const myCar = new Car("Toyota", 2020); +myCar.display(); // Output: Model: Toyota, Year: 2020 + +``` +
    + +--- + +## **What is an Object?** + +An **object** is an instance of a class. When you create an object, you create a specific instance of a class with its own unique set of attributes. Objects interact with one another and can have their own state and behavior. + +### **Creating Objects** + +
    +C++ Code + +```cpp +int main() { + Car myCar("Toyota", 2020); + myCar.display(); // Output: Model: Toyota, Year: 2020 + return 0; +} +``` +
    + +
    +Java Code + +```java +public class Main { + public static void main(String[] args) { + Car myCar = new Car("Toyota", 2020); + myCar.display(); // Output: Model: Toyota, Year: 2020 + } +} +``` +
    + +
    +JavaScript Code + +```js +class Car { + constructor(model, year) { + this.model = model; + this.year = year; + } + display() { + console.log(`Model: ${this.model}, Year: ${this.year}`); + } +} +const myCar = new Car("Toyota", 2020); +myCar.display(); // Output: Model: Toyota, Year: 2020 +``` +
    + +--- + +## **Key Differences Between Classes and Objects:** +- **Definition**: A class is a blueprint; an object is an instance of that blueprint. +- **Memory**: Class is a logical entity; an object is a physical entity in memory. +- **Instantiation**: Classes need to be instantiated to create objects. + + +*Diagram illustrating the relationship between classes and objects in OOP.* + +--- + +## **Conclusion** + +Classes and objects are the cornerstones of OOP, enabling developers to create modular, reusable, and maintainable code. Understanding these concepts is essential for mastering object-oriented design and programming. + +--- + diff --git a/docs/programming-fundamentals/OOPS/oops-03.md b/docs/programming-fundamentals/OOPS/oops-03.md new file mode 100644 index 000000000..6adae1c0b --- /dev/null +++ b/docs/programming-fundamentals/OOPS/oops-03.md @@ -0,0 +1,255 @@ +--- +id: constructors-and-destructors +title: Constructors and Destructors in OOP +sidebar_label: Constructors and Destructors +sidebar_position: 3 +description: "Constructors and destructors are special methods in OOP that handle object initialization and cleanup. Constructors set up the initial state, while destructors handle object destruction and resource management." +tags: [oops, constructors, destructors] +--- + +# **Constructors and Destructors** + +Constructors and destructors are **special member functions** in object-oriented programming (OOP) that are automatically called when an object is created or destroyed, respectively. They are essential for initializing and cleaning up resources used by objects. + +--- + +## **1. What is a Constructor?** + +A **constructor** is a special function that initializes an object when it is created. It has the same name as the class and does not have a return type. Constructors can take parameters to initialize object attributes. + +### **Types of Constructors** +- **Default Constructor**: A constructor that does not take any parameters. +- **Parameterized Constructor**: A constructor that takes parameters to set initial values for the object. + +### **Example of Constructors** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Rectangle { +private: + int width, height; + +public: + // Default Constructor + Rectangle() { + width = 0; + height = 0; + } + + // Parameterized Constructor + Rectangle(int w, int h) { + width = w; + height = h; + } + + void display() { + cout << "Width: " << width << ", Height: " << height << endl; + } +}; + +int main() { + Rectangle rect1; // Default constructor + Rectangle rect2(10, 5); // Parameterized constructor + + rect1.display(); + rect2.display(); + return 0; +} +``` +
    + +
    +Java Code + +```java +class Rectangle { + private int width, height; + + // Default Constructor + Rectangle() { + width = 0; + height = 0; + } + + // Parameterized Constructor + Rectangle(int w, int h) { + width = w; + height = h; + } + + void display() { + System.out.println("Width: " + width + ", Height: " + height); + } +} + +public class Main { + public static void main(String[] args) { + Rectangle rect1 = new Rectangle(); // Default constructor + Rectangle rect2 = new Rectangle(10, 5); // Parameterized constructor + + rect1.display(); + rect2.display(); + } +} +``` +
    + +
    +JavaScript Code + +```js +class Rectangle { + // Default Constructor + constructor(width = 0, height = 0) { + this.width = width; + this.height = height; + } + + // Method to display width and height + display() { + console.log(`Width: ${this.width}, Height: ${this.height}`); + } +} + +// Main code to demonstrate constructors +const rect1 = new Rectangle(); // Default constructor +const rect2 = new Rectangle(10, 5); // Parameterized constructor + +rect1.display(); // Output: Width: 0, Height: 0 +rect2.display(); // Output: Width: 10, Height: 5 + +``` +
    + +--- + +## **2. What is a Destructor?** + +A **destructor** is a special function that is called when an object is destroyed. It has the same name as the class but is preceded by a tilde (~) in C++. Destructors are used to release resources allocated to the object, such as memory or file handles. + +### **Example of Destructors** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Rectangle { +private: + int width, height; + +public: + Rectangle(int w, int h) : width(w), height(h) { + cout << "Constructor called!" << endl; + } + + ~Rectangle() { + cout << "Destructor called!" << endl; + } + + void display() { + cout << "Width: " << width << ", Height: " << height << endl; + } +}; + +int main() { + Rectangle rect(10, 5); + rect.display(); + return 0; // Destructor is called automatically here +} +``` +
    + +
    +Java Code + +```java +class Rectangle { + private int width, height; + + Rectangle(int w, int h) { + width = w; + height = h; + System.out.println("Constructor called!"); + } + + // Finalize method acts as a destructor in Java + protected void finalize() { + System.out.println("Destructor called!"); + } + + void display() { + System.out.println("Width: " + width + ", Height: " + height); + } +} + +public class Main { + public static void main(String[] args) { + Rectangle rect = new Rectangle(10, 5); + rect.display(); + rect = null; // Request garbage collection + System.gc(); // Calling garbage collector + } +} +``` +
    + +
    +JavaScript Code + +```js +// In JavaScript, there is no explicit destructor like in Java or C++. Instead, memory management is handled +// automatically by the garbage collector. However, you can mimic the behavior of a destructor using the +// finalize method available via the FinalizationRegistry, which lets you run cleanup code when an object +// is garbage collected. + +class Rectangle { + #width; // Private field + #height; // Private field + + constructor(width, height) { + this.#width = width; + this.#height = height; + console.log("Constructor called!"); + } + + // Method to display width and height + display() { + console.log(`Width: ${this.#width}, Height: ${this.#height}`); + } +} + +// Create a FinalizationRegistry to simulate destructor +const registry = new FinalizationRegistry(() => { + console.log("Destructor called!"); +}); + +// Main code +let rect = new Rectangle(10, 5); +rect.display(); + +// Register the object for cleanup when it's garbage collected +registry.register(rect, "Rectangle Instance"); + +// Simulate object being nullified and garbage collected +rect = null; +globalThis.gc?.(); // This is optional; the garbage collector runs automatically + +``` +
    + +--- + +## **3. Importance of Constructors and Destructors** + +- **Resource Management**: Constructors are used to allocate resources, while destructors are used to release them. This ensures that resources are properly managed and prevents memory leaks. +- **Initialization**: Constructors allow for setting initial values for object attributes, providing a clear and consistent way to create objects. + +--- \ No newline at end of file diff --git a/docs/programming-fundamentals/OOPS/oops-04.md b/docs/programming-fundamentals/OOPS/oops-04.md new file mode 100644 index 000000000..50af7daa9 --- /dev/null +++ b/docs/programming-fundamentals/OOPS/oops-04.md @@ -0,0 +1,225 @@ +--- +id: interface-vs-abstract-class +title: Interface vs Abstract Class in OOP +sidebar_label: Interface vs Abstract Class +sidebar_position: 5 +description: "An interface defines a contract for behavior, whereas an abstract class provides partial implementation. Both are used to achieve abstraction but differ in their design and use cases." +tags: [oops, interface, abstract-class] +--- + +# **Interface vs Abstract Classes** + +In object-oriented programming, both **interfaces** and **abstract classes** are used to achieve abstraction, allowing you to define methods that must be implemented by derived classes. However, they serve different purposes and have distinct characteristics. + +--- + +## **1. What is an Abstract Class?** + +An **abstract class** is a class that cannot be instantiated on its own and is meant to be subclassed. It can contain both abstract methods (without implementation) and concrete methods (with implementation). Abstract classes are used to provide a common base for derived classes. + +### **Key Features of Abstract Classes** +- Can have both abstract and concrete methods. +- Can have member variables. +- Can provide a default implementation for some methods. + +### **Example of Abstract Class** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Animal { +public: + // Abstract method + virtual void sound() = 0; // Pure virtual function + + void sleep() { + cout << "Sleeping..." << endl; + } +}; + +class Dog : public Animal { +public: + void sound() { + cout << "Woof!" << endl; + } +}; + +int main() { + Dog dog; + dog.sound(); // Calls the sound method + dog.sleep(); // Calls the sleep method from the Animal class + return 0; +} +``` +
    + +
    +Java Code + +```java +abstract class Animal { + // Abstract method + abstract void sound(); + + void sleep() { + System.out.println("Sleeping..."); + } +} + +class Dog extends Animal { + void sound() { + System.out.println("Woof!"); + } +} + +public class Main { + public static void main(String[] args) { + Dog dog = new Dog(); + dog.sound(); // Calls the sound method + dog.sleep(); // Calls the sleep method from the Animal class + } +} +``` +
    + +
    +JavaScript Code + +```js +//JavaScript doesn't have a built-in concept of abstract classes like in Java or C++, but you can mimic this +//behavior using a combination of class inheritance and throwing errors when an abstract method is not implemented. + +class Animal { + // Abstract method + sound() { + throw new Error("Abstract method 'sound' must be implemented by subclass"); + } + + // Concrete method + sleep() { + console.log("Sleeping..."); + } +} + +class Dog extends Animal { + // Implement the abstract method + sound() { + console.log("Woof!"); + } +} + +// Main code +const dog = new Dog(); +dog.sound(); // Calls the sound method +dog.sleep(); // Calls the sleep method from the Animal class + +``` +
    + +--- +## **2. What is an Interface?** + +An **interface** is a contract that defines a set of methods that implementing classes must provide. It cannot contain any implementation itself (in languages like Java) and is used to achieve multiple inheritance. + +### **Key Features of Interfaces** +- Can only contain abstract methods (Java 8 and above allows default methods). +- Cannot have member variables (only constants). +- Supports multiple inheritance. + +### **Example of Interface** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class IAnimal { +public: + virtual void sound() = 0; // Pure virtual function +}; + +class Cat : public IAnimal { +public: + void sound() { + cout << "Meow!" << endl; + } +}; + +int main() { + Cat cat; + cat.sound(); // Calls the sound method + return 0; +} +``` +
    + +
    +Java Code + +```java +interface IAnimal { + void sound(); // Abstract method +} + +class Cat implements IAnimal { + public void sound() { + System.out.println("Meow!"); + } +} + +public class Main { + public static void main(String[] args) { + Cat cat = new Cat(); + cat.sound(); // Calls the sound method + } +} +``` +
    + +
    +JavaScript Code + +```js +// JavaScript does not have a built-in concept of interfaces like Java or C++, but you can simulate +// interfaces by defining a structure that classes must follow. + +class IAnimal { + sound() { + throw new Error("Method 'sound()' must be implemented"); + } +} + +class Cat extends IAnimal { + // Implementing the sound method + sound() { + console.log("Meow!"); + } +} + +// Main code +const cat = new Cat(); +cat.sound(); // Calls the sound method + +``` +
    + + +--- + +## **3. Key Differences Between Abstract Classes and Interfaces** + +| Feature | Abstract Class | Interface | +|------------------------------|----------------------------------------|---------------------------------------------| +| **Instantiation** | Cannot be instantiated | Cannot be instantiated | +| **Method Implementation** | Can have both abstract and concrete methods | Can only have abstract methods (until Java 8) | +| **Inheritance** | Can extend only one abstract class | Can implement multiple interfaces | +| **Access Modifiers** | Can use any access modifier | All methods are public by default | +| **Member Variables** | Can have member variables | Cannot have member variables | + +--- \ No newline at end of file diff --git a/docs/programming-fundamentals/OOPS/oops-05.md b/docs/programming-fundamentals/OOPS/oops-05.md new file mode 100644 index 000000000..2d6896a54 --- /dev/null +++ b/docs/programming-fundamentals/OOPS/oops-05.md @@ -0,0 +1,486 @@ +--- +id: pillars-of-oops +title: "Pillars of OOP: Abstraction, Encapsulation, Inheritance, Polymorphism" +sidebar_label: Pillars of OOP +sidebar_position: 4 +description: "The four main pillars of OOP are abstraction, encapsulation, inheritance, and polymorphism. These principles provide a foundation for creating robust and reusable code in object-oriented systems." +tags: [oops, abstraction, encapsulation, inheritance, polymorphism] +--- + +# **Pillars of OOPs** + +Object-Oriented Programming (OOP) is built on four main pillars: **Abstraction**, **Encapsulation**, **Inheritance**, and **Polymorphism**. Each of these concepts plays a crucial role in creating modular, reusable, and maintainable code. + +--- + +## **1. Abstraction** + +Abstraction is the process of hiding the complex implementation details and showing only the essential features of an object. It allows developers to reduce complexity by providing a simplified interface. + +### **Key Points** +- Focuses on **what** an object does rather than **how** it does it. +- Achieved through abstract classes and interfaces. + +### **Example of Abstraction** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Shape { +public: + virtual void draw() = 0; // Pure virtual function +}; + +class Circle : public Shape { +public: + void draw() { + cout << "Drawing Circle" << endl; + } +}; + +int main() { + Circle circle; + circle.draw(); // Calls the draw method + return 0; +} +``` +
    + +
    +Java Code + +```java +abstract class Shape { + abstract void draw(); // Abstract method +} + +class Circle extends Shape { + void draw() { + System.out.println("Drawing Circle"); + } +} + +public class Main { + public static void main(String[] args) { + Circle circle = new Circle(); + circle.draw(); // Calls the draw method + } +} +``` +
    + +
    +JavaScript Code + +```js +// In JavaScript, abstract methods are not natively supported, but we can simulate abstract behavior +// by throwing an error in the base class method and forcing subclasses to implement it. +class Shape { + // Simulate an abstract method + draw() { + throw new Error("Method 'draw()' must be implemented"); + } +} + +class Circle extends Shape { + // Implementing the abstract method + draw() { + console.log("Drawing Circle"); + } +} + +// Main code +const circle = new Circle(); +circle.draw(); // Output: Drawing Circle + +``` +
    + +--- + +## **2. Encapsulation** + +Encapsulation is the bundling of data (attributes) and methods (functions) that operate on the data into a single unit called a class. It restricts direct access to some of the object's components, which is a means of preventing unintended interference and misuse. + +### **Key Points** +- Protects an object's state by restricting access to its internal data. +- Achieved using access modifiers (private, protected, public). + +### **Example of Encapsulation** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class BankAccount { +private: + double balance; // Private data member + +public: + BankAccount() : balance(0) {} // Constructor + + void deposit(double amount) { + balance += amount; + } + + void displayBalance() { + cout << "Balance: " << balance << endl; + } +}; + +int main() { + BankAccount account; + account.deposit(1000); + account.displayBalance(); // Displays the balance + return 0; +} +``` +
    + +
    +Java Code + +```java +class BankAccount { + private double balance; // Private data member + + public BankAccount() { + balance = 0; // Constructor + } + + public void deposit(double amount) { + balance += amount; + } + + public void displayBalance() { + System.out.println("Balance: " + balance); + } +} + +public class Main { + public static void main(String[] args) { + BankAccount account = new BankAccount(); + account.deposit(1000); + account.displayBalance(); // Displays the balance + } +} +``` +
    + +
    +JavaScript Code + +```js +class BankAccount { + #balance; // Private field + + constructor() { + this.#balance = 0; // Initialize balance in constructor + } + + // Method to deposit money + deposit(amount) { + this.#balance += amount; + } + + // Method to display balance + displayBalance() { + console.log(`Balance: ${this.#balance}`); + } +} + +// Main code +const account = new BankAccount(); +account.deposit(1000); +account.displayBalance(); // Output: Balance: 1000 + +``` +
    + +--- + +## **3. Inheritance** + +Inheritance is a mechanism that allows one class to inherit the properties and behaviors (methods) of another class. It promotes code reusability and establishes a hierarchical relationship between classes. + +### **Key Points** +- The class that inherits is called the **derived class** or **child class**, and the class being inherited from is called the **base class** or **parent class**. +- Supports "is-a" relationship. + +### **Example of Inheritance** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Animal { +public: + void eat() { + cout << "Eating..." << endl; + } +}; + +class Dog : public Animal { // Dog inherits from Animal +public: + void bark() { + cout << "Woof!" << endl; + } +}; + +int main() { + Dog dog; + dog.eat(); // Inherited method + dog.bark(); // Dog's own method + return 0; +} +``` +
    + +
    +Java Code + +```java +class Animal { + void eat() { + System.out.println("Eating..."); + } +} + +class Dog extends Animal { // Dog inherits from Animal + void bark() { + System.out.println("Woof!"); + } +} + +public class Main { + public static void main(String[] args) { + Dog dog = new Dog(); + dog.eat(); // Inherited method + dog.bark(); // Dog's own method + } +} +``` +
    + +
    +JavaScript Code + +```js +class Animal { + eat() { + console.log("Eating..."); + } +} + +class Dog extends Animal { // Dog inherits from Animal + bark() { + console.log("Woof!"); + } +} + +// Main code +const dog = new Dog(); +dog.eat(); // Inherited method +dog.bark(); // Dog's own method + +``` +
    + +--- + +## **4. Polymorphism** + +Polymorphism allows methods to do different things based on the object it is acting upon. It means "many forms" and can be classified into two types: **Compile-time polymorphism** and **Runtime polymorphism**. + +### **4.1 Compile-time Polymorphism** + +Also known as **method overloading**, it occurs when multiple methods in the same class have the same name but different parameters. + +#### **Example of Compile-time Polymorphism** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Math { +public: + int add(int a, int b) { + return a + b; + } + + double add(double a, double b) { + return a + b; + } +}; + +int main() { + Math math; + cout << "Int Addition: " << math.add(5, 10) << endl; // Calls int version + cout << "Double Addition: " << math.add(5.5, 10.5) << endl; // Calls double version + return 0; +} +``` +
    + +
    +Java Code + +```java +class Math { + int add(int a, int b) { + return a + b; + } + + double add(double a, double b) { + return a + b; + } +} + +public class Main { + public static void main(String[] args) { + Math math = new Math(); + System.out.println("Int Addition: " + math.add(5, 10)); // Calls int version + System.out.println("Double Addition: " + math.add(5.5, 10.5)); // Calls double version + } +} +``` +
    + +
    +JavaScript Code + +```js +// JavaScript does not support method overloading in the same way that Java does. +// Instead, you can achieve similar functionality by using a single method that checks +// the types of its arguments and performs the appropriate operation. + +class Math { + add(a, b) { + // Check types of a and b + if (typeof a === 'number' && typeof b === 'number') { + return a + b; // Addition + } else { + throw new Error("Invalid arguments: Both arguments must be numbers"); + } + } +} + +// Main code +const math = new Math(); +console.log("Int Addition: " + math.add(5, 10)); // Output: Int Addition: 15 +console.log("Double Addition: " + math.add(5.5, 10.5)); // Output: Double Addition: 16 + +``` +
    + +### **4.2 Runtime Polymorphism** + +Also known as **method overriding**, it occurs when a derived class provides a specific implementation of a method that is already defined in its base class. The decision about which method to call is made at runtime. + +#### **Example of Runtime Polymorphism** + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Animal { +public: + virtual void sound() { // Virtual method + cout << "Animal sound" << endl; + } +}; + +class Dog : public Animal { +public: + void sound() override { // Override method + cout << "Woof!" << endl; + } +}; + +int main() { + Animal* animal = new Dog(); // Pointer to base class + animal->sound(); // Calls Dog's sound method + delete animal; + return 0; +} +``` +
    + +
    +Java Code + +```java +class Animal { + void sound() { // Base class method + System.out.println("Animal sound"); + } +} + +class Dog extends Animal { + void sound() { // Override method + System.out.println("Woof!"); + } +} + +public class Main { + public static void main(String[] args) { + Animal animal = new Dog(); // Reference to base class + animal.sound(); // Calls Dog's sound method + } +} +``` +
    + +
    +JavaScript Code + +```js +class Animal { + sound() { // Base class method + console.log("Animal sound"); + } +} + +class Dog extends Animal { + sound() { // Override method + console.log("Woof!"); + } +} + +// Main code +const animal = new Dog(); // Reference to base class +animal.sound(); // Calls Dog's sound method, Output: Woof! + +``` +
    + +--- + +### Differences between Compile-time and Runtime Polymorphism + +| **Feature** | **Compile-time Polymorphism** | **Runtime Polymorphism** | +|-------------------------|---------------------------------------------|------------------------------------------| +| **Definition** | Achieved through method overloading. | Achieved through method overriding. | +| **Binding Time** | Resolved during compilation. | Resolved during runtime. | +| **Method Resolution** | The compiler determines which method to call. | The JVM determines which method to call. | +| **Performance** | Generally faster due to early binding. | Slightly slower due to late binding. | +| **Flexibility** | Less flexible as the decision is made at compile time. | More flexible as the decision is made at runtime. | +| **Example** | Overloading methods with different parameters. | Overriding a method in a derived class. | + +--- diff --git a/docs/programming-fundamentals/OOPS/oops-06.md b/docs/programming-fundamentals/OOPS/oops-06.md new file mode 100644 index 000000000..f6c7078be --- /dev/null +++ b/docs/programming-fundamentals/OOPS/oops-06.md @@ -0,0 +1,87 @@ +--- +id: encapsulation +title: "Encapsulation in Object-Oriented Programming (OOP)" +sidebar_label: Encapsulation +sidebar_position: 2 +description: "Encapsulation is the process of bundling data and methods that operate on that data into a single unit, and restricting access to internal details." +tags: [oops, encapsulation, object-oriented programming] +--- + +# **Encapsulation in OOP** + +Encapsulation is a core concept in Object-Oriented Programming (OOP) that involves bundling the data (attributes) and methods (functions) that operate on the data into a single unit, typically a class. It restricts direct access to some of the object's components, thereby protecting the object's internal state. + +--- + +## **Key Features of Encapsulation** +- **Data hiding**: Prevents direct access to internal data members. +- Promotes **modularity** by ensuring that the internal workings of an object are hidden from the outside world. +- Achieved using **access modifiers** like `private`, `protected`, and `public`. + +--- + +### **Example of Encapsulation** + + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Employee { +private: + int salary; // Private data member + +public: + void setSalary(int s) { + salary = s; + } + + int getSalary() { + return salary; + } +}; + +int main() { + Employee emp; + emp.setSalary(5000); + cout << "Employee Salary: " << emp.getSalary() << endl; + return 0; +} +``` + +
    + +
    +JavaScript Code + +```js +class Employee { + #salary; // Private field + + // Setter method for salary + setSalary(salary) { + this.#salary = salary; + } + + // Getter method for salary + getSalary() { + return this.#salary; + } +} + +// Main code to demonstrate encapsulation +const emp = new Employee(); +emp.setSalary(5000); +console.log(`Employee Salary: ${emp.getSalary()}`); // Output: Employee Salary: 5000 + +``` + +
    + +## Advantages of Encapsulation +Increased security by restricting access to sensitive data. +Modular design allows changes to internal implementation without affecting the external interface. +Improved maintainability as the code is organized and modular. \ No newline at end of file diff --git a/docs/programming-fundamentals/OOPS/oops-07.md b/docs/programming-fundamentals/OOPS/oops-07.md new file mode 100644 index 000000000..d0d302723 --- /dev/null +++ b/docs/programming-fundamentals/OOPS/oops-07.md @@ -0,0 +1,83 @@ +--- +id: inheritance +title: "Inheritance in Object-Oriented Programming (OOP)" +sidebar_label: Inheritance +sidebar_position: 3 +description: "Inheritance allows one class to inherit properties and behaviors from another class, promoting code reuse and creating a hierarchy." +tags: [oops, inheritance, object-oriented programming] +--- + +# **Inheritance in OOP** + +Inheritance is a fundamental principle in Object-Oriented Programming (OOP) that allows a class to inherit properties and behaviors (methods) from another class. This helps in code reuse and establishes a parent-child relationship between classes. + +--- + +## **Key Features of Inheritance** +- Establishes a **hierarchical relationship** between classes. +- Promotes **code reuse** by allowing derived classes to use methods and attributes of the base class. +- Supports an **"is-a" relationship** between objects. + +--- + +### **Example of Inheritance** + + +
    +C++ Code + +```cpp +#include +using namespace std; + +class Vehicle { +public: + void move() { + cout << "Vehicle is moving" << endl; + } +}; + +class Car : public Vehicle { // Car inherits from Vehicle +public: + void honk() { + cout << "Car is honking" << endl; + } +}; + +int main() { + Car car; + car.move(); // Inherited method + car.honk(); // Car's own method + return 0; +} +``` +
    + +
    +JavaScript Code + +```js +class Vehicle { + move() { + console.log("Vehicle is moving"); + } +} + +class Car extends Vehicle { // Car inherits from Vehicle + honk() { + console.log("Car is honking"); + } +} + +// Main code +const car = new Car(); +car.move(); // Inherited method +car.honk(); // Car's own method + +``` +
    + +## Advantages of Inheritance +Code reuse: Common code is written in the parent class and reused by child classes. +Extensibility: New features can be added to the child class without modifying the parent class. +Polymorphism: Supports runtime polymorphism through method overriding. diff --git a/docs/programming-fundamentals/OOPS/oops-08.md b/docs/programming-fundamentals/OOPS/oops-08.md new file mode 100644 index 000000000..2e5e42d6a --- /dev/null +++ b/docs/programming-fundamentals/OOPS/oops-08.md @@ -0,0 +1,79 @@ +--- +id: polymorphism +title: "Polymorphism in Object-Oriented Programming (OOP)" +sidebar_label: Polymorphism +sidebar_position: 4 +description: "Polymorphism allows methods to take many forms, enabling flexibility in calling methods based on object type. It can be categorized into compile-time and runtime polymorphism." +tags: [oops, polymorphism, object-oriented programming] +--- + +# **Polymorphism in OOP** + +Polymorphism is a key concept in Object-Oriented Programming (OOP) that allows methods to perform different tasks based on the object that calls them. It can be categorized into two types: **compile-time polymorphism** and **runtime polymorphism**. + +--- + +## **Types of Polymorphism** + +### **1. Compile-time Polymorphism** +Also known as **method overloading**, it allows multiple methods with the same name but different parameters to coexist in the same class. + +### **Example of Compile-time Polymorphism** + + +```cpp +#include +using namespace std; + +class Math { +public: + int add(int a, int b) { + return a + b; + } + + double add(double a, double b) { + return a + b; + } +}; + +int main() { + Math math; + cout << "Int Addition: " << math.add(5, 10) << endl; + cout << "Double Addition: " << math.add(5.5, 10.5) << endl; + return 0; +} +``` + +2. Runtime Polymorphism +Also known as method overriding, it occurs when a child class provides a specific implementation of a method that is already defined in its parent class. This is determined at runtime. + +Example of Runtime Polymorphism +```cpp +#include +using namespace std; + +class Animal { +public: + virtual void sound() { + cout << "Animal sound" << endl; + } +}; + +class Dog : public Animal { +public: + void sound() override { + cout << "Woof!" << endl; + } +}; + +int main() { + Animal* animal = new Dog(); // Pointer to base class + animal->sound(); // Calls Dog's sound method + delete animal; + return 0; +} +``` +## Advantages of Polymorphism +Flexibility: The same method can perform different tasks based on the object it acts upon. +Extensibility: New behavior can be added by overriding existing methods without modifying the base class. +Dynamic method dispatch: At runtime, the correct method is chosen based on the object type. diff --git a/docs/programming-fundamentals/Variables.md b/docs/programming-fundamentals/Variables.md new file mode 100644 index 000000000..f2303a160 --- /dev/null +++ b/docs/programming-fundamentals/Variables.md @@ -0,0 +1,149 @@ +--- +id: Variables +title: Introduction to variables fundamentals +sidebar_label: Variables +sidebar_position: 6 +description: "Information About variables in progamming" +tags: [variables,fundamentals] +--- + +# Variables in C + +## What are Variables? +Variables in C are containers used to store data values. Each variable is given a specific type, which defines the kind of data it can hold, like integers, floating-point numbers, characters, etc. + +## Declaration and Initialization +A variable must be declared before it can be used. You can also initialize a variable with a value when you declare it. + +### Syntax: +```c +data_type variable_name; +data_type variable_name = value; +``` + +### Example: +```C +int age = 21; // Integer variable initialized with value 21 +float height = 5.9; // Float variable initialized with value 5.9 +char grade = 'A'; // Character variable initialized with value 'A' +``` + +### Multiple Declarations: +You can declare multiple variables of the same type in one line. + +```C +int a = 5, b = 10, c = 15; +``` + +### Types of Variables +C supports several data types to store various kinds of data: + +1. int: Used to store integer values (whole numbers). +int count = 10; +Range: -32,768 to 32,767 (typically 2 bytes, but depends on system). + +2. float: Used to store single-precision floating-point numbers (decimals). +float price = 19.99; +Precision: Up to 7 decimal digits. + +3. double: Used to store double-precision floating-point numbers (larger decimals). +double bigNumber = 12345.6789; +Precision: Up to 15 decimal digits. + +4. char: Used to store single characters. +char initial = 'A'; + +5. _Bool: Used to store boolean values (true/false). In C, true is represented by 1 and false by 0. +_Bool isTrue = 1; + +6. unsigned int: Used to store only non-negative integers. +unsigned int age = 25; +Range: 0 to 65,535 (for 2 bytes). + + +### Scope of Variables +The scope of a variable defines the region of the program where the variable can be accessed. + +1. Local Variables: Declared inside a function or block, and they can only be accessed within that function/block. +```C +void myFunction() { + int x = 10; // Local variable +} +``` + +2. Global Variables: Declared outside all functions, and they can be accessed by any function within the program. +```C +int globalVar = 20; + +void myFunction() { + // globalVar can be accessed here +} +``` + +3. Static Variables: Variables that maintain their value between function calls. They are initialized only once. +```C +void myFunction() { + static int counter = 0; // Static variable + counter++; +} +``` + +4. Register Variables: Stored in CPU registers instead of RAM, providing faster access. These are recommended for frequently used variables. +```C +register int fastCounter = 0; +``` + +### Storage Classes +Storage classes in C define the scope, lifetime, and visibility of variables. + +1. auto: The default storage class for local variables. +```C +auto int num = 10; +``` + +2. extern: Used to declare a global variable that is defined elsewhere. +```C +extern int globalVar; +``` + +3. static: Limits the scope of a variable to its source file or function, while preserving its value across function calls. +```C +static int count = 0; +``` + +4. register: Suggests that the compiler store the variable in a CPU register for faster access. +```C +register int i = 5; +``` + +### Variable Naming Rules +- Names can contain letters, digits, and underscores (_), but the first character must be a letter or underscore. +- Keywords cannot be used as variable names. +- C is case-sensitive, so num and Num would be considered different variables. + + +### Example: +```C +int count; +float _price; +double price123; +``` + +### Constants +Constants are variables whose values cannot be changed once initialized. In C, constants are defined using the const keyword or #define preprocessor directive. + +### Using `const`: +```C +const int MAX = 100; +``` + +### Using #define: +```C +#define PI 3.14159 +``` + +### Summary +- Variables store data and can be of different types such as int, float, char, etc. +- Variables have a scope that defines where they can be accessed within a program. +- Storage classes modify the scope and lifetime of a variable. +- Constants are variables whose value cannot be changed after initialization. diff --git a/docs/programming-fundamentals/_category_.json b/docs/programming-fundamentals/_category_.json new file mode 100644 index 000000000..8cc1338fd --- /dev/null +++ b/docs/programming-fundamentals/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Programming Fundamentals", + "position": 4, + "link": { + "type": "generated-index", + "description": "Learn about Programming Fundamentals. This is the first step to become a good programmer." + } + } \ No newline at end of file diff --git a/docs/programming-fundamentals/functions.md b/docs/programming-fundamentals/functions.md new file mode 100644 index 000000000..0c72472d7 --- /dev/null +++ b/docs/programming-fundamentals/functions.md @@ -0,0 +1,116 @@ +--- +id: functions +title: Introduction to functions fundamentals +sidebar_label: Functions +sidebar_position: 4 +description: "Information About functions in programming" +tags: [functions, fundamentals] +--- + + +## What are Functions? +Functions in C are self-contained blocks of code that perform a specific task. They allow for code reuse, modular programming, and improve the clarity of the code. + +## Defining a Function +A function is defined by specifying its return type, name, parameters (if any), and the body of the function. + +### Syntax: +```c +return_type function_name(parameter1_type parameter1, parameter2_type parameter2) { + // function body + // return statement (if return_type is not void) +} +``` + +### Example: +```C +int add(int a, int b) { + return a + b; +} +``` + +## Calling a Function +To use a function, you need to call it by its name and pass the required arguments. + +### Example: +```C +int sum = add(5, 10); // Calling the add function +printf("Sum: %d\n", sum); +``` + +## Types of Functions +### 1. Standard Library Functions +These are built-in functions provided by C libraries, such as printf(), scanf(), strlen(), etc. + +#### Example: +```C +#include + +int main() { + printf("Hello, World!\n"); // Standard library function + return 0; +} +``` + +### 2. User-Defined Functions +These are functions defined by the user to perform specific tasks. + +#### Example: +```C +void greet() { + printf("Hello, User!\n"); +} +``` + +##Function Parameters +Functions can accept parameters, which allow you to pass data into the function. + +### Types of Parameters: +1. Value Parameters: The function receives a copy of the argument. +2. Reference Parameters: The function receives a reference (address) to the argument. + +### Example of Value Parameter: +```C +void square(int num) { + num = num * num; // This does not affect the original argument +} +``` + +### Example of Reference Parameter: +```C +void square(int *num) { + *num = *num * *num; // This affects the original argument +} +``` + +## Return Statement +The return statement is used to return a value from a function. If the return type is void, the function does not return a value. + +### Example: +```C +double multiply(double x, double y) { + return x * y; // Returns the product of x and y +} +``` + +## Function Overloading +C does not support function overloading (defining multiple functions with the same name but different parameters) like C++. However, you can achieve similar functionality by using different names for functions. + +## Recursion +A function can call itself, which is known as recursion. It's useful for solving problems that can be broken down into smaller subproblems. + +### Example: +```C +int factorial(int n) { + if (n == 0) { + return 1; // Base case + } + return n * factorial(n - 1); // Recursive case +} +``` + +## Summary +- Functions are reusable blocks of code that perform specific tasks. +- They can accept parameters and return values. +- Functions can be standard library functions or user-defined functions. +Recursion allows functions to call themselves. diff --git a/docs/sortings/Sortings.md b/docs/sortings/Sortings.md new file mode 100644 index 000000000..5da7ddda1 --- /dev/null +++ b/docs/sortings/Sortings.md @@ -0,0 +1,683 @@ +--- +id: sortings +title: Sortings Data Structure +sidebar_label: Introduction to Sortings +description: 'Sorting algorithms are fundamental in computer science, used to arrange data in a particular order, typically ascending or descending. Various sorting techniques are designed to optimize performance based on factors like time complexity, space complexity.' +tags: [dsa, Sortings, Bubble sort, Insertion sort, Selection sort, Merge sort, Quick sort , C, Java, Heap Sort] +--- + +### Introduction to Sortings + +Sorting algorithms play a crucial role in organizing data for efficient access and manipulation. Different algorithms are optimized for various use cases based on their time complexity, space complexity, and stability. + +In this page we will learn about **Bubble Sort** , **Selection Sort** , **Insertion Sort** , **Merge Sort** and **Quick Sort**. + +### Bubble Sort + +Bubble sort is a simple, comparison-based sorting algorithm. It works by repeatedly stepping through the list, comparing adjacent elements, and swapping them if they are in the wrong order. This process is repeated until no more swaps are needed, indicating that the list is sorted. + +**Algorithm** + + - Start at the beginning of the array. + - Compare each pair of adjacent elements and then swap them if they are in the wrong order. + - Repeat the process for the entire list until no swaps are made during a pass. + +### Solution in C + ```c + #include + +// Function to display array elements +void display(int a[], int n) { + for (int i = 0; i < n; i++) { + printf("%d ", a[i]); + } + printf("\n"); +} + +// Function to perform bubble sort on an array +void bubble_sort(int a[], int n) { + int i, j, temp; + for (i = 1; i < n; i++) { + for (j = 0; j < n - i; j++) { + if (a[j] > a[j + 1]) { + temp = a[j]; + a[j] = a[j + 1]; + a[j + 1] = temp; + } + } + } + display(a, n); // Calling `display` after sorting +} + +int main() { + int a[] = {5, 2, 9, 1, 5, 6}; + int n = sizeof(a) / sizeof(a[0]); + bubble_sort(a, n); + return 0; +} + + ``` + +### Solution in Java +```java +import java.util.*; + +public class Main{ + + //function to print array + public static void printArray(int arr[]){ + for(int i=0; i arr[j+1]){ + //swap + int temp = arr[j]; + arr[j] = arr[j+1]; + arr[j+1] = temp; + } + } + } + + printArray(arr); + } +} +``` + +### Solution in JavaScript + +```javascript +// Function to print array +function printArray(arr) { + console.log(...arr); +} + +// Bubble sort function +function bubbleSort(arr) { + let n = arr.length; + for (let i = 0; i < n - 1; i++) { + // Loop to ignore sorted elements from previous iterations + for (let j = 0; j < n - i - 1; j++) { + if (arr[j] > arr[j + 1]) { + // Swap elements using destructuring + [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; + } + } + } + return arr; +} + +// Main function +function main() { + let arr = [7, 8, 3, 1, 2]; + + // Perform bubble sort + let sortedArr = bubbleSort(arr); + + // Print sorted array + printArray(sortedArr); +} + +// Call main function +main(); +``` + +**Time Complexity** + - **Worst Case**: O(n²) – when the array is sorted in reverse order. + - **Best Case**: O(n) – when the array is already sorted. + +**Space Complexity** + - O(1) – sorts the list in place without extra space. + +**Stability** + - Stable – equal elements remain in the same relative order after sorting. + +**Usage** + - Not used in practical applications due to its inefficiency, but useful for educational purposes. + +### Selection Sort + +Selection sort divides the array into a sorted and an unsorted region. It works by repeatedly selecting the smallest (or largest) element from the unsorted region and swapping it with the first unsorted element. This process continues until the entire array is sorted. + +**Algorithm** + + - Start at the beginning of the array. + - Find the minimum element from the unsorted portion of the array. + - Swap it with the first element in the unsorted portion and move forward. + - Repeat until the array is fully sorted. + +### Solution in C + ```text + void selection_sort(int a[],int n) + { + int i,j,k,temp,temper; + for(i=0;ia[j]) + { + k=j; + temp=a[j]; + } + if(k!=0){ + temper=a[i]; + a[i]=a[k]; + a[k]=temper; + } + } + display(a,n); + } + ``` + +### Solution in Java +```java +import java.util.*; + +public class Main{ + + //function to print array + public static void printArray(int arr[]){ + for(int i=0; i arr[j]){ + smallest = j; + } + } + //swapping after checking for each iteration + int temp = arr[smallest]; + arr[smallest] = arr[i]; + arr[i] = temp; + } + + printArray(arr); + } +} +``` + +**Time Complexity** + - **Worst Case**: O(n²) – as it performs n comparisons for each element. + - **Best Case**: O(n) – when the array is already sorted. + +**Space Complexity** + - O(1) – in-place sorting. + +**Stability** + - Unstable – equal elements may be swapped, changing their relative order. + +**Usage** + - Useful when memory space is limited due to its in-place nature. Not efficient for large datasets. + + +### Insertion Sort + +Insertion sort works similarly to how people arrange playing cards in their hands. It builds the sorted list one element at a time by inserting each new element into its proper position relative to the elements already sorted. + +**Algorithm** + + - Start at the beginning of the array. + - Assume the first element is sorted and pick the next element. + - Compare it to the elements in the sorted portion and shift elements larger than it to the right and insert the element in its correct position. + - Repeat until the array is fully sorted. + +### Solution in C + ```text + void insertion_sort(int a[],int n) + { + int i,j,temp; + for(i=1;i=0&&a[j]>temp;j--) + { + a[j+1]=a[j]; + a[j]=temp; + } + } + display(a,n); + } + ``` + +### Solution in Java +```java +import java.util.*; + +public class Main{ + + //function to print array + public static void printArray(int arr[]){ + for(int i=0; i= 0 && current < arr[j]){ + //element are pushed forward to make space for current element + arr[j+1] = arr[j]; + j--; + } + + //placement of current element after comparison has been done + arr[j+1] = current; + } + + printArray(arr); + } +} +``` +**Time Complexity** + - **Worst Case**: O(n²) – when the array is sorted in reverse order. + - **Best Case**: O(n) – when the array is already sorted. + +**Space Complexity** + - O(1) – in-place sorting. + +**Stability** + - Stable – maintains the relative order of equal elements. + +**Usage** + - Useful when memory space is limited due to its in-place nature. + - Efficient for small datasets or nearly sorted data. + - Commonly used in hybrid algorithms like Timsort. + +### Merge Sort + +Merge sort is a divide-and-conquer algorithm. It splits the array into two halves, recursively sorts each half, and then merges the sorted halves to produce the sorted array. + +**Algorithm** + + - Start at the beginning of the array. + - Divide the array into two halves. + - Recursively sort each half and merge the sorted halves into a single sorted array. + - Repeat until the array is fully sorted. + +### Solution in C + ```text + + //fUNCTION FOR MERGING + + void merge(int a[],int l,int mid,int u) + { + int i=l; + int j=mid+1; + int x=0; + int c[10]; + while(i<=mid&&j<=u) + { + if(a[i]<=a[j]) + { + c[x]=a[i]; + i++; + x++; + } + else + { + c[x]=a[j]; + j++; + x++; + } + } + while(i<=mid) + { + c[x]=a[i]; + i++;x++; + } + while(j<=u) + { + c[x]=a[j]; + j++;x++; + } + for(i=0,j=l;i= ei){ //either single element left or reached end of array + return; + } + int mid = si + (ei - si) / 2; // (si+ei)/2 might give TC for larger test cases + divide(arr, si, mid); + divide(arr, mid+1, ei); + + conquer(arr, si, mid, ei); + } + + public static void main(String[] args){ + int[] arr = {6, 3, 9, 5, 2, 8}; + int n = arr.length; + + divide(arr, 0, n-1); + for(int i=0; ipi); + if(i arr[largest]) + largest = left; + + if (right < n && arr[right] > arr[largest]) + largest = right; + + if (largest != i) { + swap(&arr[i], &arr[largest]); + heapify(arr, n, largest); + } +} + +// HEAP SORT FUNCTION +void heapSort(int arr[], int n) { + for (int i = n / 2 - 1; i >= 0; i--){ + heapify(arr, n, i); + } + + for (int i = n - 1; i > 0; i--) { + swap(&arr[0], &arr[i]); + heapify(arr, i, 0); + } +} + +// FUNCTION TO SWAP TWO ELEMENTS +void swap(int* a, int* b) { + int temp = *a; + *a = *b; + *b = temp; +} +``` + +**Time Complexity** +O(n log n) – consistently for all cases. + +**Space Complexity** +O(1) – in-place sorting, no extra space required. + +**Stability** +Unstable – the relative order of equal elements may change. + +**Usage** +Used in applications where a guarantee of O(n log n) time is necessary and space is limited. + +### Conclusion + +Choosing the right sorting algorithm ensures optimal performance, especially in applications involving large datasets or time-sensitive operations. Understanding these techniques allows developers to make informed decisions and write efficient code for a variety of sorting tasks. + +When implementing sorting in C, the standard library provides built-in functions like qsort() in stdlib.h, or you can create custom algorithms depending on the requirements. diff --git a/docusaurus.config.js b/docusaurus.config.js new file mode 100644 index 000000000..95a72f1bf --- /dev/null +++ b/docusaurus.config.js @@ -0,0 +1,230 @@ +import { themes as prismThemes } from "prism-react-renderer"; +// import remarkPlugin from 'remark-plugin'; +import remarkMath from "remark-math"; +import rehypeKatex from "rehype-katex"; +const path = require("path"); + +/** @type {import('@docusaurus/types').Config} */ +const config = { + title: "Algo", + tagline: "Algo Mastery for Every Learner", + favicon: "logo/algo-3.png", + + url: "https://ajay-dhangar.github.io", + baseUrl: "/algo/", + organizationName: "codeharborhub", + projectName: "algo", + + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "warn", + + presets: [ + [ + "classic", + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + debug: true, + docs: { + sidebarPath: "./sidebars.js", + editUrl: + "https://github.com/ajay-dhangar/algo/tree/main/packages/create-docusaurus/templates/shared/", + remarkPlugins: [remarkMath], + rehypePlugins: [rehypeKatex], + showLastUpdateAuthor: true, + showLastUpdateTime: true, + }, + blog: { + showReadingTime: true, + editUrl: + "https://github.com/ajay-dhangar/algo/tree/main/packages/create-docusaurus/templates/shared/", + remarkPlugins: [remarkMath], + rehypePlugins: [rehypeKatex], + }, + theme: { + customCss: "./src/css/custom.css", + }, + }), + ], + ], + + stylesheets: [ + { + href: "https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css", + type: "text/css", + integrity: + "sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM", + crossorigin: "anonymous", + }, + ], + + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + image: "/", + announcementBar: { + id: "announcementBar", + content: + '📢 Join our
    WhatsApp Channel for the latest updates and collaboration on exciting projects!', + isCloseable: true, + backgroundColor: "var(--docusaurus-highlighted-code-line-bg)", + }, + + algolia: { + apiKey: "865d7bd9906f532b1d8cb5cc0f02b383", + indexName: "ajay-dhangario", + appId: "T0I3F584D5", + contextualSearch: false, + }, + + navbar: { + title: "Algo", + logo: { + alt: "Algo Logo", + src: "logo/algo.png", + }, + items: [ + { + type: "docSidebar", + sidebarId: "tutorialSidebar", + position: "left", + label: "Tutorial", + }, + { + to: "blog", + label: "Blog", + position: "left", + }, + { + to: "faq", + label: "FAQ", + position: "left", + }, + { + to: "dsa-roadmap", + label: "Pick Topic For Contribution", + position: "left", + }, + { + to: "contributors", + label: "Contributors", + position: "left", + }, + { + type: "dropdown", + label: "More", + position: "right", + items: [ + { + to: "dsa-interview", + label: "Top DSA Questions", + }, + { + to: "roadmap", + label: "Roadmap", + }, + { + to: "challenges", + label: "Challenges", + }, + { + to: "practice", + label: "Practice", + }, + { + to: "quizes", + label: "Quizes", + }, + { + to: "quiz-solutions", + label: "Quizzes Solutions", + }, + { + to: "leaderboard", + label: "Leaderboard", + }, + { + to: "community", + label: "Community", + }, + { + to: "resources", + label: "Resources", + }, + { + to: "blogs", + label: "Blogs", + }, + ], + }, + { + href: "https://github.com/ajay-dhangar/algo", + label: "GitHub", + position: "right", + }, + { + type: "search", + position: "right", + }, + ], + }, + footer: { + style: "dark", + links: [ + { + title: "Docs", + items: [ + { + label: "Tutorial", + to: "/docs/", + }, + ], + }, + ], + logo: { + alt: "Ajay Dhangar", + src: "/logo/ft-copy.png", + href: "https://github.com/ajay-dhangar", + }, + copyright: `Copyright © ${new Date().getFullYear()} Algo, Inc. Built with Docusaurus.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + additionalLanguages: [ + 'java', + 'latex', + 'haskell', + 'matlab', + 'PHp', + 'powershell', + 'bash', + 'diff', + 'json', + 'scss', + ], + }, + docs: { + sidebar: { + hideable: true, + }, + }, + }), + + themes: ["@docusaurus/theme-mermaid"], + markdown: { + mermaid: true, + }, + + plugins: [ + [ + path.join(__dirname, "/plugins/my-plugin",), + { + settings: "Some20settings", + api: "Some-API", + keys: "Some-keys", + }, + ], + ], +}; + +export default config; diff --git a/festhack.jpg b/festhack.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b21082df1c225519f7bf8d72ebde4d93ad21cca GIT binary patch literal 194570 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

    JMG1%gw}uR`|+6psgnBAey;?c-_w&etBlNYsRd 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 TS|8tqbhJ(iMgjx~KM(#N+AQ}6 literal 0 HcmV?d00001 diff --git a/girlscript.jpg b/girlscript.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ab4b58dbc8e637a8626a1428b77d2364c53a2dcc GIT binary patch literal 16124 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 literal 0 HcmV?d00001 diff --git a/java/Armstrong-Number-Checker.md b/java/Armstrong-Number-Checker.md new file mode 100644 index 000000000..d485639c3 --- /dev/null +++ b/java/Armstrong-Number-Checker.md @@ -0,0 +1,61 @@ +--- +id: Armstrong-Number-Checker +sidebar_position: 3 +title: Armstrong Number Checker +sidebar_label: Armstrong Number Checker +description: "This document explains the implementation of an Armstrong number checker in Java, detailing its description, approach, and implementation." +tags: [java, numbers, armstrong-number, checker] +--- +# Armstrong Number Checker + +## Description +An Armstrong number (or Narcissistic number) is a number that is equal to the sum of its own digits each raised to the power of the number of digits. For example, 153 is an Armstrong number because 1^3+5^3+3^3=153. This program verifies whether a given number is an Armstrong number. + +## Approach +The approach involves iterating through each digit of the number, raising it to the power of the total number of digits, and summing these values. If the sum matches the original number, it is an Armstrong number. + +## Steps: +1.**Calculate the Number of Digits**: +-Convert the number to a string or use a loop to count the digits. +2.**Compute the Armstrong Sum**: +-For each digit in the number, raise it to the power of the number of digits and add it to a cumulative sum. +3.**Comparison**: +-Check if the computed sum is equal to the original number. If yes, the number is an Armstrong number; otherwise, it is not. + +## Java Implementation +'''java +import java.util.Scanner; + +public class ArmstrongNumberChecker { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + System.out.print("Enter a number: "); + int number = scanner.nextInt(); + int originalNumber = number; + int digits = String.valueOf(number).length(); + int sum = 0; + + while (number > 0) { + int digit = number % 10; + sum += Math.pow(digit, digits); + number /= 10; + } + + if (sum == originalNumber) { + System.out.println(originalNumber + " is an Armstrong number."); + } else { + System.out.println(originalNumber + " is not an Armstrong number."); + } + } +} +''' +## Complexity Analysis +**Time Complexity**: +O(d) — where d is the number of digits in the input number, as each digit is processed once. + +**Space Complexity**: +O(1) — only a few variables are used for storage. + +## Conclusion +In this document, we implemented an Armstrong number checker that determines whether a given integer is an Armstrong number. This program has efficient constant space usage and linear time complexity relative to the number of digits in the number, making it well-suited for checking small to moderately large integers. \ No newline at end of file diff --git a/java/Arrays/1.Easy/Find missing number.md b/java/Arrays/1.Easy/Find missing number.md new file mode 100644 index 000000000..fbf4c768b --- /dev/null +++ b/java/Arrays/1.Easy/Find missing number.md @@ -0,0 +1,98 @@ +--- +id: find-missing-number +title: Find the Missing Number in Array +sidebar_label: Find Missing Number in Array +sidebar_position: 1 +description: Find the missing number in an array of size N containing numbers from 1 to N. +tags: [Array, XOR, DSA] +--- + +# Problem Statement +You are given an array `a` of size `N-1` containing numbers from `1` to `N`. The array has one number missing. Find the missing number. + +[LeetCode Problem Link](https://leetcode.com/problems/missing-number/description/) + +--- + +## Examples + +**Example 1**: +Input: +`a = [1, 2, 4, 5]`, `N = 5` + +Output: +`3` + +Explanation: +Numbers between `1` to `N` are `[1, 2, 3, 4, 5]`. The missing number is `3`. + +--- + +**Example 2**: +Input: +`a = [2, 3, 4, 5]`, `N = 5` + +Output: +`1` + +Explanation: +Numbers between `1` to `N` are `[1, 2, 3, 4, 5]`. The missing number is `1`. + +--- + +## Intuition +This problem can be solved using the properties of XOR: +1. **Property 1**: XOR of two identical numbers is always 0 (`a ^ a = 0`). +2. **Property 2**: XOR of a number with 0 results in the number itself (`0 ^ a = a`). + +### Key Idea: +- XOR all the numbers from `1` to `N`, which results in `xor1 = 1 ^ 2 ^ ... ^ N`. +- XOR all the elements in the array `a[]`, which results in `xor2 = 1 ^ 2 ^ ... ^ N` (excluding the missing number). +- The result of `xor1 ^ xor2` will cancel out all the numbers except the missing one, as explained by the XOR properties. Hence, `missing number = xor1 ^ xor2`. + +--- + +## Approach +1. Initialize two variables `xor1` and `xor2` to 0. +2. XOR all the numbers from `1` to `N` and store the result in `xor1`. +3. XOR all the elements of the array and store the result in `xor2`. +4. XOR the values of `xor1` and `xor2`. The result will be the missing number. + +--- + +## Java Implementation + +```java +import java.util.*; + +public class FindMissingNumber { + public static int missingNumber(int []a, int N) { + int xor1 = 0, xor2 = 0; + + for (int i = 0; i < N - 1; i++) { + xor2 = xor2 ^ a[i]; // XOR of array elements + xor1 = xor1 ^ (i + 1); // XOR up to [1...N-1] + } + xor1 = xor1 ^ N; // XOR up to [1...N] + + return (xor1 ^ xor2); // the missing number + } + + public static void main(String args[]) { + int N = 5; + int a[] = {1, 2, 4, 5}; + + int ans = missingNumber(a, N); + System.out.println("The missing number is: " + ans); + } +} +``` +--- +## Time Complexity +**Time Complexity**: `O(N)`, where N is the number of elements in the array. We only need to iterate over the array once to calculate the XORs. + +**Space Complexity**: `O(1)`, as we are only using a constant amount of extra space. + +--- +## Conclusion +Using XOR properties, we can find the missing number in linear time without using any extra space, making it an optimal solution for this problem. \ No newline at end of file diff --git a/java/Arrays/1.Easy/Remove Duplicates from Sorted Array.md b/java/Arrays/1.Easy/Remove Duplicates from Sorted Array.md new file mode 100644 index 000000000..aec67e5f4 --- /dev/null +++ b/java/Arrays/1.Easy/Remove Duplicates from Sorted Array.md @@ -0,0 +1,96 @@ +--- +id: remove-duplicates-sorted-array +title: Remove Duplicates in-place from Sorted Array +sidebar_label: Remove Duplicates in-place +sidebar_position: 1 +description: Given a sorted array, remove the duplicates in-place and return the new length. +tags: [Array, In-place, DSA] +--- + +# Remove Duplicates in-place from Sorted Array + +## Problem Statement +Given a sorted array `arr`, remove duplicates in-place such that each element appears only once and return the new length. The solution should modify the input array in-place and not use extra space. + +[LeetCode Problem Link](https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/) + +--- + +## Examples + +**Example 1**: +Input: +`arr = [1, 1, 2, 2, 2, 3, 3]` + +Output: +`arr = [1, 2, 3, _, _, _, _]` + +Explanation: +The unique elements are `[1, 2, 3]`, so the function returns `3` and places `[1, 2, 3]` at the start of the array. + +--- + +**Example 2**: +Input: +`arr = [1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4]` + +Output: +`arr = [1, 2, 3, 4, _, _, _, _, _, _, _]` + +Explanation: +The unique elements are `[1, 2, 3, 4]`, so the function returns `4` and places `[1, 2, 3, 4]` at the start of the array. + +--- + +## Approach +The problem can be solved using the two-pointer technique: + +1. Maintain two pointers, `i` and `j`, where `i` tracks the position of unique elements and `j` iterates over the array. +2. If the element at index `j` is different from the element at index `i`, increment `i` and set `arr[i] = arr[j]`. +3. The new length of the array will be `i + 1`. + +### Steps: +- Initialize `i = 0` to track the first unique element. +- Traverse the array from `j = 1` to the end. +- If `arr[j]` is different from `arr[i]`, update `arr[i + 1]` with `arr[j]` and increment `i`. +- After the loop, the first `i + 1` elements of the array will be unique. + +--- + +## Java Implementation + +```java +import java.util.*; + +public class Main { + public static void main(String[] args) { + int arr[] = {1, 1, 2, 2, 2, 3, 3}; + int k = removeDuplicates(arr); + System.out.println("The array after removing duplicate elements is "); + for (int i = 0; i < k; i++) { + System.out.print(arr[i] + " "); + } + } + + static int removeDuplicates(int[] arr) { + int i = 0; + for (int j = 1; j < arr.length; j++) { + if (arr[i] != arr[j]) { + i++; + arr[i] = arr[j]; + } + } + return i + 1; + } +} +``` + +--- +## Time Complexity +**Time Complexity**: `O(n)`, where n is the length of the input array. We are using a single loop to traverse the array. + +**Space Complexity**: `O(1)`, since we are modifying the array in-place without using any extra space. + +--- +## Conclusion +This solution efficiently removes duplicates from a sorted array in-place using the two-pointer technique. It has a time complexity of `O(n)` and does not require extra space, making it optimal for large inputs. \ No newline at end of file diff --git a/java/Arrays/2.Medium/Kadane's Algorithm.md b/java/Arrays/2.Medium/Kadane's Algorithm.md new file mode 100644 index 000000000..68d24dca3 --- /dev/null +++ b/java/Arrays/2.Medium/Kadane's Algorithm.md @@ -0,0 +1,104 @@ +--- +id: kadanes-algorithm> +title: Kadane's Algorithm- Maximum Subarray Sum +sidebar_label: Maximum Subarray Sum +sidebar_position: 1 +description: Find the maximum sum of a contiguous subarray in an integer array. +tags: [Array, Dynamic Programming, Greedy, DSA] +--- + +# Kadane's Algorithm: Maximum Subarray Sum + +## Problem Statement +Given an integer array `arr`, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. + +[LeetCode Problem Link](https://leetcode.com/problems/maximum-subarray/description/) + +## Examples + +**Example 1**: +Input: +`arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4]` + +Output: +`6` + +Explanation: +The subarray `[4, -1, 2, 1]` has the largest sum = 6. + +--- + +**Example 2**: +Input: +`arr = [1]` + +Output: +`1` + +Explanation: +Array has only one element, which gives a positive sum of 1. + +--- + +## Intuition +The intuition behind **Kadane's Algorithm** is simple: a subarray with a negative sum will always reduce the sum of the total subarray, so it's better to discard such subarrays and reset the sum to 0 whenever the sum goes below 0. + +### Key Idea +- Iterate through the array and add elements to a running sum. +- If the sum becomes negative at any point, reset it to zero since no subarray with a negative sum is worth considering. +- Track the maximum sum encountered during the iteration. + +## Approach +1. Initialize two variables: `maxi` to store the maximum sum and `sum` to store the current subarray sum. +2. Iterate through the array: + - Add the current element to `sum`. + - If `sum` exceeds `maxi`, update `maxi`. + - If `sum` becomes negative, reset it to `0`. +3. Return `maxi` as the result. + +### Edge Case +In some scenarios, the question may mention that the sum of an empty subarray should be considered. In that case, compare `maxi` with `0` before returning the result, and ensure you return the larger value. + +## Java Implementation + +```java +import java.util.*; + +public class Main { + public static long maxSubarraySum(int[] arr, int n) { + long maxi = Long.MIN_VALUE; // maximum sum + long sum = 0; + + for (int i = 0; i < n; i++) { + sum += arr[i]; + if (sum > maxi) { + maxi = sum; + } + // If sum < 0: discard the sum calculated + if (sum < 0) { + sum = 0; + } + } + + return maxi; + } + + public static void main(String args[]) { + int[] arr = { -2, 1, -3, 4, -1, 2, 1, -5, 4}; + int n = arr.length; + long maxSum = maxSubarraySum(arr, n); + System.out.println("The maximum subarray sum is: " + maxSum); + } +} + +``` + +--- +## Time Complexity +The **Time complexity** of Kadane's Algorithm is `O(n)`, where n is the number of elements in the array. This is because we make a single pass through the array to calculate the maximum subarray sum. + +**Space Complexity**: `O(1)` as we are not using any extra space. + +--- +## Conclusion +Kadane's Algorithm efficiently finds the maximum subarray sum in linear time, making it a powerful technique for solving problems related to contiguous subarrays. The algorithm's simplicity and effectiveness make it a staple in competitive programming and interviews. \ No newline at end of file diff --git a/java/Arrays/2.Medium/Longest Subarray with sum K.md b/java/Arrays/2.Medium/Longest Subarray with sum K.md new file mode 100644 index 000000000..8f66e0f22 --- /dev/null +++ b/java/Arrays/2.Medium/Longest Subarray with sum K.md @@ -0,0 +1,122 @@ +--- +id: longest-subarray-sum-k +title: Find Longest Subarray with Sum k +sidebar_label: Longest Subarray with Sum k +sidebar_position: 1 +description: Find the length of the longest subarray whose sum equals k. +tags: [Array, Hashing, DSA] +--- + +# Problem Statement +Given an array `a[]` and an integer `k`, find the length of the longest subarray that sums to `k`. + +[LeetCode Problem Link](https://leetcode.com/problems/subarray-sum-equals-k/) + +## Examples + +**Example 1**: +Input: +`N = 3, k = 5, array[] = {2, 3, 5}` + +Output: +`2` + +Explanation: +The longest subarray with sum `5` is `{2, 3}`. Its length is `2`. + +--- + +**Example 2**: +Input: +`N = 3, k = 1, array[] = {-1, 1, 1}` + +Output: +`3` + +Explanation: +The longest subarray with sum `1` is `{-1, 1, 1}`. Its length is `3`. + +--- + +## Intuition +To solve this problem optimally, we can use the concept of **prefix sum** combined with **hashing**. + +### Key Idea: +- Maintain a map to store the prefix sum and its corresponding index. +- As we iterate through the array, calculate the prefix sum up to each index. +- Check if the prefix sum equals `k`. If yes, update the maximum subarray length. +- Also, check if there is a prefix sum equal to `sum - k` (the remaining sum required to get `k` from the current subarray). If such a sum exists, calculate the length of the subarray and update the maximum length accordingly. +- Store the prefix sum and its earliest occurrence in the map to maximize the subarray length. + +--- + +## Approach +1. Declare a HashMap `preSumMap` to store prefix sums and their corresponding indices. +2. Initialize variables `sum = 0` (to store the running prefix sum) and `maxLen = 0` (to store the length of the longest subarray with sum `k`). +3. Iterate through the array. For each element: + - Add the current element to `sum` (prefix sum up to that index). + - If the sum is equal to `k`, update `maxLen` to `i + 1` (the length from the start). + - Check if `sum - k` exists in the map. If yes, update `maxLen` with the length of the subarray `i - preSumMap[sum - k]`. + - Add the current `sum` to the map if it doesn't already exist (to store the earliest occurrence of the prefix sum). +4. Return `maxLen`, which stores the length of the longest subarray with sum `k`. + +--- + +## Java Implementation + +```java +import java.util.*; + +public class tUf { + public static int getLongestSubarray(int[] a, int k) { + int n = a.length; // size of the array. + Map preSumMap = new HashMap<>(); + int sum = 0; + int maxLen = 0; + + for (int i = 0; i < n; i++) { + // calculate the prefix sum till index i: + sum += a[i]; + + // if the sum = k, update the maxLen: + if (sum == k) { + maxLen = Math.max(maxLen, i + 1); + } + + // calculate the sum of remaining part i.e. x-k: + int rem = sum - k; + + // calculate the length and update maxLen: + if (preSumMap.containsKey(rem)) { + int len = i - preSumMap.get(rem); + maxLen = Math.max(maxLen, len); + } + + // finally, update the map checking the conditions: + if (!preSumMap.containsKey(sum)) { + preSumMap.put(sum, i); + } + } + + return maxLen; + } + + public static void main(String[] args) { + int[] a = {-1, 1, 1}; + int k = 1; + int len = getLongestSubarray(a, k); + System.out.println("The length of the longest subarray is: " + len); + } +} + +``` + +--- +## Time Complexity +**Time Complexity**: `O(N)`, where N is the number of elements in the array. We process each element only once. + +**Space Complexity**: `O(N)`, as we are using a HashMap to store the prefix sums. + +--- +## Conclusion +Using a hash map to store prefix sums allows us to efficiently find the longest subarray with sum k in linear time. \ No newline at end of file diff --git a/java/Arrays/3.Hard/Maximum Product Subarray.md b/java/Arrays/3.Hard/Maximum Product Subarray.md new file mode 100644 index 000000000..92d596ccf --- /dev/null +++ b/java/Arrays/3.Hard/Maximum Product Subarray.md @@ -0,0 +1,85 @@ +--- +id: maximum-product-subarray +title: Maximum Product Subarray in an Array +sidebar_label: Maximum Product Subarray +sidebar_position: 1 +description: Find the maximum product of a contiguous subarray within an array containing both negative and positive integers. +tags: [Dynamic Programming, Array] +--- + +# Problem Statement +Given an array that contains both negative and positive integers, find the maximum product subarray. + +**LeetCode Problem Link**: [Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/description/) + +## Examples + +**Example 1**: +Input: +`Nums = [1, 2, 3, 4, 5, 0]` +Output: +`120` +**Explanation**: +In the given array, we can see `1 × 2 × 3 × 4 × 5` gives the maximum product value. + +--- + +**Example 2**: +Input: +`Nums = [1, 2, -3, 0, -4, -5]` +Output: +`20` +**Explanation**: +In the given array, we can see `(-4) × (-5)` gives the maximum product value. + +--- + +## Approach +The following approach is motivated by Kadane’s algorithm. The key insight is that we can obtain the maximum product from the product of two negative numbers as well. + +### Steps: +1. Initially, store the value at the 0th index in `prod1`, `prod2`, and `result`. +2. Traverse the array starting from the 1st index. +3. For each element: + - Update `prod1` to be the maximum of the current element, the product of the current element and `prod1`, and the product of the current element and `prod2`. + - Update `prod2` to be the minimum of the current element, the product of the current element and `prod1`, and the product of the current element and `prod2`. +4. Return the maximum of `result` and `prod1`. + +## Java Implementation + +```java +import java.util.*; + +public class Main { + static int maxProductSubArray(int arr[]) { + int prod1 = arr[0], prod2 = arr[0], result = arr[0]; + + for (int i = 1; i < arr.length; i++) { + int temp = Math.max(arr[i], Math.max(prod1 * arr[i], prod2 * arr[i])); + prod2 = Math.min(arr[i], Math.min(prod1 * arr[i], prod2 * arr[i])); + prod1 = temp; + + result = Math.max(result, prod1); + } + + return result; + } + + public static void main(String[] args) { + int nums[] = {1, 2, -3, 0, -4, -5}; + int answer = maxProductSubArray(nums); + System.out.print("The maximum product subarray is: " + answer); + } +} + +``` + +--- +## Time Complexity +The **Time complexity** of this algorithm is `O(n)`, where n is the number of elements in the input array. We traverse the array once to calculate the maximum product. + +The **Space complexity** is `O(1)` since we are using only a constant amount of space for variables. + +--- +## Conclusion +This approach efficiently finds the maximum product subarray by leveraging the properties of positive and negative integers. It maintains both the maximum and minimum products at each step, allowing it to handle negative values effectively. This solution is optimal in terms of both time and space complexity, making it suitable for large input sizes. \ No newline at end of file diff --git a/java/Arrays/3.Hard/Reverse pairs.md b/java/Arrays/3.Hard/Reverse pairs.md new file mode 100644 index 000000000..828d5c762 --- /dev/null +++ b/java/Arrays/3.Hard/Reverse pairs.md @@ -0,0 +1,139 @@ +--- +id: reverse-pairs +title: Count Reverse Pairs +sidebar_label: Count Reverse Pairs +sidebar_position: 1 +description: Count the number of reverse pairs in an array where i is less than j and the element at index i is greater than twice the element at index j. +tags: [Merge Sort, Array] +--- + +# Problem Statement +Given an array of numbers, return the count of reverse pairs. Reverse Pairs are those pairs where `i < j` and `arr[i] > 2 * arr[j]`. + +**LeetCode Problem Link**: [Reverse Pairs](https://leetcode.com/problems/reverse-pairs/description/) + +## Examples + +### Example 1 +Input: +`N = 5, array[] = {1, 3, 2, 3, 1}` +Output: +`2` +**Explanation**: +The pairs are `(3, 1)` and `(3, 1)` as both satisfy the condition `arr[i] > 2 * arr[j]`. + +### Example 2 +Input: +`N = 4, array[] = {3, 2, 1, 4}` +Output: +`1` +**Explanation**: +There is only 1 pair `(3, 1)` that satisfies the condition `arr[i] > 2 * arr[j]`. + +## Approach + +The problem can be solved using a modified **Merge Sort** approach, similar to the inversion count problem but with a change in the condition. The idea is to: +1. **Merge** the sorted halves. +2. **Count pairs** where `arr[i] > 2 * arr[j]` using two pointers during the merge step. +3. Merge sort ensures that both halves are sorted, making it efficient to count valid pairs. + +### Steps +1. Implement a **modified merge sort** where: + - During the merge process, count valid pairs by iterating through the left and right halves. + - For each element in the left half, count how many elements in the right half satisfy the condition. +2. After counting the pairs, merge the two halves back into the original array. + +## Java Implementation + +```java +import java.util.*; + +public class CountReversePairs { + + // Merges two sorted halves and counts reverse pairs + private static void merge(int[] arr, int low, int mid, int high) { + ArrayList temp = new ArrayList<>(); + int left = low; + int right = mid + 1; + + // Merge two halves in sorted order + while (left <= mid && right <= high) { + if (arr[left] <= arr[right]) { + temp.add(arr[left]); + left++; + } else { + temp.add(arr[right]); + right++; + } + } + + // If there are remaining elements in the left half + while (left <= mid) { + temp.add(arr[left]); + left++; + } + + // If there are remaining elements in the right half + while (right <= high) { + temp.add(arr[right]); + right++; + } + + // Transfer all elements from temp back to arr + for (int i = low; i <= high; i++) { + arr[i] = temp.get(i - low); + } + } + + // Counts pairs where arr[i] > 2 * arr[j] in two sorted halves + public static int countPairs(int[] arr, int low, int mid, int high) { + int right = mid + 1; + int cnt = 0; + for (int i = low; i <= mid; i++) { + while (right <= high && arr[i] > 2 * arr[right]) right++; + cnt += (right - (mid + 1)); + } + return cnt; + } + + // Recursive merge sort with modification to count reverse pairs + public static int mergeSort(int[] arr, int low, int high) { + int cnt = 0; + if (low >= high) return cnt; + int mid = (low + high) / 2 ; + cnt += mergeSort(arr, low, mid); // left half + cnt += mergeSort(arr, mid + 1, high); // right half + cnt += countPairs(arr, low, mid, high); // Count reverse pairs + merge(arr, low, mid, high); // Merge sorted halves + return cnt; + } + + // Main function that triggers the merge sort + public static int reversePairs(int[] arr, int n) { + return mergeSort(arr, 0, n - 1); + } + + public static void main(String[] args) { + int[] array = {4, 1, 2, 3, 1}; + int n = 5; + int count = reversePairs(array, n); + System.out.println("The number of reverse pairs is: " + count); + } +} + +``` + +--- +## Time Complexity +The **Time complexity** is O(N log N), where N is the size of the array. + +**Merge Sort**: Recursively divides the array, which takes O(log N). +**Counting pairs**: For each split, the counting process takes O(N). + +Thus, the total time complexity is `O(N log N)`. + +**Space Complexity**: The space complexity is `O(N)` because of the temporary array used to store the merged elements. + +--- +## Conclusion +This problem is a modification of the inversion count problem, with the condition `arr[i] > 2 * arr[j].` The approach uses merge sort to efficiently count such pairs in `O(N log N)` time. This is optimal for large arrays and ensures that the problem can be solved within reasonable time limits. \ No newline at end of file diff --git a/java/LCM-GCD-Calculator.md b/java/LCM-GCD-Calculator.md new file mode 100644 index 000000000..f0091eeaa --- /dev/null +++ b/java/LCM-GCD-Calculator.md @@ -0,0 +1,72 @@ +--- +id: LCM-GCD-Calculator +sidebar_position: 4 +title: LCM and GCD Calculator +sidebar_label: LCM and GCD Calculator +description: "This document details the implementation of a Java program to calculate the Least Common Multiple (LCM) and Greatest Common Divisor (GCD) of two numbers, along with explanations for the approach and implementation." +tags: [java, math, gcd, lcm, calculator] +--- +### LCM and GCD Calculator +## Description +This program calculates the Greatest Common Divisor (GCD) and Least Common Multiple (LCM) of two user-provided numbers. The GCD of two numbers is the largest number that divides both, and the LCM is the smallest number divisible by both. + +## Approach +To find the GCD, the Euclidean algorithm is used, which is efficient and based on the principle that GCD(a, b) = GCD(b, a % b). The LCM is then calculated using the relation: +LCM(a,b)= ∣a×b∣/GCD(a,b) + +## ​Steps: +1.**Input Validation**: +-Ensure both numbers are valid integers. +2.**Calculate GCD using the Euclidean Algorithm**: +-Use a loop to find the GCD based on repeated modulo operations until one of the numbers becomes zero. +3.**Calculate LCM**: +-Use the GCD to compute the LCM using the formula above. +4.**Output**: +-Display the GCD and LCM results. + +## Java Implementation +'''java +import java.util.Scanner; + +public class LCMandGCDCalculator { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + System.out.print("Enter first number: "); + int num1 = scanner.nextInt(); + + System.out.print("Enter second number: "); + int num2 = scanner.nextInt(); + + int gcd = findGCD(num1, num2); + int lcm = (num1 * num2) / gcd; + + System.out.println("GCD: " + gcd); + System.out.println("LCM: " + lcm); + } + + public static int findGCD(int a, int b) { + while (b != 0) { + int temp = b; + b = a % b; + a = temp; + } + return a; + } +} +''' +## Complexity Analysis +**Time Complexity**: +O(log(min(a, b))) — The Euclidean algorithm is efficient, with logarithmic time complexity based on the smaller of the two numbers. + +**Space Complexity**: +O(1) — Only a few variables are used for intermediate calculations. + +## Conclusion +This document details an LCM and GCD calculator that leverages the Euclidean algorithm for GCD calculation and uses it to compute the LCM. The program is efficient with logarithmic time complexity, making it suitable for calculating GCD and LCM for moderately large integers. + + + + + + diff --git a/java/Palindrome_number.md b/java/Palindrome_number.md new file mode 100644 index 000000000..743f42259 --- /dev/null +++ b/java/Palindrome_number.md @@ -0,0 +1,80 @@ +--- +id: Palindrome_number +sidebar_position: 1 +title:check palindrome number. +sidebar_label:palindrom number. +description: "This document explains the check is it Palindrome or not , including its description, approach, and implementation." +tags: [java, problem-solving] +--- + +# Palindrome number. + +## Description +Given a number , check is it palindrome or not , and return answer in boolean. Palindrome is when we read it from left to right and right to left it same. ex-121. + +## Approach + +rev = rev * 10 + (x % 10); + +This expression shifts the current value of rev one decimal place to the left by multiplying it by 10. +The last digit of x is extracted using x % 10 (modulus operation). +The last digit is then added to rev. +Modulo operator (%) is used to extract the last digit of the number. +division (/) is used to remove the last digit of the number. +Palindrome property: A number is a palindrome if it reads the same forward and backward. + +### Steps: + +1. **Initialize**: + - initialize the rev 0 for storing the value in reverse order. + +2. **Iterate**: + - by using % operator we get last digit and store it. + - by multiply by 10 and store last digit we get the number in reverse format. + - divide by 10 so that last digit get remove. + +3. **Return**: + - original digit is equal to rev. + +## java Implementation + + +```java + +public class Palindrome_number { + public static void main(String[] args) { + Palindrome_number obj = new Palindrome_number(); + boolean ans = obj.palindrome(121); + System.out.println(ans); + } + + public boolean palindrome(int num) { + if(num<0){ //if number is less than zero then return false; + return false; + } + int rev=0; //define a varible rev. for reveses number. + int original=num; //redefined the value of num. + while(num>0){ //while loop upto the num greater than 0 + rev=rev*10+num%10; //this is logic for reverse the number. + num=num/10; //last digit deleted. + } + return rev==original; // check + } + +} +``` + + + +** 👉🏻👉🏻👉🏻 time complexity=constant. O(1)** +👉🏻👉🏻👉🏻spacd complexity=constant. O(1); + +** 👉🏻👉🏻👉🏻 logic.-** +(rev = rev * 10 + x % 10; and x = x / 10;) +Modulo operator (%) is used to extract the last digit of the number. + division (/) is used to remove the last digit of the number. +Palindrome property: A number is a palindrome if it reads the same forward and backward. + +## Conclusion + +In this article, we learned about the Palindrome in number . Palindroem is a when you read from left to right and right to left is same that basically a palindrome. The time complexit is O(n) and the space complexity is O(1).. \ No newline at end of file diff --git a/java/Palindrome_string.md b/java/Palindrome_string.md new file mode 100644 index 000000000..27176d826 --- /dev/null +++ b/java/Palindrome_string.md @@ -0,0 +1,75 @@ +--- +id: Palindrome_string +title: Palindroem string +sidebar_label: Palindrome string +description: "is a well knows problem help to buid concept." +tags: [java,dsa, algorithms,Problem solving] +--- + +# Game Theory + +**Palindrome string** +Given a String , check is it palindrome or not , and return answer in boolean. Palindrome is when we read it from left to right and right to left it same. ex-madam1. + +## Apporach + +### 1. ** Understand the Problem:** +- Identify what constitutes a palindrome. +-Recognize that the string should be identical when read from left to right and right to left. + +### 2. **Two-Pointer Technique:** +- This is an efficient method to check for palindromes. The idea is to use two pointers, one starting at the beginning of the string and the other at the end. +-By comparing characters at these pointers, you can determine if the string is a palindrome by progressively moving toward the center. + +- **Steps to Implement:**: + - **Initialize Pointers: +Set a pointer (left) at the start of the string (index 0). +Set another pointer (right) at the end of the string (index length - 1). + +-**Iterate and Compare:** +While the left pointer is less than the right pointer: +Compare the characters at both pointers. +If the characters are not equal, return false. +If they are equal, move the left pointer one step to the right (increment) and the right pointer one step to the left (decrement). + +-**Return Result:** +If the loop completes without finding any mismatches, return true, indicating the string is a palindrome. + + +## java Implementation + +```java + +public class Palindrome_string { + public static void main(String[] args) { + Palindrome_string obj = new Palindrome_string(); + boolean ans = obj.Palindrome_string("manad"); + System.out.println(ans); + } + + public boolean Palindrome_string(String str) { + int left=0; + int right =str.length()-1; // last character of string . + + while(left fruits = new ArrayList<>(); + ``` + +2. **Adding Elements:** + ```java + fruits.add("Apple"); + fruits.add("Banana"); + fruits.add("Orange"); + ``` + +3. **Accessing Elements:** + ```java + String firstFruit = fruits.get(0); + ``` + +4. **Removing Elements:** + ```java + fruits.remove(1); // Removes the element at index 1 + ``` + +5. **Iterating Over Elements:** + ```java + for (String fruit : fruits) { + System.out.println(fruit); + } + ``` + +**Common Methods:** + +* **`add(E element)`:** Adds an element to the end of the list. +* **`add(int index, E element)`:** Inserts an element at a specific index. +* **`remove(int index)`:** Removes the element at a specific index. +* **`remove(Object o)`:** Removes the first occurrence of the specified object. +* **`get(int index)`:** Returns the element at a specific index. +* **`size()`:** Returns the number of elements in the list. +* **`isEmpty()`:** Returns `true` if the list is empty. +* **`clear()`:** Removes all elements from the list. + +**Example:** + +```java +import java.util.ArrayList; + +public class ArrayListExample { + public static void main(String[] args) { + ArrayList numbers = new ArrayList<>(); + numbers.add(10); + numbers.add(20); + numbers.add(30); + + System.out.println("Size of the list: " + numbers.size()); + System.out.println("First element: " + numbers.get(0)); + + numbers.remove(1); // Remove the element at index 1 + + for (int number : numbers) { + System.out.println(number); + } + } +} +``` + +**Key Points to Remember:** + +* ArrayLists are dynamic and can grow or shrink as needed. +* They are zero-indexed, meaning the first element is at index 0. +* Consider using `ArrayList` when you need a dynamic list of objects and frequent insertion and deletion operations. +* For sequential access and faster iteration, consider using `LinkedList`. + +By understanding these concepts and methods, you can effectively utilize ArrayLists in your Java programs to manage collections of objects efficiently. diff --git a/java/fast-exponential.md b/java/fast-exponential.md new file mode 100644 index 000000000..3450a7fb7 --- /dev/null +++ b/java/fast-exponential.md @@ -0,0 +1,53 @@ +--- +id: fast-exponential +sidebar_position: 1 +title: Fast Exponential +sidebar_label: fast exponential +description: Fast exponentiation is a powerful technique for handling large exponents efficiently, commonly used in various computational and mathematical applications. Its ability to work in logarithmic time makes it indispensable for performance-critical systems. +tags: [java, problem-solving] +--- + +# Fast Exponential + +## Description: + +Fast Exponentiation is an algorithm to compute powers of numbers efficiently, typically used to calculate a^b%c. The common approach is Exponentiation by Squaring, which reduces the time complexity to $O(log n)$. + +**Key Points:** + +**1. Base and Modulo:** Initialize base to be within modulo. + +**2. Loop Until Exp is Zero:** + +> *Odd Exponent:* If exp is odd (exp & 1), multiply result by base and take modulo. + +> *Update Base and Exponent:* Square the base and halve the exp. + +**3. Return Result:** Final result after computing power modulo. + +## Efficiency: + +This algorithm runs in $O(log n)$ time, making it very efficient for large exponents. + +# Code in Java: + +```java +public class FastExpo { + + public static int fastExpo(int a, int n) { + int ans = 1; + + while(n>0) { + if((n&1) != 0) { + ans = ans*a; + } + a=a*a; + n=n>>1; + } + return ans; + } + public static void main(String[] args) { + System.out.println(fastExpo(2, 4)); + } +} +``` diff --git a/java/inheritance.md b/java/inheritance.md new file mode 100644 index 000000000..2d1c63b2f --- /dev/null +++ b/java/inheritance.md @@ -0,0 +1,90 @@ +--- +id: array-list +sidebar_position: 2 +title: Inheritance +sidebar_label: inheritance +description: Inheritance is a core concept in object-oriented programming (OOP) that allows you to create new classes (subclasses or child classes) that inherit properties and behaviors from existing classes (superclasses or parent classes). This promotes code reusability and helps in creating well-structured and maintainable software systems. +tags: [java, inheritance, class] +--- + +**Inheritance in Java** + +Inheritance is a core concept in object-oriented programming (OOP) that allows you to create new classes (subclasses or child classes) that inherit properties and behaviors from existing classes (superclasses or parent classes). This promotes code reusability and helps in creating well-structured and maintainable software systems. + +**Types of Inheritance** + +1. **Single Inheritance:** A class inherits from only one parent class. + ```java + class Animal { + public void eat() { + System.out.println("Animal is eating."); + } + } + + class Dog extends Animal { + public void bark() { + System.out.println("Dog is barking."); + } + } + ``` +2. **Hierarchical Inheritance:** Multiple classes inherit from a single parent class. + ```java + class Vehicle { + public void move() { + System.out.println("Vehicle is moving."); + } + } + + class Car extends Vehicle { + public void accelerate() { + System.out.println("Car is accelerating."); + } + } + + class Bike extends Vehicle { + public void brake() { + System.out.println("Bike is braking."); + } + } + ``` +3. **Multilevel Inheritance:** A class inherits from a derived class. + ```java + class Shape { + public void draw() { + System.out.println("Shape is drawn."); + } + } + + class Rectangle extends Shape { + public void area() { + System.out.println("Rectangle area calculated."); + } + } + + class Square extends Rectangle { + public void sideLength() { + System.out.println("Square side length calculated."); + } + } + ``` + +**Key Points** + +* **`extends` keyword:** Used to establish an inheritance relationship. +* **Inheritance Hierarchy:** The chain of classes that inherit from each other. +* **Method Overriding:** Redefining a method in a subclass with the same signature as the parent class. +* **Method Overloading:** Defining multiple methods with the same name but different parameters in a class. + +**Benefits of Inheritance** + +* **Code Reusability:** Avoids redundant code by inheriting common properties and behaviors. +* **Modularity:** Encourages the creation of smaller, more focused classes. +* **Polymorphism:** Allows objects of different classes to be treated as objects of a common superclass. + +**Important Considerations** + +* **Access Modifiers:** Determine the visibility of class members. +* **Constructor Chaining:** Subclass constructors can call superclass constructors using the `super` keyword. +* **Object-Oriented Design Principles:** Follow SOLID principles for effective inheritance design. + +By understanding inheritance, you can create more efficient, flexible, and maintainable Java applications. diff --git a/java/isPowerOfTwo.md b/java/isPowerOfTwo.md new file mode 100644 index 000000000..7c779b26b --- /dev/null +++ b/java/isPowerOfTwo.md @@ -0,0 +1,44 @@ +--- +id: is-power-of-two +sidebar_position: 1 +title: check isPowerOfTwo +sidebar_label: Is power of two? +description: "In this we need to determine if a given integer is a power of two. An integer is a power of two if it can be written as 2^𝑛 where 𝑛 is a non-negative integer." +tags: [java, problem-solving] +--- + +# isPowerOfTwo +## Description: + +The isPowerOfTwo problem is a common question where we need to determine if a given integer is a power of two. An integer is a power of two if it can be written as 2^𝑛 where 𝑛 is a non-negative integer. + +## Approach + +To solve this problem, you can use bit manipulation, which is very efficient. The key observation here is that a number which is a power of two has exactly one bit set to 1 in its binary representation. + +## By Bit Manipulation +**1. Binary Check:** In binary, a power of two has a single '1' followed by zero or more '0's. +**2. Masking Trick:** For a number n, the condition n & (n - 1) will be zero if n is a power of two. + +# Code in Java + +```java +import java.util.*; + +public class isPowerOfTwo { + + public static boolean isPowerOfTwo(int n) { + return (n&(n-1)) == 0; + } + public static void main(String[] args) { + System.out.println(isPowerOfTwo(15)); + } +} +``` + +## Explanation: + +**Bitwise AND Operation:** +> n & (n - 1): This operation turns off the rightmost set bit of n. If n is a power of two, there will be exactly one set bit, so n & (n - 1) will be zero. + +**For example**, 16 in binary is 10000, and 15 is 01111. 16 & 15 = 00000. diff --git a/learn.md b/learn.md new file mode 100644 index 000000000..036e6ee4d --- /dev/null +++ b/learn.md @@ -0,0 +1,23 @@ +# Learn with Algo + +Algo is a comprehensive algorithm repository designed to help developers improve their problem-solving skills. Here's how you can get started and learn from this project: + +## Topics Covered +- Sorting Algorithms +- Searching Algorithms +- Dynamic Programming +- Greedy Algorithms +- Graph Algorithms +- Data Structures + +## How to Use This Repository +1. Clone the repository to your local machine. +2. Browse through the folders to find algorithms categorized by topics. +3. Each algorithm includes: + - A detailed description of the problem + - The solution code + - Time and space complexity analysis + +## Learning Resources +- We recommend starting with **Sorting Algorithms** if you're new to algorithms. +- Each algorithm file is documented with comments and explanations to help you understand the logic and steps involved. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..22fc8fbc2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,34303 @@ +{ + "name": "algo", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "algo", + "version": "0.0.0", + "dependencies": { + "@docusaurus/core": "^3.5.2", + "@docusaurus/plugin-content-blog": "^3.5.2", + "@docusaurus/plugin-content-docs": "^3.5.2", + "@docusaurus/plugin-debug": "^3.5.2", + "@docusaurus/preset-classic": "^3.5.2", + "@docusaurus/theme-mermaid": "^3.5.2", + "@docusaurus/theme-search-algolia": "^3.5.2", + "@fortawesome/free-brands-svg-icons": "^6.6.0", + "@fortawesome/react-fontawesome": "^0.2.2", + "@giscus/react": "^3.0.0", + "@heroicons/react": "^2.1.5", + "@mdx-js/react": "^3.0.0", + "axios": "^1.7.7", + "clsx": "^2.0.0", + "framer-motion": "^11.9.0", + "joi": "^17.13.3", + "mermaid": "^11.0.0", + "prism-react-renderer": "^2.1.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-icons": "^5.3.0", + "react-lite-youtube-embed": "^2.4.0", + "react-simple-chatbot": "^0.6.0", + "react-toastify": "^10.0.5", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", + "styled-components": "^4.4.1", + "swiper": "^11.1.14" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/types": "3.5.2", + "autoprefixer": "^10.4.20", + "gh-pages": "^6.1.0", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.13" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-account/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.7.0.tgz", + "integrity": "sha512-hrYlN9yNQukmNj8bBlw9PCXi9jmRQqNUXaG6MXH1aDabjO6YD1WPVqTvaELbIBgTbDJzCn0R2owms0uaxQkjUg==", + "peer": true, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-personalization/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.7.0.tgz", + "integrity": "sha512-0Frfjt4oxvVP2qsTQAjwdaG5SvJ3TbHBkBrS6M7cG5RDrgHqOrhBnBGCFT+YO3CeNK54r+d57oB1VcD2F1lHuQ==", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.7.0", + "@algolia/requester-browser-xhr": "5.7.0", + "@algolia/requester-fetch": "5.7.0", + "@algolia/requester-node-http": "5.7.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, + "node_modules/@algolia/logger-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" + }, + "node_modules/@algolia/logger-console": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", + "dependencies": { + "@algolia/logger-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.7.0.tgz", + "integrity": "sha512-ohtIp+lyTGM3agrHyedC3w7ijfdUvSN6wmGuKqUezrNzd0nCkFoLW0OINlyv1ODrTEVnL8PAM/Zqubjafxd/Ww==", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.7.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.7.0.tgz", + "integrity": "sha512-Eg8cBhNg2QNnDDldyK77aXvg3wIc5qnpCDCAJXQ2oaqZwwvvYaTgnP1ofznNG6+klri4Fk1YAaC9wyDBhByWIA==", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.7.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.7.0.tgz", + "integrity": "sha512-8BDssYEkcp1co06KtHO9b37H+5zVM/h+5kyesJb2C2EHFO3kgzLHWl/JyXOVtYlKQBkmdObYOI0s6JaXRy2yQA==", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.7.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", + "dependencies": { + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@antfu/install-pkg": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", + "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", + "dependencies": { + "package-manager-detector": "^0.2.0", + "tinyexec": "^0.3.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/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==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/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==" + }, + "node_modules/@babel/code-frame/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==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "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/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", + "dependencies": { + "@babel/types": "^7.23.4", + "@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-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "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==", + "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-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", + "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.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==", + "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==", + "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==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dependencies": { + "@babel/types": "^7.23.0" + }, + "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==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "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-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", + "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.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==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "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==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "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==", + "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==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", + "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.4", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "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/highlight/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/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==" + }, + "node_modules/@babel/highlight/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==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", + "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "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-async-generator-functions": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", + "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "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-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "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-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.3.tgz", + "integrity": "sha512-FGEQmugvAEu2QtgtU0uTASXevfLMFfBeVCIIdcQhn/uBQsMTjBajdnAtanQlOcuihWh10PZ7+HWvc7NtBwP74w==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "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-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "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-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", + "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", + "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-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "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-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "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-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", + "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "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-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", + "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "dependencies": { + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "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-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "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-constant-elements": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.7.tgz", + "integrity": "sha512-/qXt69Em8HgsjCLu7G3zdIQn7A2QwmYND7Wa0LTp09Na+Zn8L5d0A7wSXrKi18TJRc/Q5S1i1De/SU1LzVkSvA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", + "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "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": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", + "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "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-runtime": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.4.tgz", + "integrity": "sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "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-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "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-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "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-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "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-typescript": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.4.tgz", + "integrity": "sha512-39hCCOl+YUAyMOu6B9SmUTiHUU0t/CxJNUmY3qRdJujbqi+lrQcL11ysYUsAvFWPBdhihrv1z0oRG84Yr3dODQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "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-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.3.tgz", + "integrity": "sha512-ovzGc2uuyNfNAs/jyjIGxS8arOHS5FENZaNn4rtE7UdKMMkqHCvboHfcuhWLZNX5cB44QfcGNWjaevxMzzMf+Q==", + "dependencies": { + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.3", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.3", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.3", + "@babel/plugin-transform-classes": "^7.23.3", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.3", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.3", + "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.3", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.3", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.3", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.3", + "@babel/plugin-transform-numeric-separator": "^7.23.3", + "@babel/plugin-transform-object-rest-spread": "^7.23.3", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.3", + "@babel/plugin-transform-optional-chaining": "^7.23.3", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.3", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", + "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.23.3", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "node_modules/@babel/runtime": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", + "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.4.tgz", + "integrity": "sha512-zQyB4MJGM+rvd4pM58n26kf3xbiitw9MHzL8oLiBMKb8MCtVDfV5nDzzJWWzLMtbvKI9wN6XwJYl479qF4JluQ==", + "dependencies": { + "core-js-pure": "^3.30.2", + "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==", + "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.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", + "dependencies": { + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", + "@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.4", + "@babel/types": "^7.23.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@blakeembrey/deque": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@blakeembrey/deque/-/deque-1.0.5.tgz", + "integrity": "sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg==" + }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", + "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/css": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.2.tgz", + "integrity": "sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw==" + }, + "node_modules/@docsearch/react": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.2.tgz", + "integrity": "sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA==", + "dependencies": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.6.2", + "algoliasearch": "^4.19.1" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.5.2.tgz", + "integrity": "sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==", + "dependencies": { + "@babel/core": "^7.23.3", + "@babel/generator": "^7.23.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.22.9", + "@babel/preset-env": "^7.22.9", + "@babel/preset-react": "^7.22.5", + "@babel/preset-typescript": "^7.22.5", + "@babel/runtime": "^7.22.6", + "@babel/runtime-corejs3": "^7.22.6", + "@babel/traverse": "^7.22.8", + "@docusaurus/cssnano-preset": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.1.3", + "babel-plugin-dynamic-import-node": "^2.3.3", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "clean-css": "^5.3.2", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "copy-webpack-plugin": "^11.0.0", + "core-js": "^3.31.1", + "css-loader": "^6.8.1", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "del": "^6.1.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "html-minifier-terser": "^7.2.0", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.5.3", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "mini-css-extract-plugin": "^2.7.6", + "p-map": "^4.0.0", + "postcss": "^8.4.26", + "postcss-loader": "^7.3.3", + "prompts": "^2.4.2", + "react-dev-utils": "^12.0.1", + "react-helmet-async": "^1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "rtl-detect": "^1.0.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.5", + "shelljs": "^0.8.5", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "url-loader": "^4.1.1", + "webpack": "^5.88.1", + "webpack-bundle-analyzer": "^4.9.0", + "webpack-dev-server": "^4.15.1", + "webpack-merge": "^5.9.0", + "webpackbar": "^5.0.2" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.5.2.tgz", + "integrity": "sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.4.38", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.5.2.tgz", + "integrity": "sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.5.2.tgz", + "integrity": "sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^1.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.5.2.tgz", + "integrity": "sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==", + "dependencies": { + "@docusaurus/types": "3.5.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "*", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.5.2.tgz", + "integrity": "sha512-R7ghWnMvjSf+aeNDH0K4fjyQnt5L0KzUEnUhmf1e3jZrv3wogeytZNN6n7X8yHcMsuZHPOrctQhXWnmxu+IRRg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "reading-time": "^1.5.0", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.5.2.tgz", + "integrity": "sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.5.2.tgz", + "integrity": "sha512-kBK6GlN0itCkrmHuCS6aX1wmoWc5wpd5KJlqQ1FyrF0cLDnvsYSnh7+ftdwzt7G6lGBho8lrVwkkL9/iQvaSOA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^1.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.5.2.tgz", + "integrity": "sha512-rjEkJH/tJ8OXRE9bwhV2mb/WP93V441rD6XnM6MIluu7rk8qg38iSxS43ga2V2Q/2ib53PcqbDEJDG/yWQRJhQ==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.5.2.tgz", + "integrity": "sha512-lm8XL3xLkTPHFKKjLjEEAHUrW0SZBSHBE1I+i/tmYMBsjCcUB5UJ52geS5PSiOCFVR74tbPGcPHEV/gaaxFeSA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.5.2.tgz", + "integrity": "sha512-QkpX68PMOMu10Mvgvr5CfZAzZQFx8WLlOiUQ/Qmmcl6mjGK6H21WLT5x7xDmcpCoKA/3CegsqIqBR+nA137lQg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.5.2.tgz", + "integrity": "sha512-DnlqYyRAdQ4NHY28TfHuVk414ft2uruP4QWCH//jzpHjqvKyXjj2fmDtI8RPUBh9K8iZKFMHRnLtzJKySPWvFA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.5.2.tgz", + "integrity": "sha512-3ihfXQ95aOHiLB5uCu+9PRy2gZCeSZoDcqpnDvf3B+sTrMvMTr8qRUzBvWkoIqc82yG5prCboRjk1SVILKx6sg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/plugin-content-blog": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/plugin-content-pages": "3.5.2", + "@docusaurus/plugin-debug": "3.5.2", + "@docusaurus/plugin-google-analytics": "3.5.2", + "@docusaurus/plugin-google-gtag": "3.5.2", + "@docusaurus/plugin-google-tag-manager": "3.5.2", + "@docusaurus/plugin-sitemap": "3.5.2", + "@docusaurus/theme-classic": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-search-algolia": "3.5.2", + "@docusaurus/types": "3.5.2" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/preset-classic/node_modules/@docusaurus/plugin-content-pages": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", + "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.5.2.tgz", + "integrity": "sha512-XRpinSix3NBv95Rk7xeMF9k4safMkwnpSgThn0UNQNumKvmcIYjfkwfh2BhwYh/BxMXQHJ/PdmNh22TQFpIaYg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/plugin-content-blog": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/plugin-content-pages": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-translations": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.44", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.4.26", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/plugin-content-pages": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", + "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.5.2.tgz", + "integrity": "sha512-QXqlm9S6x9Ibwjs7I2yEDgsCocp708DrCrgHgKwg2n2AY0YQ6IjU0gAK35lHRLOvAoJUfCKpQAwUykB0R7+Eew==", + "dependencies": { + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.5.2.tgz", + "integrity": "sha512-7vWCnIe/KoyTN1Dc55FIyqO5hJ3YaV08Mr63Zej0L0mX1iGzt+qKSmeVUAJ9/aOalUhF0typV0RmNUSy5FAmCg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "mermaid": "^10.4.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/mermaid": { + "version": "10.9.3", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.3.tgz", + "integrity": "sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^6.0.1", + "@types/d3-scale": "^4.0.3", + "@types/d3-scale-chromatic": "^3.0.0", + "cytoscape": "^3.28.1", + "cytoscape-cose-bilkent": "^4.1.0", + "d3": "^7.4.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.10", + "dayjs": "^1.11.7", + "dompurify": "^3.0.5 <3.1.7", + "elkjs": "^0.9.0", + "katex": "^0.16.9", + "khroma": "^2.0.0", + "lodash-es": "^4.17.21", + "mdast-util-from-markdown": "^1.3.0", + "non-layered-tidy-tree-layout": "^2.0.2", + "stylis": "^4.1.3", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@docusaurus/theme-mermaid/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.5.2.tgz", + "integrity": "sha512-qW53kp3VzMnEqZGjakaV90sst3iN1o32PH+nawv1uepROO8aEGxptcq2R5rsv7aBShSRbZwIobdvSYKsZ5pqvA==", + "dependencies": { + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-translations": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "algoliasearch": "^4.18.0", + "algoliasearch-helper": "^3.13.3", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.5.2.tgz", + "integrity": "sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/types": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.5.2.tgz", + "integrity": "sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "^1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.5.2.tgz", + "integrity": "sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@svgr/webpack": "^8.1.0", + "escape-string-regexp": "^4.0.0", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/types": { + "optional": true + } + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.5.2.tgz", + "integrity": "sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==", + "dependencies": { + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/types": { + "optional": true + } + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.5.2.tgz", + "integrity": "sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "peer": 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/eslint-utils/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==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", + "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.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": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "peer": 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/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/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==", + "license": "MIT", + "peer": true + }, + "node_modules/@eslint/js": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", + "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", + "license": "MIT", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", + "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", + "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", + "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", + "peer": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz", + "integrity": "sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, + "node_modules/@giscus/react": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@giscus/react/-/react-3.0.0.tgz", + "integrity": "sha512-hgCjLpg3Wgh8VbTF5p8ZLcIHI74wvDk1VIFv12+eKhenNVUDjgwNg2B1aq/3puyHOad47u/ZSyqiMtohjy/OOA==", + "dependencies": { + "giscus": "^1.5.0" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@heroicons/react": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.1.5.tgz", + "integrity": "sha512-FuzFN+BsHa+7OxbvAERtgBTNeZpUjgM/MIizfVkSCL2/edriN0Hx/DWRCR//aPYwO5QX/YlgLGXk+E3PcfZwjA==", + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", + "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", + "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@humanfs/core": "^0.19.0", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.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==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" + }, + "node_modules/@iconify/utils": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.1.33.tgz", + "integrity": "sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==", + "dependencies": { + "@antfu/install-pkg": "^0.4.0", + "@antfu/utils": "^0.7.10", + "@iconify/types": "^2.0.0", + "debug": "^4.3.6", + "kolorist": "^1.8.0", + "local-pkg": "^0.5.0", + "mlly": "^1.7.1" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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==", + "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==", + "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==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "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==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==" + }, + "node_modules/@lit/reactive-element": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", + "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.0.tgz", + "integrity": "sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-to-js": "^2.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", + "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@mermaid-js/parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", + "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==", + "dependencies": { + "langium": "3.0.0" + } + }, + "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==", + "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==", + "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==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", + "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.23", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", + "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/dompurify": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", + "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", + "dependencies": { + "@types/trusted-types": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", + "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" + }, + "node_modules/@types/hast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", + "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" + }, + "node_modules/@types/mdast": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", + "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", + "integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "20.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", + "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prismjs": { + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", + "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/react": { + "version": "18.2.39", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", + "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.10.tgz", + "integrity": "sha512-Wn6c/tXdEgi9adCMtDwx8Q2vGty6TsPTc/wCQQ9kAlye8UqFxj0vGFWWuhywNfkwqth+SOgJxQTLTZukrqDQmQ==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" + }, + "node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/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/accepts/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/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "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==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.5.tgz", + "integrity": "sha512-lWvhdnc+aKOKx8jyA3bsdEgHzm/sglC4cYdMG4xSQyRiPLJVJtH/IVYZG3Hp6PkTEhQqhyVYkeP9z2IlcHJsWw==", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/algoliasearch/node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "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==" + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, + "node_modules/async-each": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", + "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", + "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.3", + "core-js-compat": "^3.33.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", + "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-styled-components": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==" + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "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.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "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==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001664", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz", + "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==", + "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/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-css": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", + "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "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==" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "node_modules/combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "engines": { + "node": ">=10" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compressible/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/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==" + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-text-to-clipboard": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/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==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", + "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", + "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", + "dependencies": { + "browserslist": "^4.22.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.3.tgz", + "integrity": "sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "dependencies": { + "layout-base": "^1.0.0" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": 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==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-to-react-native": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", + "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/css-to-react-native/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + }, + "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/cytoscape": { + "version": "3.30.2", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz", + "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-dsv/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre-d3-es": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", + "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", + "dependencies": { + "d3": "^7.8.2", + "lodash-es": "^4.17.21" + } + }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "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==", + "license": "MIT", + "peer": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "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==", + "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/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delaunator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", + "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "dependencies": { + "robust-predicates": "^3.0.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/detect-port": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", + "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + } + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/dompurify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", + "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==" + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.30.tgz", + "integrity": "sha512-sXI35EBN4lYxzc/pIGorlymYNzDBOqkSlVRe6MkgBsW/hW1tpC/HDJ2fjG7XnjakzfLEuvdmux0Mjs6jHq4UOA==" + }, + "node_modules/elkjs": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", + "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" + }, + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", + "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", + "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.6.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.12.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz", + "integrity": "sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA==", + "dependencies": { + "get-stdin": "^6.0.0" + }, + "bin": { + "eslint-config-prettier-check": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=3.14.1" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "peer": 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/eslint/node_modules/eslint-scope": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", + "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/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==", + "license": "MIT", + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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==", + "license": "ISC", + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/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==", + "license": "MIT", + "peer": true + }, + "node_modules/eslint/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==", + "license": "MIT", + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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==", + "license": "MIT", + "peer": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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==", + "license": "MIT", + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/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==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", + "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "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==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", + "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", + "dependencies": { + "@types/estree": "^1.0.0", + "is-plain-obj": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "license": "MIT" + }, + "node_modules/express/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "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==" + }, + "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==", + "license": "MIT", + "peer": 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==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/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==" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "license": "MIT", + "peer": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flat-cache/node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "license": "ISC", + "peer": true + }, + "node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/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==" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/framer-motion": { + "version": "11.11.11", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.11.tgz", + "integrity": "sha512-tuDH23ptJAKUHGydJQII9PhABNJBpB+z0P1bmgKK9QFIssHGlfPd6kxMq00LSKwE27WFsb2z0ovY0bpUyMvfRw==", + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" + }, + "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==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "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==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gh-pages": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.2.0.tgz", + "integrity": "sha512-HMXJ8th9u5wRXaZCnLcs/d3oVvCHiZkaP5KQExQljYGwJjQbSPyTdHe/Gc1IvYUR/rWiZLxNobIqfoMHKTKjHQ==", + "dev": true, + "dependencies": { + "async": "^3.2.4", + "commander": "^11.0.0", + "email-addresses": "^5.0.0", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^11.1.1", + "globby": "^11.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gh-pages/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/gh-pages/node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/gh-pages/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gh-pages/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gh-pages/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gh-pages/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gh-pages/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/gh-pages/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/giscus": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/giscus/-/giscus-1.5.0.tgz", + "integrity": "sha512-t3LL0qbSO3JXq3uyQeKpF5CegstGfKX/0gI6eDe1cmnI7D56R7j52yLdzw4pdKrg3VnufwCgCM3FDz7G1Qr6lg==", + "dependencies": { + "lit": "^3.1.2" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "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": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "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==", + "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==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-dom": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", + "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", + "dependencies": { + "@types/hast": "^3.0.0", + "hastscript": "^8.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", + "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.2.0.tgz", + "integrity": "sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", + "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "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==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.44", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.44.tgz", + "integrity": "sha512-tuRkUSO/lB3rEhLJk25atwAjgLuzq070+pOW8XcvpHky/YbENnRRdPd85IBkyeTgttmOy5ah+yHYsK1HhUd4lQ==", + "engines": { + "node": ">=12" + } + }, + "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==", + "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==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" + } + }, + "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/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "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==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "license": "MIT" + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "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==", + "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==", + "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==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "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==", + "license": "MIT", + "peer": 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==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/katex": { + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", + "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" + }, + "node_modules/langium": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", + "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", + "dependencies": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "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==", + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/lit": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.0.tgz", + "integrity": "sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw==", + "dependencies": { + "@lit/reactive-element": "^2.0.4", + "lit-element": "^4.1.0", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-element": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.0.tgz", + "integrity": "sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww==", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit/reactive-element": "^2.0.4", + "lit-html": "^3.2.0" + } + }, + "node_modules/lit-html": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.0.tgz", + "integrity": "sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA==", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "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==", + "license": "MIT", + "peer": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/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/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/marked": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", + "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", + "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", + "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", + "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", + "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT" + }, + "node_modules/merge-anything": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz", + "integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==", + "license": "MIT", + "dependencies": { + "is-what": "^3.3.1" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/mermaid": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.0.tgz", + "integrity": "sha512-mxCfEYvADJqOiHfGpJXLs4/fAjHz448rH0pfY5fAoxiz70rQiDSzUUy4dNET2T08i46IVpjohPd6WWbzmRHiPA==", + "dependencies": { + "@braintree/sanitize-url": "^7.0.1", + "@iconify/utils": "^2.1.32", + "@mermaid-js/parser": "^0.3.0", + "@types/d3": "^7.4.3", + "@types/dompurify": "^3.0.5", + "cytoscape": "^3.29.2", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.11", + "dayjs": "^1.11.10", + "dompurify": "^3.0.11 <3.1.7", + "katex": "^0.16.9", + "khroma": "^2.1.0", + "lodash-es": "^4.17.21", + "marked": "^13.0.2", + "roughjs": "^4.6.6", + "stylis": "^4.3.1", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.1" + } + }, + "node_modules/mermaid/node_modules/@braintree/sanitize-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz", + "integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==" + }, + "node_modules/mermaid/node_modules/dagre-d3-es": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", + "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } + }, + "node_modules/mermaid/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", + "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", + "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", + "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", + "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", + "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", + "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mlly": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", + "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", + "optional": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "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/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/nanomatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT", + "peer": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "node_modules/non-layered-tidy-tree-layout": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", + "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "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-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "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==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "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.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onchange": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/onchange/-/onchange-5.2.0.tgz", + "integrity": "sha512-kBNMF4KU1m0GkZCANckQZs3N41esf950T/gv7JIjNS6qWS8R34+iCKk/wmVRPEdaYCA+yi2aK2vNXS0RaB/V2A==", + "dependencies": { + "@blakeembrey/deque": "^1.0.3", + "arrify": "^1.0.1", + "chokidar": "^2.0.0", + "cross-spawn": "^6.0.0", + "minimist": "^1.2.0", + "supports-color": "^5.5.0", + "tree-kill": "^1.2.0" + }, + "bin": { + "onchange": "cli.js" + } + }, + "node_modules/onchange/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/onchange/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/onchange/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/onchange/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/onchange/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/onchange/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/onchange/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/onchange/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/onchange/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/onchange/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/onchange/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/onchange/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/onchange/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/onchange/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/onchange/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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/onchange/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onchange/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "license": "MIT", + "peer": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/package-manager-detector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.0.tgz", + "integrity": "sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==" + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==" + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==" + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "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==", + "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==" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-types": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz", + "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==", + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.7.1", + "pathe": "^1.1.2" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "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.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.3.tgz", + "integrity": "sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA==", + "dependencies": { + "cosmiconfig": "^8.2.0", + "jiti": "^1.18.2", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-merge-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", + "dependencies": { + "sort-css-media-queries": "2.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.23" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/postcss-zindex": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "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==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.0.tgz", + "integrity": "sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw==", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "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/property-information": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", + "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/pupa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", + "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "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==", + "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/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/random-id": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/random-id/-/random-id-0.0.2.tgz", + "integrity": "sha512-e1E0fCzmRQcSxeAFnCybHkVi4filc7c07INtA1BAjKFRfKyO+upZ3q0OhxMnyJ2PRwTSpy/jiMN0ZXwLtyQaBw==", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/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==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/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==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/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==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/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==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-helmet-async": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-icons": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "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-json-view-lite": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", + "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-lite-youtube-embed": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-lite-youtube-embed/-/react-lite-youtube-embed-2.4.0.tgz", + "integrity": "sha512-Xo6cM1zPlROvvM97JkqQIoXstlQDaC4+DawmM7BB7Hh1cXrkBHEGq1iJlQxBTUWAUklmpcC7ph7qg7CztXtABQ==", + "peerDependencies": { + "react": ">=18.2.0", + "react-dom": ">=18.2.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "dependencies": { + "@types/react": "*" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", + "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-simple-chatbot": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/react-simple-chatbot/-/react-simple-chatbot-0.6.1.tgz", + "integrity": "sha512-q9y5GXwBvD+YvLgDVyDuZHYMkrcgIirm1FVV9RkR7XojPmbiX1lCzT6ib8U1M5zh42kTUBRnszXzkAGm9e0K8w==", + "dependencies": { + "eslint-config-prettier": "^4.1.0", + "eslint-plugin-prettier": "^3.0.1", + "flatted": "^2.0.0", + "onchange": "^5.2.0", + "prettier": "^1.16.4", + "prop-types": "^15.6.0", + "random-id": "0.0.2", + "react": "^16.4.1", + "react-dom": "^16.4.1" + }, + "peerDependencies": { + "react": "^16.3.0", + "react-dom": "^16.3.0", + "styled-components": "^4.0.0" + } + }, + "node_modules/react-simple-chatbot/node_modules/react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-simple-chatbot/node_modules/react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" + } + }, + "node_modules/react-simple-chatbot/node_modules/scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/react-toastify": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.6.tgz", + "integrity": "sha512-yYjp+omCDf9lhZcrZHKbSq7YMuK0zcYkDFTzfRFgTXkTFHZ1ToxwAonzA4JI5CxA91JpjFLmwEsZEgfYfOqI1A==", + "dependencies": { + "clsx": "^2.1.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reading-time": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", + "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "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/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/rehype-katex": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", + "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz", + "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.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-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "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==", + "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==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, + "node_modules/rtl-detect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", + "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" + }, + "node_modules/rtlcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "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==", + "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/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/search-insights": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", + "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", + "peer": true + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "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==", + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sirv": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", + "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/sitemap": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", + "engines": { + "node": ">= 6.3.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated" + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.5.0.tgz", + "integrity": "sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", + "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "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-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "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==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/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/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/styled-components": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz", + "integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@emotion/is-prop-valid": "^0.8.1", + "@emotion/unitless": "^0.7.0", + "babel-plugin-styled-components": ">= 1", + "css-to-react-native": "^2.2.2", + "memoize-one": "^5.0.0", + "merge-anything": "^2.2.4", + "prop-types": "^15.5.4", + "react-is": "^16.6.0", + "stylis": "^3.5.0", + "stylis-rule-sheet": "^0.0.10", + "supports-color": "^5.5.0" + }, + "peerDependencies": { + "react": ">= 16.3.0", + "react-dom": ">= 16.3.0" + } + }, + "node_modules/styled-components/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==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/styled-components/node_modules/stylis": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==", + "license": "MIT" + }, + "node_modules/styled-components/node_modules/stylis-rule-sheet": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", + "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==", + "license": "MIT", + "peerDependencies": { + "stylis": "^3.5.0" + } + }, + "node_modules/styled-components/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/stylis": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/swiper": { + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.1.14.tgz", + "integrity": "sha512-VbQLQXC04io6AoAjIUWuZwW4MSYozkcP9KjLdrsG/00Q/yiwvhz9RQyt0nHXV10hi9NVnDNy1/wv7Dzq1lkOCQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "engines": { + "node": ">= 4.7.0" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/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/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.35.0.tgz", + "integrity": "sha512-TmYbQnzVfrx3RQsPoItoPplymixIAtp2R2xlpyVBYmFmvI34IzLhCLj8SimRb/kZXlq4t1gA+vbcTqLQ3+5Q5g==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/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==" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "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==" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "node_modules/tinyexec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", + "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==" + }, + "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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-regex/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-regex/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/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/trough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", + "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "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==", + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/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==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", + "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "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.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated" + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/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==" + }, + "node_modules/url-loader/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/url-loader/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/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "node_modules/utility-types": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", + "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uvu/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", + "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, + "node_modules/webpack": { + "version": "5.95.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", + "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", + "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "is-plain-object": "^5.0.0", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/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/webpack-dev-middleware/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/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/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==" + }, + "node_modules/webpack/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/webpack/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/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpackbar": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", + "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.3", + "pretty-time": "^1.1.0", + "std-env": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + }, + "dependencies": { + "@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "requires": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "requires": { + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "@algolia/autocomplete-preset-algolia": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "requires": { + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "requires": {} + }, + "@algolia/cache-browser-local-storage": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", + "requires": { + "@algolia/cache-common": "4.24.0" + } + }, + "@algolia/cache-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" + }, + "@algolia/cache-in-memory": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", + "requires": { + "@algolia/cache-common": "4.24.0" + } + }, + "@algolia/client-account": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", + "requires": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" + }, + "dependencies": { + "@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "requires": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "requires": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + } + } + }, + "@algolia/client-analytics": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", + "requires": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + }, + "dependencies": { + "@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "requires": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "requires": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + } + } + }, + "@algolia/client-common": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.7.0.tgz", + "integrity": "sha512-hrYlN9yNQukmNj8bBlw9PCXi9jmRQqNUXaG6MXH1aDabjO6YD1WPVqTvaELbIBgTbDJzCn0R2owms0uaxQkjUg==", + "peer": true + }, + "@algolia/client-personalization": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", + "requires": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + }, + "dependencies": { + "@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "requires": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + } + } + }, + "@algolia/client-search": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.7.0.tgz", + "integrity": "sha512-0Frfjt4oxvVP2qsTQAjwdaG5SvJ3TbHBkBrS6M7cG5RDrgHqOrhBnBGCFT+YO3CeNK54r+d57oB1VcD2F1lHuQ==", + "peer": true, + "requires": { + "@algolia/client-common": "5.7.0", + "@algolia/requester-browser-xhr": "5.7.0", + "@algolia/requester-fetch": "5.7.0", + "@algolia/requester-node-http": "5.7.0" + } + }, + "@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, + "@algolia/logger-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" + }, + "@algolia/logger-console": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", + "requires": { + "@algolia/logger-common": "4.24.0" + } + }, + "@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "requires": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + }, + "dependencies": { + "@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "requires": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "requires": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "requires": { + "@algolia/requester-common": "4.24.0" + } + }, + "@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "requires": { + "@algolia/requester-common": "4.24.0" + } + } + } + }, + "@algolia/requester-browser-xhr": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.7.0.tgz", + "integrity": "sha512-ohtIp+lyTGM3agrHyedC3w7ijfdUvSN6wmGuKqUezrNzd0nCkFoLW0OINlyv1ODrTEVnL8PAM/Zqubjafxd/Ww==", + "peer": true, + "requires": { + "@algolia/client-common": "5.7.0" + } + }, + "@algolia/requester-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" + }, + "@algolia/requester-fetch": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.7.0.tgz", + "integrity": "sha512-Eg8cBhNg2QNnDDldyK77aXvg3wIc5qnpCDCAJXQ2oaqZwwvvYaTgnP1ofznNG6+klri4Fk1YAaC9wyDBhByWIA==", + "peer": true, + "requires": { + "@algolia/client-common": "5.7.0" + } + }, + "@algolia/requester-node-http": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.7.0.tgz", + "integrity": "sha512-8BDssYEkcp1co06KtHO9b37H+5zVM/h+5kyesJb2C2EHFO3kgzLHWl/JyXOVtYlKQBkmdObYOI0s6JaXRy2yQA==", + "peer": true, + "requires": { + "@algolia/client-common": "5.7.0" + } + }, + "@algolia/transporter": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", + "requires": { + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" + } + }, + "@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true + }, + "@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@antfu/install-pkg": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", + "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", + "requires": { + "package-manager-detector": "^0.2.0", + "tinyexec": "^0.3.0" + } + }, + "@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==" + }, + "@babel/code-frame": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "requires": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "dependencies": { + "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==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "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==" + }, + "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==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/compat-data": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==" + }, + "@babel/core": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/generator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", + "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", + "requires": { + "@babel/types": "^7.23.4", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "requires": { + "@babel/types": "^7.22.15" + } + }, + "@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==", + "requires": { + "@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" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", + "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", + "requires": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + } + }, + "@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==" + }, + "@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==", + "requires": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "requires": { + "@babel/types": "^7.23.0" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.22.15" + } + }, + "@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "requires": { + "@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" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", + "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==" + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + } + }, + "@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" + }, + "@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==" + }, + "@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==" + }, + "@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "requires": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + } + }, + "@babel/helpers": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.4.tgz", + "integrity": "sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw==", + "requires": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.4", + "@babel/types": "^7.23.4" + } + }, + "@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "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==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "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==" + }, + "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==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==" + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + } + }, + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", + "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "requires": {} + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-async-generator-functions": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", + "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "requires": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.3.tgz", + "integrity": "sha512-FGEQmugvAEu2QtgtU0uTASXevfLMFfBeVCIIdcQhn/uBQsMTjBajdnAtanQlOcuihWh10PZ7+HWvc7NtBwP74w==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", + "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "requires": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "requires": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "requires": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", + "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", + "requires": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "requires": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-transform-object-rest-spread": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", + "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "requires": { + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + } + }, + "@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-react-constant-elements": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.7.tgz", + "integrity": "sha512-/qXt69Em8HgsjCLu7G3zdIQn7A2QwmYND7Wa0LTp09Na+Zn8L5d0A7wSXrKi18TJRc/Q5S1i1De/SU1LzVkSvA==", + "requires": { + "@babel/helper-plugin-utils": "^7.25.7" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", + "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "requires": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + } + }, + "@babel/plugin-transform-react-pure-annotations": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", + "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.4.tgz", + "integrity": "sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw==", + "requires": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.4.tgz", + "integrity": "sha512-39hCCOl+YUAyMOu6B9SmUTiHUU0t/CxJNUmY3qRdJujbqi+lrQcL11ysYUsAvFWPBdhihrv1z0oRG84Yr3dODQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/preset-env": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.3.tgz", + "integrity": "sha512-ovzGc2uuyNfNAs/jyjIGxS8arOHS5FENZaNn4rtE7UdKMMkqHCvboHfcuhWLZNX5cB44QfcGNWjaevxMzzMf+Q==", + "requires": { + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.3", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.3", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.3", + "@babel/plugin-transform-classes": "^7.23.3", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.3", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.3", + "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.3", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.3", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.3", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.3", + "@babel/plugin-transform-numeric-separator": "^7.23.3", + "@babel/plugin-transform-object-rest-spread": "^7.23.3", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.3", + "@babel/plugin-transform-optional-chaining": "^7.23.3", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.3", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-react": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", + "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.23.3", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.23.3" + } + }, + "@babel/preset-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" + } + }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "@babel/runtime": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", + "integrity": "sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "@babel/runtime-corejs3": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.4.tgz", + "integrity": "sha512-zQyB4MJGM+rvd4pM58n26kf3xbiitw9MHzL8oLiBMKb8MCtVDfV5nDzzJWWzLMtbvKI9wN6XwJYl479qF4JluQ==", + "requires": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + } + }, + "@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + } + }, + "@babel/traverse": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", + "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", + "requires": { + "@babel/code-frame": "^7.23.4", + "@babel/generator": "^7.23.4", + "@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.4", + "@babel/types": "^7.23.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", + "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", + "requires": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + } + }, + "@blakeembrey/deque": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@blakeembrey/deque/-/deque-1.0.5.tgz", + "integrity": "sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg==" + }, + "@braintree/sanitize-url": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", + "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" + }, + "@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "requires": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "requires": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" + }, + "@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" + }, + "@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" + }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" + }, + "@docsearch/css": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.2.tgz", + "integrity": "sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw==" + }, + "@docsearch/react": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.2.tgz", + "integrity": "sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA==", + "requires": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.6.2", + "algoliasearch": "^4.19.1" + } + }, + "@docusaurus/core": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.5.2.tgz", + "integrity": "sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==", + "requires": { + "@babel/core": "^7.23.3", + "@babel/generator": "^7.23.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.22.9", + "@babel/preset-env": "^7.22.9", + "@babel/preset-react": "^7.22.5", + "@babel/preset-typescript": "^7.22.5", + "@babel/runtime": "^7.22.6", + "@babel/runtime-corejs3": "^7.22.6", + "@babel/traverse": "^7.22.8", + "@docusaurus/cssnano-preset": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.1.3", + "babel-plugin-dynamic-import-node": "^2.3.3", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "clean-css": "^5.3.2", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "copy-webpack-plugin": "^11.0.0", + "core-js": "^3.31.1", + "css-loader": "^6.8.1", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "del": "^6.1.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "html-minifier-terser": "^7.2.0", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.5.3", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "mini-css-extract-plugin": "^2.7.6", + "p-map": "^4.0.0", + "postcss": "^8.4.26", + "postcss-loader": "^7.3.3", + "prompts": "^2.4.2", + "react-dev-utils": "^12.0.1", + "react-helmet-async": "^1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "rtl-detect": "^1.0.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.5", + "shelljs": "^0.8.5", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "url-loader": "^4.1.1", + "webpack": "^5.88.1", + "webpack-bundle-analyzer": "^4.9.0", + "webpack-dev-server": "^4.15.1", + "webpack-merge": "^5.9.0", + "webpackbar": "^5.0.2" + } + }, + "@docusaurus/cssnano-preset": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.5.2.tgz", + "integrity": "sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==", + "requires": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.4.38", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + } + }, + "@docusaurus/logger": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.5.2.tgz", + "integrity": "sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==", + "requires": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + } + }, + "@docusaurus/mdx-loader": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.5.2.tgz", + "integrity": "sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==", + "requires": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^1.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + } + }, + "@docusaurus/module-type-aliases": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.5.2.tgz", + "integrity": "sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==", + "requires": { + "@docusaurus/types": "3.5.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "*", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + } + }, + "@docusaurus/plugin-content-blog": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.5.2.tgz", + "integrity": "sha512-R7ghWnMvjSf+aeNDH0K4fjyQnt5L0KzUEnUhmf1e3jZrv3wogeytZNN6n7X8yHcMsuZHPOrctQhXWnmxu+IRRg==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "reading-time": "^1.5.0", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + } + }, + "@docusaurus/plugin-content-docs": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.5.2.tgz", + "integrity": "sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + } + }, + "@docusaurus/plugin-debug": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.5.2.tgz", + "integrity": "sha512-kBK6GlN0itCkrmHuCS6aX1wmoWc5wpd5KJlqQ1FyrF0cLDnvsYSnh7+ftdwzt7G6lGBho8lrVwkkL9/iQvaSOA==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^1.2.0", + "tslib": "^2.6.0" + } + }, + "@docusaurus/plugin-google-analytics": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.5.2.tgz", + "integrity": "sha512-rjEkJH/tJ8OXRE9bwhV2mb/WP93V441rD6XnM6MIluu7rk8qg38iSxS43ga2V2Q/2ib53PcqbDEJDG/yWQRJhQ==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "tslib": "^2.6.0" + } + }, + "@docusaurus/plugin-google-gtag": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.5.2.tgz", + "integrity": "sha512-lm8XL3xLkTPHFKKjLjEEAHUrW0SZBSHBE1I+i/tmYMBsjCcUB5UJ52geS5PSiOCFVR74tbPGcPHEV/gaaxFeSA==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + } + }, + "@docusaurus/plugin-google-tag-manager": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.5.2.tgz", + "integrity": "sha512-QkpX68PMOMu10Mvgvr5CfZAzZQFx8WLlOiUQ/Qmmcl6mjGK6H21WLT5x7xDmcpCoKA/3CegsqIqBR+nA137lQg==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "tslib": "^2.6.0" + } + }, + "@docusaurus/plugin-sitemap": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.5.2.tgz", + "integrity": "sha512-DnlqYyRAdQ4NHY28TfHuVk414ft2uruP4QWCH//jzpHjqvKyXjj2fmDtI8RPUBh9K8iZKFMHRnLtzJKySPWvFA==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + } + }, + "@docusaurus/preset-classic": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.5.2.tgz", + "integrity": "sha512-3ihfXQ95aOHiLB5uCu+9PRy2gZCeSZoDcqpnDvf3B+sTrMvMTr8qRUzBvWkoIqc82yG5prCboRjk1SVILKx6sg==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/plugin-content-blog": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/plugin-content-pages": "3.5.2", + "@docusaurus/plugin-debug": "3.5.2", + "@docusaurus/plugin-google-analytics": "3.5.2", + "@docusaurus/plugin-google-gtag": "3.5.2", + "@docusaurus/plugin-google-tag-manager": "3.5.2", + "@docusaurus/plugin-sitemap": "3.5.2", + "@docusaurus/theme-classic": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-search-algolia": "3.5.2", + "@docusaurus/types": "3.5.2" + }, + "dependencies": { + "@docusaurus/plugin-content-pages": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", + "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + } + } + } + }, + "@docusaurus/theme-classic": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.5.2.tgz", + "integrity": "sha512-XRpinSix3NBv95Rk7xeMF9k4safMkwnpSgThn0UNQNumKvmcIYjfkwfh2BhwYh/BxMXQHJ/PdmNh22TQFpIaYg==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/plugin-content-blog": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/plugin-content-pages": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-translations": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.44", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.4.26", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "dependencies": { + "@docusaurus/plugin-content-pages": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", + "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + } + } + } + }, + "@docusaurus/theme-common": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.5.2.tgz", + "integrity": "sha512-QXqlm9S6x9Ibwjs7I2yEDgsCocp708DrCrgHgKwg2n2AY0YQ6IjU0gAK35lHRLOvAoJUfCKpQAwUykB0R7+Eew==", + "requires": { + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + } + }, + "@docusaurus/theme-mermaid": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.5.2.tgz", + "integrity": "sha512-7vWCnIe/KoyTN1Dc55FIyqO5hJ3YaV08Mr63Zej0L0mX1iGzt+qKSmeVUAJ9/aOalUhF0typV0RmNUSy5FAmCg==", + "requires": { + "@docusaurus/core": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "mermaid": "^10.4.0", + "tslib": "^2.6.0" + }, + "dependencies": { + "@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "requires": { + "@types/unist": "^2" + } + }, + "@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "requires": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + } + }, + "mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "requires": { + "@types/mdast": "^3.0.0" + } + }, + "mermaid": { + "version": "10.9.3", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.3.tgz", + "integrity": "sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==", + "requires": { + "@braintree/sanitize-url": "^6.0.1", + "@types/d3-scale": "^4.0.3", + "@types/d3-scale-chromatic": "^3.0.0", + "cytoscape": "^3.28.1", + "cytoscape-cose-bilkent": "^4.1.0", + "d3": "^7.4.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.10", + "dayjs": "^1.11.7", + "dompurify": "^3.0.5 <3.1.7", + "elkjs": "^0.9.0", + "katex": "^0.16.9", + "khroma": "^2.0.0", + "lodash-es": "^4.17.21", + "mdast-util-from-markdown": "^1.3.0", + "non-layered-tidy-tree-layout": "^2.0.2", + "stylis": "^4.1.3", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" + } + }, + "micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "requires": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "requires": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "requires": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "requires": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==" + }, + "micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==" + }, + "micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "requires": { + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "requires": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" + }, + "unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + } + } + }, + "@docusaurus/theme-search-algolia": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.5.2.tgz", + "integrity": "sha512-qW53kp3VzMnEqZGjakaV90sst3iN1o32PH+nawv1uepROO8aEGxptcq2R5rsv7aBShSRbZwIobdvSYKsZ5pqvA==", + "requires": { + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-translations": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "algoliasearch": "^4.18.0", + "algoliasearch-helper": "^3.13.3", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + } + }, + "@docusaurus/theme-translations": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.5.2.tgz", + "integrity": "sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==", + "requires": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + } + }, + "@docusaurus/types": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.5.2.tgz", + "integrity": "sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==", + "requires": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "^1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1", + "webpack-merge": "^5.9.0" + } + }, + "@docusaurus/utils": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.5.2.tgz", + "integrity": "sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==", + "requires": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@svgr/webpack": "^8.1.0", + "escape-string-regexp": "^4.0.0", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + } + }, + "@docusaurus/utils-common": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.5.2.tgz", + "integrity": "sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==", + "requires": { + "tslib": "^2.6.0" + } + }, + "@docusaurus/utils-validation": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.5.2.tgz", + "integrity": "sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==", + "requires": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + } + }, + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@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==", + "peer": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "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==", + "peer": true + } + } + }, + "@eslint-community/regexpp": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "peer": true + }, + "@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "peer": true, + "requires": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + } + }, + "@eslint/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", + "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "peer": true + }, + "@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "peer": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.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" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "peer": true + }, + "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==", + "peer": true + } + } + }, + "@eslint/js": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", + "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", + "peer": true + }, + "@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "peer": true + }, + "@eslint/plugin-kit": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", + "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "peer": true, + "requires": { + "levn": "^0.4.1" + } + }, + "@fortawesome/fontawesome-common-types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", + "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", + "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", + "peer": true, + "requires": { + "@fortawesome/fontawesome-common-types": "6.6.0" + } + }, + "@fortawesome/free-brands-svg-icons": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz", + "integrity": "sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.6.0" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "requires": { + "prop-types": "^15.8.1" + } + }, + "@giscus/react": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@giscus/react/-/react-3.0.0.tgz", + "integrity": "sha512-hgCjLpg3Wgh8VbTF5p8ZLcIHI74wvDk1VIFv12+eKhenNVUDjgwNg2B1aq/3puyHOad47u/ZSyqiMtohjy/OOA==", + "requires": { + "giscus": "^1.5.0" + } + }, + "@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@heroicons/react": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.1.5.tgz", + "integrity": "sha512-FuzFN+BsHa+7OxbvAERtgBTNeZpUjgM/MIizfVkSCL2/edriN0Hx/DWRCR//aPYwO5QX/YlgLGXk+E3PcfZwjA==", + "requires": {} + }, + "@humanfs/core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", + "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "peer": true + }, + "@humanfs/node": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", + "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "peer": true, + "requires": { + "@humanfs/core": "^0.19.0", + "@humanwhocodes/retry": "^0.3.0" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "peer": true + }, + "@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "peer": true + }, + "@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" + }, + "@iconify/utils": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.1.33.tgz", + "integrity": "sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==", + "requires": { + "@antfu/install-pkg": "^0.4.0", + "@antfu/utils": "^0.7.10", + "@iconify/types": "^2.0.0", + "debug": "^4.3.6", + "kolorist": "^1.8.0", + "local-pkg": "^0.5.0", + "mlly": "^1.7.1" + } + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "requires": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@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==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@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==" + }, + "@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==" + }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@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==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==" + }, + "@lit/reactive-element": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", + "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", + "requires": { + "@lit-labs/ssr-dom-shim": "^1.2.0" + } + }, + "@mdx-js/mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.0.tgz", + "integrity": "sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==", + "requires": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-to-js": "^2.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + } + }, + "@mdx-js/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", + "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", + "requires": { + "@types/mdx": "^2.0.0" + } + }, + "@mermaid-js/parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", + "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==", + "requires": { + "langium": "3.0.0" + } + }, + "@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==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@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==" + }, + "@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==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==" + }, + "@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "requires": { + "graceful-fs": "4.2.10" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + } + } + }, + "@pnpm/npm-conf": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", + "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "requires": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + } + }, + "@polka/url": { + "version": "1.0.0-next.23", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", + "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==" + }, + "@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" + }, + "@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "requires": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "requires": {} + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "requires": {} + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "requires": {} + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "requires": {} + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "requires": {} + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "requires": {} + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "requires": {} + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "requires": {} + }, + "@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "requires": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + } + }, + "@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "requires": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + } + }, + "@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "requires": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + } + }, + "@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "requires": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + } + }, + "@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "requires": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + } + }, + "@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "requires": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + } + }, + "@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "requires": { + "defer-to-connect": "^2.0.1" + } + }, + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" + }, + "@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "requires": { + "@types/estree": "*" + } + }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "requires": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" + }, + "@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "requires": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" + }, + "@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" + }, + "@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" + }, + "@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "requires": { + "@types/d3-dsv": "*" + } + }, + "@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==" + }, + "@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" + }, + "@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "requires": { + "@types/geojson": "*" + } + }, + "@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" + }, + "@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "requires": { + "@types/d3-color": "*" + } + }, + "@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" + }, + "@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" + }, + "@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" + }, + "@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "requires": { + "@types/d3-time": "*" + } + }, + "@types/d3-scale-chromatic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + }, + "@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==" + }, + "@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "requires": { + "@types/d3-path": "*" + } + }, + "@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" + }, + "@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "requires": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "requires": { + "@types/ms": "*" + } + }, + "@types/dompurify": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", + "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", + "requires": { + "@types/trusted-types": "*" + } + }, + "@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "@types/estree-jsx": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", + "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", + "requires": { + "@types/estree": "*" + } + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, + "@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" + }, + "@types/hast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", + "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", + "requires": { + "@types/unist": "*" + } + }, + "@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + }, + "@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" + }, + "@types/mdast": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", + "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "requires": { + "@types/unist": "*" + } + }, + "@types/mdx": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", + "integrity": "sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==" + }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "@types/node": { + "version": "20.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", + "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/node-forge": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "requires": { + "@types/node": "*" + } + }, + "@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "@types/prismjs": { + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", + "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" + }, + "@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "@types/react": { + "version": "18.2.39", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz", + "integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "requires": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "@types/react-router-config": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.10.tgz", + "integrity": "sha512-Wn6c/tXdEgi9adCMtDwx8Q2vGty6TsPTc/wCQQ9kAlye8UqFxj0vGFWWuhywNfkwqth+SOgJxQTLTZukrqDQmQ==", + "requires": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "requires": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "requires": { + "@types/node": "*" + } + }, + "@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" + }, + "@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "requires": { + "@types/node": "*" + } + }, + "@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "requires": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "dependencies": { + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "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==", + "requires": { + "mime-db": "1.52.0" + } + } + } + }, + "acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==" + }, + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "requires": {} + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "requires": {} + }, + "acorn-walk": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==" + }, + "address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==" + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "algoliasearch": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "requires": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + }, + "dependencies": { + "@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "requires": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "requires": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "requires": { + "@algolia/requester-common": "4.24.0" + } + }, + "@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "requires": { + "@algolia/requester-common": "4.24.0" + } + } + } + }, + "algoliasearch-helper": { + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.5.tgz", + "integrity": "sha512-lWvhdnc+aKOKx8jyA3bsdEgHzm/sglC4cYdMG4xSQyRiPLJVJtH/IVYZG3Hp6PkTEhQqhyVYkeP9z2IlcHJsWw==", + "requires": { + "@algolia/events": "^4.0.1" + } + }, + "ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "requires": { + "string-width": "^4.1.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==" + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==" + }, + "astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==" + }, + "async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, + "async-each": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "requires": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "requires": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "requires": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", + "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "requires": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.3", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", + "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.4.3", + "core-js-compat": "^3.33.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", + "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "requires": { + "@babel/helper-define-polyfill-provider": "^0.4.3" + } + }, + "babel-plugin-styled-components": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" + } + }, + "bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "requires": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + } + } + } + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "requires": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "requires": { + "fill-range": "^7.1.1" + } + }, + "browserslist": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "requires": { + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==" + }, + "cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "requires": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "dependencies": { + "normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==" + } + } + }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true + }, + "camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001664", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz", + "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==" + }, + "ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==" + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" + }, + "character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" + }, + "character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==" + }, + "character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==" + }, + "character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==" + }, + "cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "requires": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + } + }, + "cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "requires": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + } + }, + "chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "requires": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "requires": { + "lodash-es": "^4.17.21" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + }, + "ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==" + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + } + }, + "clean-css": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", + "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==" + }, + "cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" + }, + "collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "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==", + "requires": { + "color-name": "~1.1.4" + } + }, + "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==" + }, + "colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==" + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==" + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "requires": { + "mime-db": ">= 1.43.0 < 2" + }, + "dependencies": { + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + } + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==" + }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "requires": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + } + }, + "connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" + }, + "consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==" + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "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==" + }, + "cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==" + }, + "copy-text-to-clipboard": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==" + }, + "copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "requires": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "dependencies": { + "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==", + "requires": { + "is-glob": "^4.0.3" + } + }, + "globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" + } + } + }, + "core-js": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", + "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==" + }, + "core-js-compat": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", + "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", + "requires": { + "browserslist": "^4.22.1" + } + }, + "core-js-pure": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.3.tgz", + "integrity": "sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ==" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "requires": { + "layout-base": "^1.0.0" + } + }, + "cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "requires": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "requires": { + "type-fest": "^1.0.1" + }, + "dependencies": { + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==" + } + } + }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" + }, + "css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "requires": {} + }, + "css-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + } + }, + "css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "requires": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + } + }, + "css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + } + }, + "css-to-react-native": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", + "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "requires": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "requires": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "dependencies": { + "lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==" + } + } + }, + "cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "requires": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + } + }, + "cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "requires": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + } + }, + "cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "requires": {} + }, + "csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "requires": { + "css-tree": "~2.2.0" + }, + "dependencies": { + "css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "requires": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + } + }, + "mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + } + } + }, + "csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "cytoscape": { + "version": "3.30.2", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz", + "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==" + }, + "cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "requires": { + "cose-base": "^1.0.0" + } + }, + "cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "requires": { + "cose-base": "^2.2.0" + }, + "dependencies": { + "cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "requires": { + "layout-base": "^2.0.0" + } + }, + "layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" + } + } + }, + "d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "requires": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + } + }, + "d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "requires": { + "internmap": "1 - 2" + } + }, + "d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==" + }, + "d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + } + }, + "d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "requires": { + "d3-path": "1 - 3" + } + }, + "d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==" + }, + "d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "requires": { + "d3-array": "^3.2.0" + } + }, + "d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "requires": { + "delaunator": "5" + } + }, + "d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==" + }, + "d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + } + }, + "d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "requires": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" + }, + "d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "requires": { + "d3-dsv": "1 - 3" + } + }, + "d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + } + }, + "d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==" + }, + "d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "requires": { + "d3-array": "2.5.0 - 3" + } + }, + "d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==" + }, + "d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "requires": { + "d3-color": "1 - 3" + } + }, + "d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==" + }, + "d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==" + }, + "d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==" + }, + "d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==" + }, + "d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "requires": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + }, + "dependencies": { + "d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "requires": { + "internmap": "^1.0.0" + } + }, + "d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" + }, + "d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "requires": { + "d3-path": "1" + } + }, + "internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + } + } + }, + "d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "requires": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + } + }, + "d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "requires": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + } + }, + "d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==" + }, + "d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "requires": { + "d3-path": "^3.1.0" + } + }, + "d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "requires": { + "d3-array": "2 - 3" + } + }, + "d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "requires": { + "d3-time": "1 - 3" + } + }, + "d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==" + }, + "d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "requires": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + } + }, + "d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + } + }, + "dagre-d3-es": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", + "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", + "requires": { + "d3": "^7.8.2", + "lodash-es": "^4.17.21" + } + }, + "dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "requires": { + "ms": "^2.1.3" + } + }, + "decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "requires": { + "character-entities": "^2.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + } + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "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==", + "peer": true + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" + }, + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "requires": { + "execa": "^5.0.0" + } + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" + }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "requires": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + } + }, + "delaunator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", + "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "requires": { + "robust-predicates": "^3.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "detect-port": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", + "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", + "requires": { + "address": "^1.0.1", + "debug": "4" + } + }, + "detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "requires": { + "dequal": "^2.0.0" + } + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + }, + "dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "requires": { + "utila": "~0.4" + } + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "dompurify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", + "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==" + }, + "domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "requires": { + "is-obj": "^2.0.0" + }, + "dependencies": { + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + } + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "electron-to-chromium": { + "version": "1.5.30", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.30.tgz", + "integrity": "sha512-sXI35EBN4lYxzc/pIGorlymYNzDBOqkSlVRe6MkgBsW/hW1tpC/HDJ2fjG7XnjakzfLEuvdmux0Mjs6jHq4UOA==" + }, + "elkjs": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", + "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" + }, + "email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + }, + "emoticon": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", + "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==" + }, + "encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" + }, + "enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + }, + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" + }, + "escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "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==" + }, + "eslint": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", + "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", + "peer": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.6.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.12.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "eslint-scope": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", + "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", + "peer": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "peer": true + }, + "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==", + "peer": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "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==", + "peer": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "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==", + "peer": true + }, + "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==", + "peer": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "peer": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "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==", + "peer": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "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==", + "peer": true + }, + "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==", + "peer": true + } + } + }, + "eslint-config-prettier": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz", + "integrity": "sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA==", + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "peer": true + }, + "espree": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", + "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", + "peer": true, + "requires": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "peer": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "peer": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "requires": { + "@types/estree": "^1.0.0" + } + }, + "estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "requires": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + } + }, + "estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==" + }, + "estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "requires": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + } + }, + "estree-util-value-to-estree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", + "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", + "requires": { + "@types/estree": "^1.0.0", + "is-plain-obj": "^4.0.0" + } + }, + "estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "requires": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + } + }, + "estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "requires": { + "@types/estree": "^1.0.0" + } + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "requires": { + "@types/node": "*", + "require-like": ">= 0.1.1" + } + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "requires": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + } + } + } + }, + "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==" + }, + "fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" + }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "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==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "peer": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "requires": { + "format": "^0.2.0" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "requires": { + "xml-js": "^1.6.11" + } + }, + "file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "peer": true, + "requires": { + "flat-cache": "^4.0.0" + } + }, + "file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, + "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==" + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true + }, + "filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + } + }, + "filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "requires": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + } + }, + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" + }, + "flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "peer": true, + "requires": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "dependencies": { + "flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "peer": true + } + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + }, + "follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==" + }, + "foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } + } + }, + "fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "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==" + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + } + } + }, + "form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==" + }, + "format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "requires": { + "map-cache": "^0.2.2" + } + }, + "framer-motion": { + "version": "11.11.11", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.11.tgz", + "integrity": "sha512-tuDH23ptJAKUHGydJQII9PhABNJBpB+z0P1bmgKK9QFIssHGlfPd6kxMq00LSKwE27WFsb2z0ovY0bpUyMvfRw==", + "requires": { + "tslib": "^2.4.0" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "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==" + }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==" + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==" + }, + "gh-pages": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.2.0.tgz", + "integrity": "sha512-HMXJ8th9u5wRXaZCnLcs/d3oVvCHiZkaP5KQExQljYGwJjQbSPyTdHe/Gc1IvYUR/rWiZLxNobIqfoMHKTKjHQ==", + "dev": true, + "requires": { + "async": "^3.2.4", + "commander": "^11.0.0", + "email-addresses": "^5.0.0", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^11.1.1", + "globby": "^11.1.0" + }, + "dependencies": { + "commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "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 + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "giscus": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/giscus/-/giscus-1.5.0.tgz", + "integrity": "sha512-t3LL0qbSO3JXq3uyQeKpF5CegstGfKX/0gI6eDe1cmnI7D56R7j52yLdzw4pdKrg3VnufwCgCM3FDz7G1Qr6lg==", + "requires": { + "lit": "^3.1.2" + } + }, + "github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "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" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "requires": { + "ini": "2.0.0" + }, + "dependencies": { + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "requires": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==" + } + } + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "requires": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } + } + }, + "gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "requires": { + "duplexer": "^0.1.2" + } + }, + "hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==" + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + }, + "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==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==" + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "hast-util-from-dom": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", + "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", + "requires": { + "@types/hast": "^3.0.0", + "hastscript": "^8.0.0", + "web-namespaces": "^2.0.0" + } + }, + "hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "requires": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + } + }, + "hast-util-from-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", + "requires": { + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + } + }, + "hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "requires": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + } + }, + "hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "requires": { + "@types/hast": "^3.0.0" + } + }, + "hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "requires": { + "@types/hast": "^3.0.0" + } + }, + "hast-util-raw": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.1.tgz", + "integrity": "sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==", + "requires": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + } + }, + "hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "requires": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + } + }, + "hast-util-to-jsx-runtime": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.2.0.tgz", + "integrity": "sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==", + "requires": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + } + }, + "hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "requires": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + } + }, + "hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "requires": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + } + }, + "hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "requires": { + "@types/hast": "^3.0.0" + } + }, + "hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "requires": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==" + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "requires": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "dependencies": { + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" + } + } + }, + "html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==" + }, + "html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==" + }, + "html-webpack-plugin": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "requires": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "dependencies": { + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + }, + "html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "requires": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + } + } + } + }, + "htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" + } + } + }, + "http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "requires": {} + }, + "ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==" + }, + "image-size": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", + "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", + "requires": { + "queue": "6.0.2" + } + }, + "immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "infima": { + "version": "0.2.0-alpha.44", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.44.tgz", + "integrity": "sha512-tuRkUSO/lB3rEhLJk25atwAjgLuzq070+pOW8XcvpHky/YbENnRRdPd85IBkyeTgttmOy5ah+yHYsK1HhUd4lQ==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==" + }, + "is-accessor-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==" + }, + "is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "requires": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "requires": { + "ci-info": "^3.2.0" + } + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==" + }, + "is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "requires": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==" + }, + "is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "requires": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + } + }, + "is-npm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" + }, + "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==" + }, + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, + "is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "requires": { + "@types/estree": "*" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" + }, + "is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, + "is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" + }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "requires": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==" + }, + "joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "requires": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "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==" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "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==", + "peer": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "katex": { + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", + "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", + "requires": { + "commander": "^8.3.0" + }, + "dependencies": { + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + } + } + }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "requires": { + "json-buffer": "3.0.1" + } + }, + "khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" + }, + "langium": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", + "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", + "requires": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + } + }, + "latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "requires": { + "package-json": "^8.1.0" + } + }, + "launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "requires": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "peer": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "lit": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.0.tgz", + "integrity": "sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw==", + "requires": { + "@lit/reactive-element": "^2.0.4", + "lit-element": "^4.1.0", + "lit-html": "^3.2.0" + } + }, + "lit-element": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.0.tgz", + "integrity": "sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww==", + "requires": { + "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit/reactive-element": "^2.0.4", + "lit-html": "^3.2.0" + } + }, + "lit-html": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.0.tgz", + "integrity": "sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA==", + "requires": { + "@types/trusted-types": "^2.0.2" + } + }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" + }, + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "requires": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + } + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "requires": { + "p-locate": "^6.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "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==", + "peer": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==" + }, + "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==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==" + }, + "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==", + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==" + }, + "markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==" + }, + "marked": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", + "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==" + }, + "mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "requires": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + } + }, + "mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "requires": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" + } + } + }, + "mdast-util-from-markdown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", + "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "requires": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "dependencies": { + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "requires": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" + } + } + }, + "mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "requires": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "mdast-util-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "requires": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "requires": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + } + }, + "mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "requires": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "requires": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "requires": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "requires": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + } + }, + "mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "requires": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "mdast-util-mdx-expression": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", + "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "requires": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "mdast-util-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", + "requires": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + } + }, + "mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "requires": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "mdast-util-phrasing": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", + "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", + "requires": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + } + }, + "mdast-util-to-hast": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.0.2.tgz", + "integrity": "sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==", + "requires": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0" + } + }, + "mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "requires": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + } + }, + "mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "requires": { + "@types/mdast": "^4.0.0" + } + }, + "mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "requires": { + "fs-monkey": "^1.0.4" + } + }, + "memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "merge-anything": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz", + "integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==", + "requires": { + "is-what": "^3.3.1" + } + }, + "merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "mermaid": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.0.tgz", + "integrity": "sha512-mxCfEYvADJqOiHfGpJXLs4/fAjHz448rH0pfY5fAoxiz70rQiDSzUUy4dNET2T08i46IVpjohPd6WWbzmRHiPA==", + "requires": { + "@braintree/sanitize-url": "^7.0.1", + "@iconify/utils": "^2.1.32", + "@mermaid-js/parser": "^0.3.0", + "@types/d3": "^7.4.3", + "@types/dompurify": "^3.0.5", + "cytoscape": "^3.29.2", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.11", + "dayjs": "^1.11.10", + "dompurify": "^3.0.11 <3.1.7", + "katex": "^0.16.9", + "khroma": "^2.1.0", + "lodash-es": "^4.17.21", + "marked": "^13.0.2", + "roughjs": "^4.6.6", + "stylis": "^4.3.1", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.1" + }, + "dependencies": { + "@braintree/sanitize-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz", + "integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==" + }, + "dagre-d3-es": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", + "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", + "requires": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } + }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + } + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "requires": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-core-commonmark": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", + "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", + "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", + "requires": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "requires": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "requires": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-extension-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "requires": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "requires": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", + "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "requires": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "requires": { + "micromark-util-types": "^2.0.0" + } + }, + "micromark-extension-gfm-task-list-item": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", + "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "requires": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "requires": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "requires": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "requires": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "requires": { + "micromark-util-types": "^2.0.0" + } + }, + "micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "requires": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "requires": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "requires": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-factory-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", + "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "requires": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "dependencies": { + "micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" + } + } + }, + "micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "requires": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "requires": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "requires": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "dependencies": { + "micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" + } + } + }, + "micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "requires": { + "micromark-util-symbol": "^2.0.0" + }, + "dependencies": { + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "requires": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "requires": { + "micromark-util-symbol": "^2.0.0" + }, + "dependencies": { + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==" + }, + "micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "requires": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "dependencies": { + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==" + }, + "micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "requires": { + "micromark-util-symbol": "^2.0.0" + }, + "dependencies": { + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "requires": { + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + }, + "dependencies": { + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-subtokenize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", + "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "requires": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + } + } + }, + "micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==" + }, + "micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==" + }, + "micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "requires": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "requires": { + "mime-db": "~1.33.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==" + }, + "mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "requires": { + "schema-utils": "^4.0.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "mlly": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", + "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", + "requires": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + } + }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" + }, + "mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "nan": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", + "optional": true + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "requires": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "peer": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "requires": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" + }, + "node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "non-layered-tidy-tree-layout": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", + "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "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==" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true + }, + "object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "requires": { + "isobject": "^3.0.0" + } + }, + "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==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "requires": { + "isobject": "^3.0.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onchange": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/onchange/-/onchange-5.2.0.tgz", + "integrity": "sha512-kBNMF4KU1m0GkZCANckQZs3N41esf950T/gv7JIjNS6qWS8R34+iCKk/wmVRPEdaYCA+yi2aK2vNXS0RaB/V2A==", + "requires": { + "@blakeembrey/deque": "^1.0.3", + "arrify": "^1.0.1", + "chokidar": "^2.0.0", + "cross-spawn": "^6.0.0", + "minimist": "^1.2.0", + "supports-color": "^5.5.0", + "tree-kill": "^1.2.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "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==" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "requires": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + } + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + }, + "optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "peer": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + } + }, + "p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==" + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "requires": { + "p-limit": "^4.0.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "requires": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "requires": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + } + }, + "package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "package-manager-detector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.0.tgz", + "integrity": "sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==" + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "requires": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "dependencies": { + "@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + } + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" + }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "requires": { + "entities": "^4.4.0" + } + }, + "parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "requires": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==" + }, + "path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==" + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==" + }, + "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==" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "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==" + }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + } + } + }, + "path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "requires": { + "isarray": "0.0.1" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" + }, + "periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true + }, + "pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true + }, + "pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "requires": { + "find-up": "^6.3.0" + } + }, + "pkg-types": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz", + "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==", + "requires": { + "confbox": "^0.1.7", + "mlly": "^1.7.1", + "pathe": "^1.1.2" + } + }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + } + } + }, + "points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==" + }, + "points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "requires": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==" + }, + "postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + } + }, + "postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "requires": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "requires": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "requires": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "requires": {} + }, + "postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "requires": {} + }, + "postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "requires": {} + }, + "postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "requires": {} + }, + "postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "requires": { + "postcss-selector-parser": "^6.0.16" + } + }, + "postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "requires": { + "camelcase-css": "^2.0.1" + } + }, + "postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "requires": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "dependencies": { + "lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true + }, + "yaml": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "dev": true + } + } + }, + "postcss-loader": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.3.tgz", + "integrity": "sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA==", + "requires": { + "cosmiconfig": "^8.2.0", + "jiti": "^1.18.2", + "semver": "^7.3.8" + } + }, + "postcss-merge-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", + "requires": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "requires": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + } + }, + "postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "requires": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + } + }, + "postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "requires": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "requires": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "requires": { + "postcss-selector-parser": "^6.0.16" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "requires": {} + }, + "postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.1.1" + } + }, + "postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "requires": {} + }, + "postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "requires": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "requires": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "requires": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-sort-media-queries": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", + "requires": { + "sort-css-media-queries": "2.2.0" + } + }, + "postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "requires": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + } + }, + "postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "requires": { + "postcss-selector-parser": "^6.0.16" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "postcss-zindex": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", + "requires": {} + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "peer": true + }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==" + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "requires": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" + }, + "prism-react-renderer": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.0.tgz", + "integrity": "sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw==", + "requires": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + } + }, + "prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "property-information": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.0.tgz", + "integrity": "sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==" + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + } + } + }, + "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==" + }, + "pupa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", + "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "requires": { + "escape-goat": "^4.0.0" + } + }, + "qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "requires": { + "side-channel": "^1.0.6" + } + }, + "queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "requires": { + "inherits": "~2.0.3" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, + "random-id": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/random-id/-/random-id-0.0.2.tgz", + "integrity": "sha512-e1E0fCzmRQcSxeAFnCybHkVi4filc7c07INtA1BAjKFRfKyO+upZ3q0OhxMnyJ2PRwTSpy/jiMN0ZXwLtyQaBw==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==" + }, + "raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + } + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + } + } + }, + "react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "requires": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { + "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==", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" + }, + "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==", + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "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==", + "requires": { + "p-limit": "^3.0.2" + } + }, + "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==" + }, + "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==" + } + } + }, + "react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + } + }, + "react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "react-helmet-async": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "requires": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + } + }, + "react-icons": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "requires": {} + }, + "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==" + }, + "react-json-view-lite": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", + "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", + "requires": {} + }, + "react-lite-youtube-embed": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-lite-youtube-embed/-/react-lite-youtube-embed-2.4.0.tgz", + "integrity": "sha512-Xo6cM1zPlROvvM97JkqQIoXstlQDaC4+DawmM7BB7Hh1cXrkBHEGq1iJlQxBTUWAUklmpcC7ph7qg7CztXtABQ==", + "requires": {} + }, + "react-loadable": { + "version": "npm:@docusaurus/react-loadable@6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "requires": { + "@types/react": "*" + } + }, + "react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", + "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "requires": { + "@babel/runtime": "^7.10.3" + } + }, + "react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "requires": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, + "react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "requires": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, + "react-simple-chatbot": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/react-simple-chatbot/-/react-simple-chatbot-0.6.1.tgz", + "integrity": "sha512-q9y5GXwBvD+YvLgDVyDuZHYMkrcgIirm1FVV9RkR7XojPmbiX1lCzT6ib8U1M5zh42kTUBRnszXzkAGm9e0K8w==", + "requires": { + "eslint-config-prettier": "^4.1.0", + "eslint-plugin-prettier": "^3.0.1", + "flatted": "^2.0.0", + "onchange": "^5.2.0", + "prettier": "^1.16.4", + "prop-types": "^15.6.0", + "random-id": "0.0.2", + "react": "^16.4.1", + "react-dom": "^16.4.1" + }, + "dependencies": { + "react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } + }, + "react-toastify": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.6.tgz", + "integrity": "sha512-yYjp+omCDf9lhZcrZHKbSq7YMuK0zcYkDFTzfRFgTXkTFHZ1ToxwAonzA4JI5CxA91JpjFLmwEsZEgfYfOqI1A==", + "requires": { + "clsx": "^2.1.0" + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "requires": { + "pify": "^2.3.0" + } + }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "reading-time": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", + "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "requires": { + "minimatch": "^3.0.5" + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, + "regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "requires": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + } + }, + "registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "requires": { + "@pnpm/npm-conf": "^2.1.0" + } + }, + "registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "requires": { + "rc": "1.2.8" + } + }, + "regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" + } + } + }, + "rehype-katex": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", + "requires": { + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + } + }, + "rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "requires": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" + }, + "remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "requires": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + } + }, + "remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "requires": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + } + }, + "remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "requires": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + } + }, + "remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "requires": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + } + }, + "remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "requires": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + } + }, + "remark-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.0.tgz", + "integrity": "sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==", + "requires": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + } + }, + "remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "requires": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + } + }, + "remark-rehype": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.0.0.tgz", + "integrity": "sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==", + "requires": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + } + }, + "remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "requires": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" + }, + "renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "requires": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + } + } + }, + "repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, + "require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "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==" + }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==" + }, + "responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "requires": { + "lowercase-keys": "^3.0.0" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, + "roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "requires": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, + "rtl-detect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", + "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" + }, + "rtlcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + } + }, + "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==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, + "sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "requires": { + "mri": "^1.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, + "scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "search-insights": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", + "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", + "peer": true + }, + "section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "requires": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "requires": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "requires": { + "semver": "^7.3.5" + } + }, + "send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + } + } + }, + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-handler": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "requires": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + }, + "dependencies": { + "path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==" + } + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" + } + } + }, + "serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "requires": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + } + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "requires": { + "kind-of": "^6.0.2" + } + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "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==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "sirv": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", + "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", + "requires": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^3.0.0" + } + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "sitemap": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", + "requires": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "dependencies": { + "@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + } + } + }, + "skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "requires": { + "unicode-emoji-modifier-base": "^1.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "requires": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "sort-css-media-queries": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==" + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" + }, + "source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" + }, + "space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==" + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "std-env": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.5.0.tgz", + "integrity": "sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + } + } + }, + "stringify-entities": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", + "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "requires": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==" + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "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==" + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + }, + "dependencies": { + "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 + } + } + }, + "style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "requires": { + "inline-style-parser": "0.1.1" + } + }, + "styled-components": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz", + "integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@emotion/is-prop-valid": "^0.8.1", + "@emotion/unitless": "^0.7.0", + "babel-plugin-styled-components": ">= 1", + "css-to-react-native": "^2.2.2", + "memoize-one": "^5.0.0", + "merge-anything": "^2.2.4", + "prop-types": "^15.5.4", + "react-is": "^16.6.0", + "stylis": "^3.5.0", + "stylis-rule-sheet": "^0.0.10", + "supports-color": "^5.5.0" + }, + "dependencies": { + "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==" + }, + "stylis": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" + }, + "stylis-rule-sheet": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", + "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==", + "requires": {} + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "requires": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + } + }, + "stylis": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" + }, + "sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "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==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "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==" + }, + "svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + } + } + }, + "swiper": { + "version": "11.1.14", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.1.14.tgz", + "integrity": "sha512-VbQLQXC04io6AoAjIUWuZwW4MSYozkcP9KjLdrsG/00Q/yiwvhz9RQyt0nHXV10hi9NVnDNy1/wv7Dzq1lkOCQ==" + }, + "tailwindcss": { + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", + "dev": true, + "requires": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "dependencies": { + "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, + "requires": { + "is-glob": "^4.0.3" + } + } + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + }, + "terser": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.35.0.tgz", + "integrity": "sha512-TmYbQnzVfrx3RQsPoItoPplymixIAtp2R2xlpyVBYmFmvI34IzLhCLj8SimRb/kZXlq4t1gA+vbcTqLQ3+5Q5g==", + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, + "terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "requires": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "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==" + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "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==" + }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "tinyexec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", + "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==" + }, + "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==" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "requires": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + } + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" + }, + "trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + }, + "dependencies": { + "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 + } + } + }, + "trough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", + "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==" + }, + "ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==" + }, + "ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "peer": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "dependencies": { + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "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==", + "requires": { + "mime-db": "1.52.0" + } + } + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", + "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", + "peer": true + }, + "ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==" + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" + }, + "unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==" + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" + }, + "unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" + }, + "unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "requires": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "requires": { + "crypto-random-string": "^4.0.0" + } + }, + "unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + } + }, + "unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "requires": { + "@types/unist": "^3.0.0" + } + }, + "unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "requires": { + "@types/unist": "^3.0.0" + } + }, + "unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "requires": { + "@types/unist": "^3.0.0" + } + }, + "unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + } + }, + "unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "requires": { + "@types/unist": "^3.0.0" + } + }, + "unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + } + }, + "unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + } + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + }, + "update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "requires": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + } + }, + "update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "requires": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "dependencies": { + "boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "requires": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + } + }, + "camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==" + }, + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==" + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==" + }, + "url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "requires": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, + "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==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "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==", + "requires": { + "mime-db": "1.52.0" + } + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "utility-types": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", + "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "requires": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "dependencies": { + "kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" + } + } + }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + } + }, + "vfile-location": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", + "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "requires": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + } + }, + "vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + } + }, + "vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==" + }, + "vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "requires": { + "vscode-languageserver-protocol": "3.17.5" + } + }, + "vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "requires": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" + }, + "vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + }, + "vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, + "watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==" + }, + "web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, + "webpack": { + "version": "5.95.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", + "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "requires": { + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} + }, + "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==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "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==", + "requires": { + "mime-db": "1.52.0" + } + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "webpack-bundle-analyzer": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", + "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", + "requires": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "is-plain-object": "^5.0.0", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + } + } + }, + "webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "dependencies": { + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "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==", + "requires": { + "mime-db": "1.52.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + } + } + }, + "webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "dependencies": { + "ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "requires": {} + } + } + }, + "webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "requires": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" + }, + "webpackbar": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", + "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", + "requires": { + "chalk": "^4.1.0", + "consola": "^2.15.3", + "pretty-time": "^1.1.0", + "std-env": "^3.0.1" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "requires": { + "string-width": "^5.0.1" + } + }, + "wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" + }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "peer": true + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "requires": {} + }, + "xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==" + }, + "xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "requires": { + "sax": "^1.2.4" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==" + }, + "zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..68521868b --- /dev/null +++ b/package.json @@ -0,0 +1,69 @@ +{ + "name": "algo", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "gh-pages -d build", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids" + }, + "dependencies": { + "@docusaurus/core": "^3.5.2", + "@docusaurus/plugin-content-blog": "^3.5.2", + "@docusaurus/plugin-content-docs": "^3.5.2", + "@docusaurus/plugin-debug": "^3.5.2", + "@docusaurus/preset-classic": "^3.5.2", + "@docusaurus/theme-mermaid": "^3.5.2", + "@docusaurus/theme-search-algolia": "^3.5.2", + "@fortawesome/free-brands-svg-icons": "^6.6.0", + "@fortawesome/react-fontawesome": "^0.2.2", + "@giscus/react": "^3.0.0", + "@heroicons/react": "^2.1.5", + "@mdx-js/react": "^3.0.0", + "axios": "^1.7.7", + "clsx": "^2.0.0", + "framer-motion": "^11.9.0", + "joi": "^17.13.3", + "mermaid": "^11.0.0", + "prism-react-renderer": "^2.1.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "react-icons": "^5.3.0", + "react-lite-youtube-embed": "^2.4.0", + "react-simple-chatbot": "^0.6.0", + "react-toastify": "^10.0.5", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", + "styled-components": "^4.4.1", + "swiper": "^11.1.14" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/types": "3.5.2", + "autoprefixer": "^10.4.20", + "gh-pages": "^6.1.0", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.13" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=18.0" + } +} diff --git a/plugins/my-plugin/index.js b/plugins/my-plugin/index.js new file mode 100644 index 000000000..63612cc0c --- /dev/null +++ b/plugins/my-plugin/index.js @@ -0,0 +1,50 @@ +const Joi = require("joi"); + +module.exports = function (context, options) { + return { + name: "my-plugin", + // lifecycle methods + injectHtmlTags() { + return { + headTags: [ + { + tagName: "meta", + attributes: { + "og:description": "My custom OG: Description", + }, + }, + ], + }; + }, + extendCli(cli) { + cli + .command("my-command action") + .description("This is a custom command") + .action(() => { + console.log("Hello World! - This is a custom command!"); + console.log("Plugin options:", options); + }); + }, + configurePostCss(postcssOptions) { + // Add Tailwind CSS and other PostCSS plugins + postcssOptions.plugins = [ + require("postcss-import"), + require("tailwindcss"), + require("autoprefixer"), + ]; + return postcssOptions; + }, + }; +}; + +module.exports.validateOptions = ({ validate, options }) => { + const joiSchema = Joi.object({ + settings: Joi.string().alphanum().min(3).max(30).required(), + api: Joi.string().required(), + keys: Joi.string().min(2).required(), + }); + + const validateOptions = validate(joiSchema, options); + + return validateOptions; +}; \ No newline at end of file diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000..1c81bef59 --- /dev/null +++ b/renovate.json @@ -0,0 +1,23 @@ +{ + "extends": [ + "config:base", + "config:recommended", + ":dependencyDashboard" + ], + "schedule": [ + "at any time" + ], + "packageRules": [ + { + "packagePatterns": ["*"], + "groupName": "all dependencies", + "groupSlug": "all" + } + ], + "automerge": false, + "automergeType": "pr", + "prHourlyLimit": 24, + "prConcurrentLimit": 10, + "labels": ["dependencies"], + "reviewers": ["Ajay-Dhangar"] + } \ No newline at end of file diff --git a/sidebars.js b/sidebars.js new file mode 100644 index 000000000..332758032 --- /dev/null +++ b/sidebars.js @@ -0,0 +1,33 @@ +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + */ + +// @ts-check + +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const sidebars = { + // By default, Docusaurus generates a sidebar from the docs folder structure + tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], + + // But you can create a sidebar manually + /* + tutorialSidebar: [ + 'intro', + 'hello', + { + type: 'category', + label: 'Tutorial', + items: ['tutorial-basics/create-a-document'], + }, + ], + */ +}; + +export default sidebars; diff --git a/src/components/AdsComponent/Ads.tsx b/src/components/AdsComponent/Ads.tsx new file mode 100644 index 000000000..2869594e3 --- /dev/null +++ b/src/components/AdsComponent/Ads.tsx @@ -0,0 +1,40 @@ +import React, { useEffect } from "react"; +import Head from "@docusaurus/Head"; + +declare global { + interface Window { + adsbygoogle: any[]; + } +} + +const Ads: React.FC = () => { + useEffect(() => { + try { + (window.adsbygoogle = window.adsbygoogle || []).push({}); + } + catch (err) { + console.error(err); + } + }, []); + return ( + <> + + + +
    + + + + +
    + + ); +} diff --git a/src/pages/leaderboard/index.tsx b/src/pages/leaderboard/index.tsx new file mode 100644 index 000000000..cfae2708c --- /dev/null +++ b/src/pages/leaderboard/index.tsx @@ -0,0 +1,67 @@ +import Layout from "@theme/Layout"; +import React from "react"; +import { motion } from "framer-motion"; +import { FaCrown } from "react-icons/fa"; + +const Leaderboard: React.FC = () => { + const leaders = [ + { name: "Ajay Dhangar", points: 1500, rank: 1 }, + { name: "Jane Doe", points: 1450, rank: 2 }, + { name: "John Smith", points: 1420, rank: 3 }, + ]; + + return ( + +
    +
    + + Leaderboard + + + + See where you rank against other coders! + + +
    + + + + + + + + + + {leaders.map((leader) => ( + + + + + + ))} + +
    RankNamePoints
    + {leader.rank === 1 ? ( + + ) : ( + leader.rank + )} + {leader.name}{leader.points}
    +
    +
    +
    +
    + ); +}; + +export default Leaderboard; diff --git a/src/pages/markdown-page.md b/src/pages/markdown-page.md new file mode 100644 index 000000000..9756c5b66 --- /dev/null +++ b/src/pages/markdown-page.md @@ -0,0 +1,7 @@ +--- +title: Markdown page example +--- + +# Markdown page example + +You don't need React to write simple standalone pages. diff --git a/src/pages/practice/index.tsx b/src/pages/practice/index.tsx new file mode 100644 index 000000000..700caae12 --- /dev/null +++ b/src/pages/practice/index.tsx @@ -0,0 +1,228 @@ +import React from "react"; +import { LayoutGroup, motion } from "framer-motion"; +import { FaPlayCircle } from "react-icons/fa"; +import Layout from "@theme/Layout"; + +const Practice: React.FC = () => { + return ( + +
    +
    + + Practice Your Skills + + + + Sharpen your coding skills with hundreds of algorithm problems to practice. + + +
    + {/* Example Practice Problem */} + +

    + Problem 1: Two Sum +

    +

    + Given an array of integers, return indices of the two numbers such that they add up to a specific target. +

    + +
    + + {/* Example Problem 2 */} + +

    + Problem 2: Longest Substring Without Repeating Characters +

    +

    + Find the length of the longest substring without repeating characters. +

    + +
    + + {/* Add more problems as needed */} + + +

    + Problem 2: Add Two Numbers +

    +

    + You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order. +

    + +
    + + +

    + Problem 4: Median of Two Sorted Arrays +

    +

    + Given two sorted arrays, find the median of the two sorted arrays. +

    + +
    + + +

    + Problem 5: Longest Palindromic Substring +

    +

    + Given a string, find the longest palindromic substring in it. +

    + +
    + + +

    + Problem 6: Zigzag Conversion +

    +

    + Convert a string to a zigzag pattern on a given number of rows and read line by line. +

    + +
    + + +

    + Problem 7: Reverse Integer +

    +

    + Given a 32-bit signed integer, reverse its digits. +

    + +
    + + +

    + Problem 8: String to Integer (atoi) +

    +

    + Implement the `atoi` function, which converts a string to an integer. +

    + +
    + + +

    + Problem 9: Palindrome Number +

    +

    + Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward. +

    + +
    + + +

    + Problem 10: Regular Expression Matching +

    +

    + Implement regular expression matching with support for `.` and `*`. +

    + +
    + + +

    + Problem 11: Rotate List +

    +

    + Given the head of a linked list and an integer k, rotate the list to the right by k places. +

    + +
    + +
    +
    +
    +
    + ); +}; + +export default Practice; diff --git a/src/pages/quiz-solutions/array.md b/src/pages/quiz-solutions/array.md new file mode 100644 index 000000000..edfb43741 --- /dev/null +++ b/src/pages/quiz-solutions/array.md @@ -0,0 +1,103 @@ +--- +title: Array Quiz Solutions +hide_table_of_contents: true +--- + +

    Array Quiz Solutions

    + +
    + +### 1. What will the output of the below code? + +```cpp +#include +using namespace std; + +int main() +{ + int arr[2] = { 1, 2 }; + cout << 0[arr] << ", " << 1[arr] << endl; + return 0; +} +``` +- **Options:** + - A) 1, 2 + - B) Syntax error + - C) Run time error + - D) None +- **Answer:** A) 1, 2 + +
    + Explanation: + In C++, array subscripting works in both ways. `arr[0]` is the same as `0[arr]`. Hence, `0[arr]` gives the first element of the array (1), and `1[arr]` gives the second element (2). Therefore, the output is 1, 2. +
    + + + +### 2. The minimum number of comparisons required to determine if an integer appears more than n/2 times in a sorted array of n integers is +- **Options:** + - A) Θ(n) + - B) Θ(logn) + - C) Θ(n*logn) + - D) Θ(1) +- **Answer:** A) Θ(n) + +
    + Explanation: + In a sorted array, once you find a majority element (if it exists), you only need to perform a linear scan to count its occurrences and verify if it appears more than n/2 times. Thus, the minimum number of comparisons is Θ(n). +
    + + + +### 3. An algorithm performs (logN) find operations, N insert operations, (logN) delete operations, and (logN) decrease-key operations on a set of data items with keys drawn from a linearly ordered set. Which one of the following data structures is most suited for the algorithm to achieve the best total asymptotic complexity? +- **Options:** + - A) Unsorted array + - B) Min-heap + - C) Sorted array + - D) Sorted doubly linked list +- **Answer:** B) Min-heap + +
    + Explanation: + Min-heaps are optimal for algorithms that require frequent insertion, deletion, and decrease-key operations. A min-heap supports insertions in O(log N) time and is efficient for find-minimum and delete-minimum operations, making it ideal for this problem. +
    + + + +### 4. Consider a two-dimensional array consisting of –ve and +ve numbers. What would be the worst-case time complexity of an algorithm to segregate the numbers having the same sign altogether? +- **Options:** + - A) O(N) + - B) O(N Log N) + - C) O(N * N) + - D) O(N Log Log N) +- **Answer:** A) O(N) + +
    + Explanation: + This problem can be solved in linear time by using the two-pointer technique, one starting at the beginning and the other at the end. Thus, the worst-case time complexity is O(N). +
    + + + +### 5. Let A[1...n] be an array of n distinct numbers. If i < j and A[i] > A[j], then the pair (i, j) is called an inversion of A. What is the expected number of inversions in any permutation on n elements? +- **Options:** + - A) n(n-1)/2 + - B) n(n-1)/4 + - C) n(n+1)/4 + - D) 2n[logn] +- **Answer:** A) n(n-1)/2 + +
    + Explanation: + An inversion occurs when two elements are out of order. In a worst-case scenario (a completely reverse sorted array), the number of inversions is n(n-1)/2, which is the maximum number of comparisons needed to sort the array. +
    + + + +

    +Now, let's Discuss! +

    + + + +
    \ No newline at end of file diff --git a/src/pages/quiz-solutions/b-trees.md b/src/pages/quiz-solutions/b-trees.md new file mode 100644 index 000000000..595a597a3 --- /dev/null +++ b/src/pages/quiz-solutions/b-trees.md @@ -0,0 +1,172 @@ +--- +title: B-Tree Quiz +hide_table_of_contents: true +--- + +

    B-Tree Quiz Solutions

    + +
    + +### 1. What is a B-Tree? + +- **A)** A binary search tree that is balanced. +- **B)** A tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time. +- **C)** A type of tree that only allows three children per node. +- **D)** A tree used exclusively for storing strings. + +**Solution:** **B)** A tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time. + +
    + Explanation: + A B-Tree is a self-balancing tree data structure that keeps data sorted and allows operations like searching, insertion, and deletion in logarithmic time. It is widely used in database and file systems. +
    + + + +### 2. What is the minimum degree of a B-Tree? + +- **A)** The minimum number of keys a node can contain. +- **B)** The maximum number of children a node can have. +- **C)** The maximum number of keys a node can contain. +- **D)** The number of levels in the tree. + +**Solution:** **A)** The minimum number of keys a node can contain. + +
    + Explanation: + The minimum degree `t` of a B-Tree is the minimum number of keys each node can have, except for the root node. It defines the tree's branching factor. +
    + + + +### 3. In a B-Tree, each node can have a maximum of how many children? + +- **A)** 2 +- **B)** 3 +- **C)** 2t +- **D)** t + +**Solution:** **C)** 2t + +
    + Explanation: + In a B-Tree, each node can have up to `2t` children, where `t` is the minimum degree of the tree. The exact number of children depends on the number of keys in the node. +
    + + + +### 4. What is the main advantage of using a B-Tree over a binary search tree? + +- **A)** Faster search times. +- **B)** Less memory usage. +- **C)** Better balance and reduced height. +- **D)** Simplicity of implementation. + +**Solution:** **C)** Better balance and reduced height. + +
    + Explanation: + The primary advantage of a B-Tree is that it remains balanced, keeping its height minimal, which ensures that the time for insertions, deletions, and searches is kept logarithmic. +
    + + + +### 5. When inserting into a B-Tree, what happens if a node exceeds the maximum number of keys? + +- **A)** The node is deleted. +- **B)** The tree is restructured. +- **C)** The node is split into two nodes. +- **D)** No action is taken. + +**Solution:** **C)** The node is split into two nodes. + +
    + Explanation: + If a node exceeds the maximum allowed number of keys, it is split into two nodes, and the median key is pushed up to the parent node. This ensures the B-Tree remains balanced. +
    + + + +### 6. What does it mean for a B-Tree to be balanced? + +- **A)** All leaves are at the same depth. +- **B)** The number of keys in each node is equal. +- **C)** Each node contains the same number of children. +- **D)** The tree is a complete binary tree. + +**Solution:** **A)** All leaves are at the same depth. + +
    + Explanation: + A B-Tree is balanced because all leaf nodes appear at the same depth, ensuring that the tree's operations are efficient in terms of time complexity. +
    + + + +### 7. How is deletion handled in a B-Tree? + +- **A)** Simply remove the key from the node. +- **B)** Reorganize keys within the node only. +- **C)** It may require borrowing a key from a sibling or merging nodes. +- **D)** Deletion is not allowed in B-Trees. + +**Solution:** **C)** It may require borrowing a key from a sibling or merging nodes. +**Explanation:** Deletion in a B-Tree may lead to an underflow in a node, in which case keys may be borrowed from adjacent sibling nodes or merged with them to maintain the tree structure. + + + +### 8. Which of the following properties is NOT true for B-Trees? + +- **A)** All leaf nodes are at the same level. +- **B)** Each internal node has at least t-1 keys. +- **C)** The root node can have fewer than t keys. +- **D)** Every node can have an arbitrary number of children. + +**Solution:** **D)** Every node can have an arbitrary number of children. + +
    + Explanation: + In a B-Tree, the number of children a node can have is limited by the minimum degree `t`. Each internal node has between `t-1` and `2t-1` keys, but the root node can have fewer than `t` keys. +
    + + + +### 9. In which applications are B-Trees commonly used? + +- **A)** In-memory data structures. +- **B)** File systems and databases. +- **C)** Simple data retrieval tasks. +- **D)** Small data storage. + +**Solution:** **B)** File systems and databases. + +
    + Explanation: + B-Trees are commonly used in file systems and databases due to their ability to handle large amounts of data efficiently and maintain balanced search times. +
    + + + +### 10. What is the relationship between the height of a B-Tree and its order? + +- **A)** The height increases as the order increases. +- **B)** The height decreases as the order increases. +- **C)** The height is independent of the order. +- **D)** The height and order are always equal. + +**Solution:** **B)** The height decreases as the order increases. + +
    + Explanation: + As the order of a B-Tree increases, the number of keys per node increases, which reduces the height of the tree. This relationship helps maintain the tree's balance and efficiency. +
    + + + +

    +Now, let's Discuss! +

    + + + +
    \ No newline at end of file diff --git a/src/pages/quiz-solutions/binary-search-trees.md b/src/pages/quiz-solutions/binary-search-trees.md new file mode 100644 index 000000000..b7d278fd2 --- /dev/null +++ b/src/pages/quiz-solutions/binary-search-trees.md @@ -0,0 +1,111 @@ +# Binary Search Tree Quiz + +## Questions and Solutions + +### 1. What is a binary search tree (BST)? +- **Options:** + - A) A tree where each node has at most two children. + - B) A tree where the left child is greater than the parent. + - C) A tree where the left child is less than the parent and the right child is greater. + - D) A tree where all nodes are on one side. +- **Answer:** C) A tree where the left child is less than the parent and the right child is greater. +- **Explanation:** In a BST, each node's left child is less than the node, and the right child is greater, maintaining the sorted order. + +--- + +### 2. What is the time complexity for searching an element in a balanced binary search tree? +- **Options:** + - A) O(n) + - B) O(log n) + - C) O(n log n) + - D) O(1) +- **Answer:** B) O(log n) +- **Explanation:** In a balanced BST, the height of the tree is log(n), making search operations efficient at O(log n). + +--- + +### 3. Which of the following is true about the in-order traversal of a binary search tree? +- **Options:** + - A) It visits the nodes in descending order. + - B) It visits the nodes in ascending order. + - C) It visits nodes in random order. + - D) It does not visit all nodes. +- **Answer:** B) It visits the nodes in ascending order. +- **Explanation:** In-order traversal of a BST visits nodes in ascending order due to the property of BST. + +--- + +### 4. Which operation in a binary search tree can have a worst-case time complexity of O(n)? +- **Options:** + - A) Insertion + - B) Deletion + - C) Searching + - D) All of the above +- **Answer:** D) All of the above +- **Explanation:** In the worst case, all operations can degrade to O(n) if the tree becomes unbalanced. + +--- + +### 5. What is the maximum number of nodes in a binary search tree with a height of 'h'? +- **Options:** + - A) h + - B) 2^h - 1 + - C) 2^h + - D) h^2 +- **Answer:** B) 2^h - 1 +- **Explanation:** A binary tree with height h can have at most 2^h - 1 nodes, which is full at height h. + +--- + +### 6. Which of the following traversals can be used to get a sorted order of elements in a binary search tree? +- **Options:** + - A) Pre-order + - B) In-order + - C) Post-order + - D) Level-order +- **Answer:** B) In-order +- **Explanation:** In-order traversal yields a sorted order of elements in a BST. + +--- + +### 7. In a binary search tree, what would happen if you tried to insert a duplicate value? +- **Options:** + - A) It will replace the existing value. + - B) It will be ignored. + - C) It will cause an error. + - D) It will create a duplicate node. +- **Answer:** B) It will be ignored. +- **Explanation:** BSTs typically do not allow duplicate values, so the insertion of a duplicate is ignored. + +--- + +### 8. What is the time complexity for finding the lowest common ancestor (LCA) of two nodes in a binary search tree? +- **Options:** + - A) O(n) + - B) O(log n) + - C) O(h) + - D) O(1) +- **Answer:** C) O(h) +- **Explanation:** Finding the LCA can take O(h) time, where h is the height of the tree, depending on the position of the nodes. + +--- + +### 9. Which of the following operations requires tree rotation in a binary search tree? +- **Options:** + - A) Insertion + - B) Deletion + - C) Balancing + - D) Both A and B +- **Answer:** C) Balancing +- **Explanation:** Rotations are needed during insertion and deletion to maintain balance in self-balancing BSTs. + +--- + +### 10. How can you check if a binary tree is a binary search tree? +- **Options:** + - A) By checking if in-order traversal is sorted. + - B) By checking if all nodes have two children. + - C) By checking if all nodes have unique values. + - D) By performing a pre-order traversal. +- **Answer:** A) By checking if in-order traversal is sorted. +- **Explanation:** If the in-order traversal of the tree is sorted, it confirms that the tree is a valid BST. diff --git a/src/pages/quiz-solutions/binary-trees.md b/src/pages/quiz-solutions/binary-trees.md new file mode 100644 index 000000000..b74647646 --- /dev/null +++ b/src/pages/quiz-solutions/binary-trees.md @@ -0,0 +1,89 @@ +# Binary Tree Quiz + +## Questions + +### Easy Questions + +1. **What is the height of a binary tree with a single node?** + - A) 0 + - B) 1 + - C) 2 + - D) Depends on the tree + **Answer:** B) 1 + **Explanation:** The height of a tree is defined as the number of edges on the longest path from the root to a leaf. A single node has height 0, but considering the node itself, the height is 1. + +2. **Which traversal of a binary tree visits nodes in the order: left, root, right?** + - A) Pre-order + - B) In-order + - C) Post-order + - D) Level-order + **Answer:** B) In-order + **Explanation:** In-order traversal visits the left subtree first, then the root node, followed by the right subtree. + +3. **In a binary tree, what is the maximum number of nodes at depth 'd'?** + - A) 2^d + - B) 2^(d+1) - 1 + - C) 2d + - D) d^2 + **Answer:** A) 2^d + **Explanation:** At depth 'd', the maximum number of nodes is \(2^d\) because each level can double the number of nodes of the previous level. + +### Average Questions + +4. **What is the time complexity of searching for an element in a balanced binary search tree?** + - A) O(n) + - B) O(log n) + - C) O(n log n) + - D) O(1) + **Answer:** B) O(log n) + **Explanation:** In a balanced binary search tree, the height is logarithmic with respect to the number of nodes, leading to O(log n) time complexity for search operations. + +5. **Which of the following statements is true about a binary search tree?** + - A) The left subtree of a node contains only nodes with keys less than the node's key. + - B) The right subtree of a node contains only nodes with keys greater than the node's key. + - C) Both A and B. + - D) None of the above. + **Answer:** C) Both A and B. + **Explanation:** A binary search tree maintains the property where the left subtree has nodes with keys less than the parent's key, and the right subtree has nodes with keys greater than the parent's key. + +6. **In a binary tree, which of the following properties is true for a complete binary tree?** + - A) All levels are completely filled except possibly the last level. + - B) All nodes are as far left as possible. + - C) All leaves are at the same level. + - D) A and B. + **Answer:** D) A and B. + **Explanation:** A complete binary tree has all levels fully filled except possibly the last level, which is filled from left to right. + +### Difficult Questions + +7. **What is the maximum depth of a binary tree with 'n' nodes?** + - A) n + - B) log n + - C) n/2 + - D) n - 1 + **Answer:** A) n + **Explanation:** In the worst case (for example, a skewed tree), the maximum depth can be equal to the number of nodes (n). + +8. **Which of the following algorithms can be used to find the lowest common ancestor (LCA) in a binary tree?** + - A) Recursive approach + - B) Iterative approach + - C) Both A and B + - D) None of the above + **Answer:** C) Both A and B + **Explanation:** Both recursive and iterative approaches can be used to find the LCA, depending on the structure and properties of the tree. + +9. **Which of the following traversal methods would give the nodes of a binary tree in descending order?** + - A) In-order traversal + - B) Pre-order traversal + - C) Post-order traversal + - D) Reverse in-order traversal + **Answer:** D) Reverse in-order traversal + **Explanation:** Reverse in-order traversal visits nodes in the order of right subtree, root, and then left subtree, resulting in a descending order. + +10. **What is the worst-case time complexity for inserting an element in a binary search tree?** + - A) O(log n) + - B) O(n) + - C) O(n log n) + - D) O(1) + **Answer:** B) O(n) + **Explanation:** In the worst case, if the tree is skewed, the insertion operation could take O(n) time. diff --git a/src/pages/quiz-solutions/index.tsx b/src/pages/quiz-solutions/index.tsx new file mode 100644 index 000000000..f910a6592 --- /dev/null +++ b/src/pages/quiz-solutions/index.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import Layout from "@theme/Layout"; +import Header from "../../components/Header"; +import QuizCard from "../../components/QuizCard"; +import quizData from "../../data/quizData"; + +const Quizes: React.FC = () => ( + +
    +
    +
    + {quizData.map((quiz, index) => ( + + ))} +
    +
    +
    +); + +export default Quizes; diff --git a/src/pages/quiz-solutions/queues.md b/src/pages/quiz-solutions/queues.md new file mode 100644 index 000000000..870576a38 --- /dev/null +++ b/src/pages/quiz-solutions/queues.md @@ -0,0 +1,162 @@ + +# Queue Quiz + +## 1. Following is C-like pseudo-code of a function that takes a Queue as an argument, and uses a stack S to do processing. + +```c +void fun(Queue *Q) +{ + Stack S; // Say it creates an empty stack S + + // Run while Q is not empty + while (!isEmpty(Q)) + { + // deQueue an item from Q and push the dequeued item to S + push(&S, deQueue(Q)); + } + + // Run while Stack S is not empty + while (!isEmpty(&S)) + { + // Pop an item from S and enqueue the popped item to Q + enQueue(Q, pop(&S)); + } +} +``` + +- **Options:** + - A) Removes the last from Q + - B) Keeps the Q same as it was before the call + - C) Makes Q empty + - D) Reverses the Q + +- **Answer:** D) Reverses the Q + +- **Explanation:** + The function uses a stack to reverse the queue. First, all elements are dequeued from the queue and pushed into the stack. Then, elements are popped from the stack and enqueued back into the queue. Since the stack follows LIFO order, the queue is reversed. + + +## 2. How many stacks are needed to implement a queue? Consider the situation where no other data structure like arrays or linked lists is available to you. + +- **Options:** + - A) 1 + - B) 2 + - C) 3 + - D) 4 + +- **Answer:** B) 2 + +- **Explanation:** + To implement a queue using stacks, two stacks are required. One stack is used for enqueuing elements, and the other is used for dequeuing them. + + +## 3. Which of the following operations on a queue data structure has a time complexity of O(1)? + +- **Options:** + - A) Enqueue + - B) Dequeue + - C) Peek + - D) Clear + +- **Answer:** A and B + +- **Explanation:** + Both enqueue and dequeue operations in a standard queue have a time complexity of O(1) as they involve simple pointer adjustments. + + +## 4. A priority queue can be efficiently implemented using which of the following data structures? + +- **Options:** + - A) Array + - B) Linked List + - C) Heap Data Structures like Binary Heap, Fibonacci Heap + - D) None of the above + +- **Answer:** C) Heap Data Structures like Binary Heap, Fibonacci Heap + +- **Explanation:** + Heaps are the most efficient data structures to implement priority queues as they allow insertion and removal of elements in logarithmic time. + + +## 5. Which of the following is true about linked list implementation of a queue? + +- **Options:** + - A) In push operation, if new nodes are inserted at the beginning of the linked list, then in pop operation, nodes must be removed from the end. + - B) In push operation, if new nodes are inserted at the end, then in pop operation, nodes must be removed from the beginning. + - C) Both of the above + - D) None of the above + +- **Answer:** C) Both of the above + +- **Explanation:** + In a linked list implementation of a queue, nodes can either be inserted at the beginning or end, and the opposite operation should be performed to remove nodes, depending on where the nodes were added. + + +## 6. A Priority-Queue is implemented as a Max-Heap. Initially, it has 5 elements. The level-order traversal of the heap is given below: 10, 8, 5, 3, 2. Two new elements '1' and '7' are inserted in the heap in that order. The level-order traversal of the heap after the insertion of the elements is: + +- **Options:** + - A) 10, 8, 7, 5, 3, 2, 1 + - B) 10, 8, 7, 2, 3, 1, 5 + - C) 10, 8, 7, 1, 2, 3, 5 + - D) 10, 8, 7, 3, 2, 1, 5 + +- **Answer:** A) 10, 8, 7, 5, 3, 2, 1 + +- **Explanation:** + Inserting elements '1' and '7' into the Max-Heap results in the heap structure adjusting such that the maximum element remains at the root. The final level-order traversal after the insertions is 10, 8, 7, 5, 3, 2, 1. + + +## 7. Which of the following is true about the circular queue? + +- **Options:** + - A) It avoids memory wastage compared to the simple linear queue. + - B) It has a fixed size and cannot be dynamically resized. + - C) Dequeue and enqueue operations wrap around at the end. + - D) All of the above + +- **Answer:** D) All of the above + +- **Explanation:** + Circular queues eliminate the problem of unused space in linear queues by wrapping around the enqueue and dequeue operations. It uses fixed-size memory but optimizes the use of available space. + + +## 8. In a circular queue, if `front == rear + 1`, what does it signify? + +- **Options:** + - A) Queue is empty + - B) Queue is full + - C) Queue is circular + - D) Invalid state + +- **Answer:** B) Queue is full + +- **Explanation:** + In a circular queue, the condition `front == rear + 1` indicates that the queue is full because the rear has wrapped around and is just before the front. + + +## 9. What is the time complexity of inserting an element in an unsorted priority queue? + +- **Options:** + - A) O(1) + - B) O(log n) + - C) O(n) + - D) O(n^2) + +- **Answer:** A) O(1) + +- **Explanation:** + Inserting an element into an unsorted priority queue takes constant time because there is no need to maintain order during insertion. However, removal of the highest priority element will take O(n) time. + + +## 10. How is a double-ended queue (Deque) different from a standard queue? + +- **Options:** + - A) It allows insertion and deletion from both ends. + - B) It only allows deletion from one end. + - C) It is always implemented using a circular array. + - D) It has more memory overhead compared to a queue. + +- **Answer:** A) It allows insertion and deletion from both ends. + +- **Explanation:** + A double-ended queue (Deque) is a generalized form of a queue where insertion and deletion operations can be performed at both the front and rear ends. diff --git a/src/pages/quiz-solutions/red-black-trees.md b/src/pages/quiz-solutions/red-black-trees.md new file mode 100644 index 000000000..1009318a5 --- /dev/null +++ b/src/pages/quiz-solutions/red-black-trees.md @@ -0,0 +1,111 @@ +# Red-Black Tree Quiz + +## Questions and Solutions + +### 1. What is a Red-Black Tree? +- **Options:** + - A) A binary search tree with additional color properties. + - B) A tree that only allows red nodes. + - C) A tree where all nodes are black. + - D) A tree with no duplicate values. +- **Answer:** A) A binary search tree with additional color properties. +- **Explanation:** A Red-Black Tree is a binary search tree that follows specific properties to maintain balance, ensuring efficient operations. + +--- + +### 2. What are the two colors used in a Red-Black Tree? +- **Options:** + - A) Red and Blue + - B) Black and White + - C) Red and Black + - D) Green and Yellow +- **Answer:** C) Red and Black +- **Explanation:** Red-Black Trees use two colors (red and black) to maintain balance and ensure that the tree remains approximately balanced. + +--- + +### 3. What is the maximum height of a Red-Black Tree with n nodes? +- **Options:** + - A) O(n) + - B) O(log n) + - C) O(2 log n) + - D) O(sqrt(n)) +- **Answer:** B) O(log n) +- **Explanation:** The maximum height of a Red-Black Tree is O(log n), ensuring that operations like insertion, deletion, and search remain efficient. + +--- + +### 4. Which of the following properties must be true for a Red-Black Tree? +- **Options:** + - A) The root must be red. + - B) Red nodes cannot have red children. + - C) All leaves are red. + - D) Every path from a node to its leaves must have the same number of red nodes. +- **Answer:** B) Red nodes cannot have red children. +- **Explanation:** One of the fundamental properties of Red-Black Trees is that red nodes cannot have red children, which helps maintain balance. + +--- + +### 5. What is the role of rotations in Red-Black Trees? +- **Options:** + - A) To delete nodes. + - B) To maintain the balance of the tree. + - C) To insert nodes. + - D) To traverse the tree. +- **Answer:** B) To maintain the balance of the tree. +- **Explanation:** Rotations are used to restore balance in the tree after insertions and deletions, ensuring the Red-Black properties are maintained. + +--- + +### 6. When a new node is inserted into a Red-Black Tree, what color is it initially? +- **Options:** + - A) Red + - B) Black + - C) Blue + - D) Green +- **Answer:** A) Red +- **Explanation:** Newly inserted nodes in a Red-Black Tree are always colored red to maintain the tree's balance. + +--- + +### 7. In a Red-Black Tree, how do you ensure that the tree remains balanced after an insertion? +- **Options:** + - A) By performing rotations and recoloring nodes. + - B) By deleting the inserted node. + - C) By adjusting the tree's height. + - D) By increasing the tree's depth. +- **Answer:** A) By performing rotations and recoloring nodes. +- **Explanation:** Balancing is achieved through rotations and recoloring, following specific rules based on the colors of the affected nodes. + +--- + +### 8. Which of the following scenarios requires a right rotation in a Red-Black Tree? +- **Options:** + - A) Inserting a red node in the left subtree of a left child. + - B) Inserting a red node in the right subtree of a right child. + - C) Inserting a red node in the right subtree of a left child. + - D) Inserting a black node. +- **Answer:** A) Inserting a red node in the left subtree of a left child. +- **Explanation:** This scenario causes an imbalance that is corrected with a right rotation. + +--- + +### 9. What happens if a Red-Black Tree property is violated during an insertion? +- **Options:** + - A) The tree is deleted. + - B) The tree is rebalanced. + - C) The insertion is aborted. + - D) No action is taken. +- **Answer:** B) The tree is rebalanced. +- **Explanation:** If any property is violated, the tree undergoes rebalancing through rotations and recoloring to restore its properties. + +--- + +### 10. What is the primary advantage of using a Red-Black Tree over a regular Binary Search Tree? +- **Options:** + - A) It requires less memory. + - B) It guarantees O(log n) time complexity for insertions, deletions, and searches. + - C) It can store duplicate values. + - D) It allows for faster traversals. +- **Answer:** B) It guarantees O(log n) time complexity for insertions, deletions, and searches. +- **Explanation:** The balanced nature of Red-Black Trees ensures that operations maintain logarithmic time complexity, making them efficient for dynamic sets. diff --git a/src/pages/quiz-solutions/stack.md b/src/pages/quiz-solutions/stack.md new file mode 100644 index 000000000..0acbd475c --- /dev/null +++ b/src/pages/quiz-solutions/stack.md @@ -0,0 +1,270 @@ + +# Stack Quiz Solutions + +## Question 1 + +**Question:** + +Following is C-like pseudo code of a function that takes a number as an argument, and uses a stack S to do processing. + +```c +void fun(int n) +{ + Stack S; // Say it creates an empty stack S + while (n > 0) + { + push(&S, n%2); + n = n/2; + } + + while (!isEmpty(&S)) + printf("%d ", pop(&S)); +} +``` + +What does the above function do in general? + +**Options:** + +- A) Prints binary representation of n in reverse order +- B) Prints binary representation of n +- C) Prints the value of Logn +- D) Prints the value of Logn in reverse order + +**Answer:** A) Prints binary representation of n in reverse order + +**Explanation:** + +The first loop converts the number `n` to its binary equivalent by repeatedly dividing `n` by 2 and pushing the remainder (which is the binary digit) onto the stack. The second loop pops the stack and prints the binary digits, which results in the binary number being printed in reverse order. + +--- + +## Question 2 + +**Question:** + +Consider the following pseudocode that uses a stack: + +```c +declare a stack of characters +while (there are more characters in the word to read) +{ + read a character + push the character on the stack +} +while (the stack is not empty) +{ + pop a character off the stack + write the character to the screen +} +``` + +What is the output for input "geeksquiz"? + +**Options:** + +- A) geeksquizgeeksquiz +- B) ziuqskeeg +- C) geeksquiz +- D) ziuqskeegziuqskeeg + +**Answer:** B) ziuqskeeg + +**Explanation:** + +The first loop pushes all the characters of the word "geeksquiz" onto the stack. The second loop pops the stack, which reverses the order of the characters, resulting in "ziuqskeeg". + +--- + +## Question 3 + +**Question:** + +Following is an incorrect pseudocode for the algorithm which is supposed to determine whether a sequence of parentheses is balanced: + +```c +declare a character stack +while (more input is available) +{ + read a character + if (the character is a '(' ) + push it on the stack + else if (the character is a ')' and the stack is not empty) + pop a character off the stack + else + print "unbalanced" and exit +} +print "balanced" +``` + +Which of these unbalanced sequences does the above code think is balanced? + +**Options:** + +- A) ((()) +- B) ())(()) +- C) (()()) +- D) (()))() + +**Answer:** D) (()))() + +**Explanation:** + +The code checks if each ')' has a corresponding '(' by using a stack. However, it fails to detect unbalanced sequences like `D) (()))()` because it only checks if the stack is empty at the end, and does not properly handle cases with too many closing parentheses. + +--- + +## Question 4 + +**Question:** + +The following postfix expression with single-digit operands is evaluated using a stack: + +``` +8 2 3 ^ / 2 3 * + 5 1 * - +``` + +The top two elements of the stack after the first `*` is evaluated are: + +**Options:** + +- A) 6, 1 +- B) 5, 7 +- C) 3, 2 +- D) 1, 5 + +**Answer:** A) 6, 1 + +**Explanation:** + +The postfix expression is evaluated from left to right. After the first multiplication operation (`2 * 3`), the top two elements left on the stack are `6` and `1`. + +--- + +## Question 5 + +**Question:** + +A single array `A[1..MAXSIZE]` is used to implement two stacks. The two stacks grow from opposite ends of the array. If the space is to be used efficiently, the condition for “stack full” is: + +**Options:** + +- A) (top1 = MAXSIZE/2) and (top2 = MAXSIZE/2+1) +- B) top1 + top2 + 1 = MAXSIZE +- C) (top1= MAXSIZE/2) or (top2 = MAXSIZE) +- D) top1= top2 -1 + +**Answer:** B) top1 + top2 + 1 = MAXSIZE + +**Explanation:** + +For two stacks growing from opposite ends of the array, the space is fully utilized when the sum of the indices of the top elements of both stacks equals `MAXSIZE - 1`. + +--- + +## Question 6 + +**Question:** + +Assume that the operators `+`, `-`, `×` are left-associative and `^` is right-associative. The order of precedence (from highest to lowest) is `^`, `×`, `+`, `-`. The postfix expression corresponding to the infix expression `a + b × c - d ^ e ^ f` is: + +**Options:** + +- A) `abc × + def ^ ^ -` +- B) `abc × + de ^ f ^ -` +- C) `ab + c × d - e ^ f ^` +- D) `- + a × bc ^ ^ def` + +**Answer:** A) abc × + def ^ ^ - + +**Explanation:** + +Following the operator precedence and associativity rules, the correct postfix expression is `abc × + def ^ ^ -`. + +--- + +## Question 7 + +**Question:** + +The result of evaluating the postfix expression `10 5 + 60 6 / * 8 –` is: + +**Options:** + +- A) 284 +- B) 213 +- C) 142 +- D) 71 + +**Answer:** C) 142 + +**Explanation:** + +Evaluating the postfix expression step by step: +- `10 5 +` → 15 +- `60 6 /` → 10 +- `15 * 10` → 150 +- `150 - 8` → 142 + +--- + +## Question 8 + +**Question:** + +A function `f` defined on stacks of integers satisfies the following properties: `f(∅) = 0` and `f(push(S, i)) = max(f(S), 0) + i` for all stacks `S` and integers `i`. If a stack `S` contains the integers `2, -3, 2, -1, 2` in order from bottom to top, what is `f(S)`? + +**Options:** + +- A) 6 +- B) 4 +- C) 3 +- D) 2 + +**Answer:** A) 6 + +**Explanation:** + +Evaluating the function `f` for each push operation results in the maximum sum being 6. + +--- + +## Question 9 + +**Question:** + +A priority queue `Q` is used to implement a stack `S` that stores characters. `PUSH(C)` is implemented as `INSERT(Q, C, K)` where `K` is an appropriate integer key chosen by the implementation. For a sequence of operations, the keys chosen are in: + +**Options:** + +- A) Non-increasing order +- B) Non-decreasing order +- C) Strictly increasing order +- D) Strictly decreasing order + +**Answer:** C) Strictly increasing order + +**Explanation:** + +For the stack to behave correctly with a priority queue, each push operation should use a key that is strictly greater than the previous one, ensuring the correct order of pop operations. + +--- + +## Question 10 + +**Question:** + +If the sequence of operations - `push(1)`, `push(2)`, `pop`, `push(1)`, `push(2)`, `pop`, `pop`, `pop`, `push(2)`, `pop` are performed on a stack, the sequence of popped out values is: + +**Options:** + +- A) 2,2,1,1,2 +- B) 2,2,1,2,2 +- C) 2,1,2,2,1 +- D) 2,1,2,2,2 + +**Answer:** C) 2,1,2,2,1 + +**Explanation:** + +Following the sequence of operations on the stack, the values are popped in the order `2,1,2,2,1`. diff --git a/src/pages/quizes/arrays.tsx b/src/pages/quizes/arrays.tsx new file mode 100644 index 000000000..31d6b48f0 --- /dev/null +++ b/src/pages/quizes/arrays.tsx @@ -0,0 +1,252 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; + +const ArrayQuiz: React.FC = () => { + const questions = [ + { + question: ( + <> + 1. What will the output of the below code? +
    +            {`#include 
    +using namespace std;
    +
    +int main()
    +{
    +    int arr[2] = { 1, 2 };
    +    cout << 0[arr] << ", " << 1[arr] << endl;
    +    return 0;
    +}`}
    +          
    + + ), + options: ["A) 1, 2", "B) Syntax error", "C) Run time error", "D) None"], + answer: "A) 1, 2", + }, + { + question: ( + <> + 2. What will the output of the below code? +
    +            {`#include 
    +using namespace std;
    +
    +int main()
    +{
    +    int arr[5] = { 1, 2, 3, 4, 5 };
    +    cout << arr[5] << endl;
    +    return 0;
    +}`}
    +          
    + + ), + options: ["A) 5", "B) 0", "C) Garbage value", "D) None"], + answer: "C) Garbage value", + }, + { + question: ( + <> + 3. What will the output of the below code? +
    +            {`#include 
    +using namespace std;
    +
    +int main()
    +{
    +    int arr[5] = { 1, 2, 3, 4, 5 };
    +    cout << arr[4] << endl;
    +    return 0;
    +}`}
    +          
    + + ), + options: ["A) 5", "B) 0", "C) 4", "D) None"], + answer: "A) 5", + }, + { + question: ( + <> + 4. What will the output of the below code? +
    +            {`#include 
    +using namespace std;
    +
    +int main()
    +{
    +    int arr[5] = { 1, 2, 3, 4, 5 };
    +    cout << arr[0] << endl;
    +    return 0;
    +}`}
    +          
    + + ), + options: ["A) 1", "B) 0", "C) 5", "D) None"], + answer: "A) 1", + }, + { + question: ( + <> + 5. What is the time complexity of accessing an element in an array by + its index? + + ), + options: ["A) O(1)", "B) O(n)", "C) O(log n)", "D) O(n^2)"], + answer: "A) O(1)", + }, + { + question: ( + <>6. Which of the following statements is true about arrays in C++? + ), + options: [ + "A) The elements of an array are stored in contiguous memory locations", + "B) The elements of an array are stored in non-contiguous memory locations", + "C) The elements of an array are stored in random memory locations", + "D) None of the above", + ], + answer: + "A) The elements of an array are stored in contiguous memory locations", + }, + { + question: ( + <> + 7. In C++, if an array is declared as int arr[5];, what will be the + default value of its elements? + + ), + options: ["A) 0", "B) 1", "C) Random value", "D) None"], + answer: "A) 0", + }, + { + question: ( + <> + 8. What will be the output of the below code? +
    +            {`#include 
    +using namespace std;
    +
    +int main()
    +{
    +    int arr[5];
    +    cout << arr[0] << endl;
    +    return 0;
    +}`}
    +          
    + + ), + options: ["A) 0", "B) 1", "C) Random value", "D) None"], + answer: "A) 0", + }, + { + question: ( + <> + 9. What will be the output of the below code? +
    +            {`#include 
    +using namespace std;
    +
    +int main()
    +{
    +    int arr[5] = { 1, 2, 3, 4, 5 };
    +    cout << arr << endl;
    +    return 0;
    +}`}
    +          
    + + ), + options: ["A) Address of the first element", "B) 1", "C) 2", "D) None"], + answer: "A) Address of the first element", + }, + ]; + + const [currentQuestion, setCurrentQuestion] = useState(0); + const [score, setScore] = useState(0); + const [showResult, setShowResult] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + const [userAnswers, setUserAnswers] = useState([]); + + const handleAnswer = (selected: string) => { + setSelectedOption(selected); + setUserAnswers((prevAnswers) => [...prevAnswers, selected]); + if (selected === questions[currentQuestion].answer) { + setScore(score + 1); + } + }; + + const nextQuestion = () => { + if (currentQuestion < questions.length - 1) { + setCurrentQuestion(currentQuestion + 1); + setSelectedOption(null); + } else { + setShowResult(true); + } + }; + + return ( + +
    +
    +

    Quiz on Arrays

    + {showResult ? ( +
    +
    +

    + Your Score: {score} 🎉 +

    +

    + {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} +

    +
    + + {/* Solutions Section */} +
    +

    Solutions:

    + {questions.map((q, index) => ( +
    +

    {q.question}

    +

    + Your Answer: {userAnswers[index]} +

    +

    + Correct Answer: {q.answer} +

    +

    + Explanation: {q.explanation} +

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

    + {questions[currentQuestion].question} +

    +
    + {questions[currentQuestion].options.map((option, index) => ( + + ))} +
    + +
    + )} +
    +
    +
    + ); +}; + +export default ArrayQuiz; diff --git a/src/pages/quizes/b-tree.tsx b/src/pages/quizes/b-tree.tsx new file mode 100644 index 000000000..2cdcd554a --- /dev/null +++ b/src/pages/quizes/b-tree.tsx @@ -0,0 +1,203 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; + +const BTree: React.FC = () => { + const questions = [ + { + question: "1. What is a B-Tree?", + options: [ + "A) A binary search tree that is balanced.", + "B) A tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time.", + "C) A type of tree that only allows three children per node.", + "D) A tree used exclusively for storing strings.", + ], + answer: + "B) A tree data structure that maintains sorted data and allows searches, sequential access, insertions, and deletions in logarithmic time.", + }, + { + question: "2. What is the minimum degree of a B-Tree?", + options: [ + "A) The minimum number of keys a node can contain.", + "B) The maximum number of children a node can have.", + "C) The maximum number of keys a node can contain.", + "D) The number of levels in the tree.", + ], + answer: "A) The minimum number of keys a node can contain.", + }, + { + question: + "3. In a B-Tree, each node can have a maximum of how many children?", + options: ["A) 2", "B) 3", "C) 2t", "D) t"], + answer: "C) 2t", + }, + { + question: + "4. What is the main advantage of using a B-Tree over a binary search tree?", + options: [ + "A) Faster search times.", + "B) Less memory usage.", + "C) Better balance and reduced height.", + "D) Simplicity of implementation.", + ], + answer: "C) Better balance and reduced height.", + }, + { + question: + "5. When inserting into a B-Tree, what happens if a node exceeds the maximum number of keys?", + options: [ + "A) The node is deleted.", + "B) The tree is restructured.", + "C) The node is split into two nodes.", + "D) No action is taken.", + ], + answer: "C) The node is split into two nodes.", + }, + { + question: "6. What does it mean for a B-Tree to be balanced?", + options: [ + "A) All leaves are at the same depth.", + "B) The number of keys in each node is equal.", + "C) Each node contains the same number of children.", + "D) The tree is a complete binary tree.", + ], + answer: "A) All leaves are at the same depth.", + }, + { + question: "7. How is deletion handled in a B-Tree?", + options: [ + "A) Simply remove the key from the node.", + "B) Reorganize keys within the node only.", + "C) It may require borrowing a key from a sibling or merging nodes.", + "D) Deletion is not allowed in B-Trees.", + ], + answer: + "C) It may require borrowing a key from a sibling or merging nodes.", + }, + { + question: "8. Which of the following properties is NOT true for B-Trees?", + options: [ + "A) All leaf nodes are at the same level.", + "B) Each internal node has at least t-1 keys.", + "C) The root node can have fewer than t keys.", + "D) Every node can have an arbitrary number of children.", + ], + answer: "D) Every node can have an arbitrary number of children.", + }, + { + question: "9. In which applications are B-Trees commonly used?", + options: [ + "A) In-memory data structures.", + "B) File systems and databases.", + "C) Simple data retrieval tasks.", + "D) Small data storage.", + ], + answer: "B) File systems and databases.", + }, + { + question: + "10. What is the relationship between the height of a B-Tree and its order?", + options: [ + "A) The height increases as the order increases.", + "B) The height decreases as the order increases.", + "C) The height is independent of the order.", + "D) The height and order are always equal.", + ], + answer: "B) The height decreases as the order increases.", + }, + ]; + + const [currentQuestion, setCurrentQuestion] = useState(0); + const [score, setScore] = useState(0); + const [showResult, setShowResult] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + const [userAnswers, setUserAnswers] = useState([]); + + const handleAnswer = (selected: string) => { + setSelectedOption(selected); + setUserAnswers((prevAnswers) => [...prevAnswers, selected]); + if (selected === questions[currentQuestion].answer) { + setScore(score + 1); + } + }; + + const nextQuestion = () => { + if (currentQuestion < questions.length - 1) { + setCurrentQuestion(currentQuestion + 1); + setSelectedOption(null); // Reset selected option for the next question + } else { + setShowResult(true); + } + }; + + return ( + +
    +
    +

    Quiz on B-Trees

    + {showResult ? ( +
    +
    +

    + Your Score: {score} 🎉 +

    +

    + {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} +

    +
    + + {/* Solutions Section */} +
    +

    Solutions:

    + {questions.map((q, index) => ( +
    +

    {q.question}

    +

    + Your Answer: {userAnswers[index]} +

    +

    + Correct Answer: {q.answer} +

    +

    + Explanation: {q.explanation} +

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

    + {questions[currentQuestion].question} +

    +
    + {questions[currentQuestion].options.map((option, index) => ( + + ))} +
    + +
    + )} +
    +
    +
    + ); +}; + +export default BTree; diff --git a/src/pages/quizes/binary-search-tree.tsx b/src/pages/quizes/binary-search-tree.tsx new file mode 100644 index 000000000..ea9dfc62e --- /dev/null +++ b/src/pages/quizes/binary-search-tree.tsx @@ -0,0 +1,118 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; + +const BinarySearchTreeQuiz: React.FC = () => { + const questions = [ + { + question: "1. What is a binary search tree (BST)?", + options: [ + "A) A tree where each node has at most two children.", + "B) A tree where the left child is greater than the parent.", + "C) A tree where the left child is less than the parent and the right child is greater.", + "D) A tree where all nodes are on one side.", + ], + answer: "C) A tree where the left child is less than the parent and the right child is greater.", + explanation: "In a BST, each node's left child is less than the node, and the right child is greater, maintaining the sorted order.", + }, + { + question: "2. What is the time complexity for searching an element in a balanced binary search tree?", + options: ["A) O(n)", "B) O(log n)", "C) O(n log n)", "D) O(1)"], + answer: "B) O(log n)", + explanation: "In a balanced BST, the height of the tree is log(n), making search operations efficient at O(log n).", + }, + // Additional questions... + ]; + + const [currentQuestion, setCurrentQuestion] = useState(0); + const [score, setScore] = useState(0); + const [showResult, setShowResult] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + const [userAnswers, setUserAnswers] = useState([]); + + const handleAnswer = (selected: string) => { + setSelectedOption(selected); + setUserAnswers((prevAnswers) => [...prevAnswers, selected]); + + if (selected === questions[currentQuestion].answer) { + setScore(score + 1); + } + }; + + const nextQuestion = () => { + if (currentQuestion < questions.length - 1) { + setCurrentQuestion(currentQuestion + 1); + setSelectedOption(null); + } else { + setShowResult(true); + } + }; + + return ( + +
    +
    +

    Quiz on Binary Search Trees

    + {showResult ? ( +
    +
    +

    + Your Score: {score} 🎉 +

    +

    + {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} +

    +
    + + {/* Solutions Section */} +
    +

    Solutions:

    + {questions.map((q, index) => ( +
    +

    {q.question}

    +

    + Your Answer: {userAnswers[index]} +

    +

    + Correct Answer: {q.answer} +

    +

    + Explanation: {q.explanation} +

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

    + {questions[currentQuestion].question} +

    +
    + {questions[currentQuestion].options.map((option, index) => ( + + ))} +
    + +
    + )} +
    +
    +
    + ); +}; + +export default BinarySearchTreeQuiz; diff --git a/src/pages/quizes/binary-tree.tsx b/src/pages/quizes/binary-tree.tsx new file mode 100644 index 000000000..56dc5102c --- /dev/null +++ b/src/pages/quizes/binary-tree.tsx @@ -0,0 +1,188 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; + +const BinaryTreeQuiz: React.FC = () => { + const questions = [ + // Easy Questions + { + question: "1. What is the height of a binary tree with a single node?", + options: ["A) 0", "B) 1", "C) 2", "D) Depends on the tree"], + answer: "B) 1", + }, + { + question: + "2. Which traversal of a binary tree visits nodes in the order: left, root, right?", + options: [ + "A) Pre-order", + "B) In-order", + "C) Post-order", + "D) Level-order", + ], + answer: "B) In-order", + }, + { + question: + "3. In a binary tree, what is the maximum number of nodes at depth 'd'?", + options: ["A) 2^d", "B) 2^(d+1) - 1", "C) 2d", "D) d^2"], + answer: "A) 2^d", + }, + // Average Questions + { + question: + "4. What is the time complexity of searching for an element in a balanced binary search tree?", + options: ["A) O(n)", "B) O(log n)", "C) O(n log n)", "D) O(1)"], + answer: "B) O(log n)", + }, + { + question: + "5. Which of the following statements is true about a binary search tree?", + options: [ + "A) The left subtree of a node contains only nodes with keys less than the node's key.", + "B) The right subtree of a node contains only nodes with keys greater than the node's key.", + "C) Both A and B.", + "D) None of the above.", + ], + answer: "C) Both A and B.", + }, + { + question: + "6. In a binary tree, which of the following properties is true for a complete binary tree?", + options: [ + "A) All levels are completely filled except possibly the last level.", + "B) All nodes are as far left as possible.", + "C) All leaves are at the same level.", + "D) A and B.", + ], + answer: "D) A and B.", + }, + // Difficult Questions + { + question: "7. What is the maximum depth of a binary tree with 'n' nodes?", + options: ["A) n", "B) log n", "C) n/2", "D) n - 1"], + answer: "A) n", + }, + { + question: + "8. Which of the following algorithms can be used to find the lowest common ancestor (LCA) in a binary tree?", + options: [ + "A) Recursive approach", + "B) Iterative approach", + "C) Both A and B", + "D) None of the above", + ], + answer: "C) Both A and B", + }, + { + question: + "9. Which of the following traversal methods would give the nodes of a binary tree in descending order?", + options: [ + "A) In-order traversal", + "B) Pre-order traversal", + "C) Post-order traversal", + "D) Reverse in-order traversal", + ], + answer: "D) Reverse in-order traversal", + }, + { + question: + "10. What is the worst-case time complexity for inserting an element in a binary search tree?", + options: ["A) O(log n)", "B) O(n)", "C) O(n log n)", "D) O(1)"], + answer: "B) O(n)", + }, + ]; + + const [currentQuestion, setCurrentQuestion] = useState(0); + const [score, setScore] = useState(0); + const [showResult, setShowResult] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + const [userAnswers, setUserAnswers] = useState([]); + + const handleAnswer = (selected: string) => { + setSelectedOption(selected); + setUserAnswers((prevAnswers) => [...prevAnswers, selected]); + if (selected === questions[currentQuestion].answer) { + setScore(score + 1); + } + }; + + const nextQuestion = () => { + if (currentQuestion < questions.length - 1) { + setCurrentQuestion(currentQuestion + 1); + setSelectedOption(null); + } else { + setShowResult(true); + } + }; + + return ( + +
    +
    +

    Quiz on Binary Tree

    + {showResult ? ( +
    +
    +

    + Your Score: {score} 🎉 +

    +

    + {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} +

    +
    + + {/* Solutions Section */} +
    +

    Solutions:

    + {questions.map((q, index) => ( +
    +

    {q.question}

    +

    + Your Answer: {userAnswers[index]} +

    +

    + Correct Answer: {q.answer} +

    +

    + Explanation: {q.explanation} +

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

    + {questions[currentQuestion].question} +

    +
    + {questions[currentQuestion].options.map((option, index) => ( + + ))} +
    + +
    + )} +
    +
    +
    + ); +}; + +export default BinaryTreeQuiz; diff --git a/src/pages/quizes/index.tsx b/src/pages/quizes/index.tsx new file mode 100644 index 000000000..dc22e2f8a --- /dev/null +++ b/src/pages/quizes/index.tsx @@ -0,0 +1,203 @@ +import React from "react"; +import { LayoutGroup, motion } from "framer-motion"; +import { FaPlayCircle } from "react-icons/fa"; +import Layout from "@theme/Layout"; + +const Quizes: React.FC = () => { + return ( + +
    +
    + + Test Your Data Structures Skills + + + + Sharpen your data structures knowledge with quizzes from basic to advanced topics. + + +
    + {/* Array Quiz Card */} + +

    + Quiz on Arrays +

    +

    + Test your knowledge on array operations and algorithms. +

    + +
    + + {/* Stack Quiz Card */} + +

    + Quiz on Stacks +

    +

    + Evaluate your understanding of stack operations and applications. +

    + +
    + + {/* Queue Quiz Card */} + +

    + Quiz on Queues +

    +

    + Challenge your knowledge on queue implementations and their use cases. +

    + + +
    + + {/* Binary Tree Quiz Card */} + +

    + Quiz on Binary Trees +

    +

    + Test your understanding of Binary Tree structures and traversals. +

    + +
    + + {/* Binary Search Tree Quiz Card */} + +

    + Quiz on Binary Search Trees (BST) +

    +

    + Evaluate your knowledge of Binary Search Tree properties and operations. +

    + +
    + + {/* AVL Tree Quiz Card */} + +

    + Quiz on AVL Trees +

    +

    + Test your skills on the balancing properties of AVL Trees. +

    + +
    + + {/* Red-Black Tree Quiz Card */} + +

    + Quiz on Red-Black Trees +

    +

    + Challenge your understanding of the properties and algorithms of Red-Black Trees. +

    + +
    + + {/* B-Tree Quiz Card */} + +

    + Quiz on B-Trees +

    +

    + Test your understanding of B-Tree properties and their applications. +

    + +
    +
    +
    +
    +
    + ); +}; + +export default Quizes; + diff --git a/src/pages/quizes/queue.tsx b/src/pages/quizes/queue.tsx new file mode 100644 index 000000000..af3fa1bcc --- /dev/null +++ b/src/pages/quizes/queue.tsx @@ -0,0 +1,228 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; + +const QueueQuiz: React.FC = () => { + const questions = [ + { + question: ( + <> + 1. Following is C like pseudo-code of a function that takes a Queue as an argument, and uses a stack S to do processing. +
    +            {`void fun(Queue *Q)
    +{
    +    Stack S;  // Say it creates an empty stack S
    +
    +    // Run while Q is not empty
    +    while (!isEmpty(Q))
    +    {
    +        // deQueue an item from Q and push the dequeued item to S
    +        push(&S, deQueue(Q));
    +    }
    +
    +    // Run while Stack S is not empty
    +    while (!isEmpty(&S))
    +    {
    +      // Pop an item from S and enqueue the popped item to Q
    +      enQueue(Q, pop(&S));
    +    }
    +}`}
    +          
    + + ), + options: [ + "A) Removes the last from Q", + "B) Keeps the Q same as it was before the call", + "C) Makes Q empty", + "D) Reverses the Q" + ], + answer: "D) Reverses the Q", + }, + { + question: "2. How many stacks are needed to implement a queue? Consider the situation where no other data structure like arrays, linked list is available to you.", + options: ["A) 1", "B) 2", "C) 3", "D) 4"], + answer: "B) 2", + }, + { + question: "3. Which of the following operations on a queue data structure has a time complexity of O(1)?", + options: ["A) Enqueue", "B) Dequeue", "C) Peek", "D) Clear"], + answer: "A and B", + }, + { + question: "4. A priority queue can be efficiently implemented using which of the following data structures?", + options: ["A) Array", "B) Linked List", "C) Heap Data Structures like Binary Heap, Fibonacci Heap", "D) None of the above"], + answer: "C) Heap Data Structures like Binary Heap, Fibonacci Heap", + }, + { + question: "5. Which of the following is true about linked list implementation of a queue?", + options: [ + "A) In push operation, if new nodes are inserted at the beginning of linked list, then in pop operation, nodes must be removed from end.", + "B) In push operation, if new nodes are inserted at the end, then in pop operation, nodes must be removed from the beginning.", + "C) Both of the above", + "D) None of the above" + ], + answer: "C) Both of the above", + }, + { + question: "6. A Priority-Queue is implemented as a Max-Heap. Initially, it has 5 elements. The level-order traversal of the heap is given below: 10, 8, 5, 3, 2. Two new elements '1' and '7' are inserted in the heap in that order. The level-order traversal of the heap after the insertion of the elements is:", + options: [ + "A) 10, 8, 7, 5, 3, 2, 1", + "B) 10, 8, 7, 2, 3, 1, 5", + "C) 10, 8, 7, 1, 2, 3, 5", + "D) 10, 8, 7, 3, 2, 1, 5" + ], + answer: "A) 10, 8, 7, 5, 3, 2, 1", + }, + { + question: ( + <> + 7. An implementation of a queue Q, using two stacks S1 and S2, is given below: +
    +            {`void insert(Q, x) {
    +   push(S1, x);
    +}
    + 
    +void delete(Q){
    +   if(stack-empty(S2)) then 
    +      if(stack-empty(S1)) then {
    +          print(“Q is empty”);
    +          return;
    +      }
    +      else while (!(stack-empty(S1))){
    +          x=pop(S1);
    +          push(S2,x);
    +      }
    +   x=pop(S2);
    +}`}
    +          
    + + ), + options: [ + "A) n+m <= x < 2n and 2m <= y <= n+m", + "B) n+m <= x < 2n and 2m <= y <= 2n", + "C) 2m <= x < 2n and 2m <= y <= n+m", + "D) 2m <= x < 2n and 2m <= y <= 2n" + ], + answer: "A) n+m <= x < 2n and 2m <= y <= n+m", + }, + { + question: ( + <> + 8. Consider the following operation along with Enqueue and Dequeue operations on queues, where k is a global parameter. +
    +            {`MultiDequeue(Q){
    +   m = k
    +   while (Q is not empty and m  > 0) {
    +      Dequeue(Q)
    +      m = m - 1
    +   }
    +}`}
    +          
    + What is the worst-case time complexity of a sequence of n MultiDequeue() operations on an initially empty queue? + + ), + options: [ + "A) Θ(n)", + "B) Θ(n + k)", + "C) Θ(nk)", + "D) Θ(n²)" + ], + answer: "B) Θ(n + k)", + }, + { + question: ( + <> + 9. Consider the following pseudo code. Assume that IntQueue is an integer queue. What does the function fun do? +
    +            {`fun(int n)
    +{
    +   IntQueue q = new IntQueue();
    +   q.enqueue(0);
    +   q.enqueue(1);
    +   for (int i = 0; i < n; i++)
    +   {
    +      int a = q.dequeue();
    +      int b = q.dequeue();
    +      q.enqueue(b);
    +      q.enqueue(a + b);
    +      print(a);
    +   }
    +}`}
    +          
    + + ), + options: [ + "A) Prints numbers from 0 to n-1", + "B) Prints numbers from n-1 to 0", + "C) Prints first n Fibonacci numbers", + "D) Prints first n Fibonacci numbers in reverse order" + ], + answer: "C) Prints first n Fibonacci numbers", + }, + { + question: "10. Which of the following is NOT a common operation in a queue data structure?", + options: ["A) Enqueue", "B) Dequeue", "C) Peek", "D) Shuffle"], + answer: "D) Shuffle", + }, + ]; + + const [currentQuestion, setCurrentQuestion] = useState(0); + const [score, setScore] = useState(0); + const [showResult, setShowResult] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + + const handleAnswer = (selected: string) => { + setSelectedOption(selected); + if (selected === questions[currentQuestion].answer) { + setScore(score + 1); + } + }; + + const nextQuestion = () => { + if (currentQuestion < questions.length - 1) { + setCurrentQuestion(currentQuestion + 1); + setSelectedOption(null); // Reset selected option for the next question + } else { + setShowResult(true); + } + }; + + return ( + +
    +

    Quiz on Queues

    + {showResult ? ( +
    +

    Your Score: {score} 🎉

    +

    + {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} +

    +
    + ) : ( +
    +

    {questions[currentQuestion].question}

    +
    + {questions[currentQuestion].options.map((option, index) => ( +
    + handleAnswer(option)} + /> + +
    + ))} +
    + +
    + )} +
    +
    + ); +}; + +export default QueueQuiz; diff --git a/src/pages/quizes/queues.tsx b/src/pages/quizes/queues.tsx new file mode 100644 index 000000000..34cb89d8a --- /dev/null +++ b/src/pages/quizes/queues.tsx @@ -0,0 +1,207 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; + +const QueueQuiz: React.FC = () => { + const questions = [ + // Easy Questions + { + question: "1. What will happen if you try to dequeue an item from an empty queue?", + options: ["A) Returns null", "B) Throws an error", "C) Returns undefined", "D) No operation"], + answer: "B) Throws an error", + }, + { + question: "2. In a circular queue, what is the primary benefit compared to a linear queue?", + options: ["A) More memory usage", "B) Faster access time", "C) Efficient use of space", "D) Simpler implementation"], + answer: "C) Efficient use of space", + }, + { + question: ( + <> + 3. Consider the following operations on a queue: +
    +            {`enqueue(1);
    +enqueue(2);
    +enqueue(3);
    +dequeue();
    +enqueue(4);
    +dequeue();`}
    +          
    + What will be the output of the dequeue operations? + + ), + options: ["A) 1, 2", "B) 1, 3", "C) 2, 4", "D) 3, 4"], + answer: "A) 1, 2", + }, + // Average Questions + { + question: "4. Which data structure is commonly used to implement a queue?", + options: ["A) Array", "B) Linked List", "C) Stack", "D) Both A and B"], + answer: "D) Both A and B", + }, + { + question: "5. What is the time complexity of enqueue and dequeue operations in a linked list-based queue?", + options: ["A) O(1)", "B) O(n)", "C) O(log n)", "D) O(n^2)"], + answer: "A) O(1)", + }, + { + question: "6. In a queue, which operation is used to remove an element from the front?", + options: ["A) push", "B) pop", "C) enqueue", "D) dequeue"], + answer: "D) dequeue", + }, + { + question: ( + <> + 7. Given the following pseudocode for a queue operation: +
    +            {`if (front == -1) {
    +    front = 0;
    +}
    +rear++;
    +queue[rear] = value;`}
    +          
    + What does this pseudocode represent? + + ), + options: [ + "A) Enqueue operation", + "B) Dequeue operation", + "C) Peek operation", + "D) IsEmpty operation", + ], + answer: "A) Enqueue operation", + }, + // Difficult QuestionsclassName="options" + { + question: "8. Which of the following is not a type of queue?", + options: ["A) Simple Queue", "B) Circular Queue", "C) Double-ended Queue", "D) Random Queue"], + answer: "D) Random Queue", + }, + { + question: ( + <> + 9. In a priority queue, elements are dequeued based on: +
    +            {`1. Their position in the queue
    +2. Their priority level`}
    +          
    + Which statement is correct? + + ), + options: [ + "A) Only by position", + "B) Only by priority level", + "C) Both position and priority level", + "D) Neither", + ], + answer: "B) Only by priority level", + }, + { + question: ( + <> + 10. What will be the output of the following queue operations if the initial queue is empty? +
    +            {`enqueue(10);
    +enqueue(20);
    +dequeue();
    +enqueue(30);`}
    +          
    + What will be the current front of the queue? + + ), + options: ["A) 10", "B) 20", "C) 30", "D) Queue is empty"], + answer: "C) 30", + }, + ]; + + const [currentQuestion, setCurrentQuestion] = useState(0); + const [score, setScore] = useState(0); + const [showResult, setShowResult] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + const [userAnswers, setUserAnswers] = useState([]); + + const handleAnswer = (selected: string) => { + setSelectedOption(selected); + setUserAnswers((prevAnswers) => [...prevAnswers, selected]); + if (selected === questions[currentQuestion].answer) { + setScore(score + 1); + } + }; + + const nextQuestion = () => { + if (currentQuestion < questions.length - 1) { + setCurrentQuestion(currentQuestion + 1); + setSelectedOption(null); // Reset selected option for the next question + } else { + setShowResult(true); + } + }; + + return ( + +
    +
    +

    Quiz on Queues

    + {showResult ? ( +
    +
    +

    + Your Score: {score} 🎉 +

    +

    + {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} +

    +
    + + {/* Solutions Section */} +
    +

    Solutions:

    + {questions.map((q, index) => ( +
    +

    {q.question}

    +

    + Your Answer: {userAnswers[index]} +

    +

    + Correct Answer: {q.answer} +

    +

    + Explanation: {q.explanation} +

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

    + {questions[currentQuestion].question} +

    +
    + {questions[currentQuestion].options.map((option, index) => ( + + ))} +
    + +
    + )} +
    +
    +
    + ); +}; + +export default QueueQuiz; diff --git a/src/pages/quizes/red-black-tree.tsx b/src/pages/quizes/red-black-tree.tsx new file mode 100644 index 000000000..5714a52b1 --- /dev/null +++ b/src/pages/quizes/red-black-tree.tsx @@ -0,0 +1,242 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; + +const RedBlackTreeQuiz: React.FC = () => { + const questions = [ + // Easy Questions + { + question: ( + <> + 1. What is a Red-Black Tree? + + ), + options: [ + "A) A binary search tree with additional color properties.", + "B) A tree that only allows red nodes.", + "C) A tree where all nodes are black.", + "D) A tree with no duplicate values.", + ], + answer: "A) A binary search tree with additional color properties.", + }, + { + question: ( + <> + 2. What are the two colors used in a Red-Black Tree? + + ), + options: [ + "A) Red and Blue", + "B) Black and White", + "C) Red and Black", + "D) Green and Yellow", + ], + answer: "C) Red and Black", + }, + { + question: ( + <> + 3. What is the maximum height of a Red-Black Tree with n nodes? + + ), + options: [ + "A) O(n)", + "B) O(log n)", + "C) O(2 log n)", + "D) O(sqrt(n))", + ], + answer: "B) O(log n)", + }, + // Average Questions + { + question: ( + <> + 4. Which of the following properties must be true for a Red-Black Tree? + + ), + options: [ + "A) The root must be red.", + "B) Red nodes cannot have red children.", + "C) All leaves are red.", + "D) Every path from a node to its leaves must have the same number of red nodes.", + ], + answer: "B) Red nodes cannot have red children.", + }, + { + question: ( + <> + 5. What is the role of rotations in Red-Black Trees? + + ), + options: [ + "A) To delete nodes.", + "B) To maintain the balance of the tree.", + "C) To insert nodes.", + "D) To traverse the tree.", + ], + answer: "B) To maintain the balance of the tree.", + }, + { + question: ( + <> + 6. When a new node is inserted into a Red-Black Tree, what color is it initially? + + ), + options: [ + "A) Red", + "B) Black", + "C) Blue", + "D) Green", + ], + answer: "A) Red", + }, + // Difficult Questions + { + question: ( + <> + 7. In a Red-Black Tree, how do you ensure that the tree remains balanced after an insertion? + + ), + options: [ + "A) By performing rotations and recoloring nodes.", + "B) By deleting the inserted node.", + "C) By adjusting the tree's height.", + "D) By increasing the tree's depth.", + ], + answer: "A) By performing rotations and recoloring nodes.", + }, + { + question: ( + <> + 8. Which of the following scenarios requires a right rotation in a Red-Black Tree? + + ), + options: [ + "A) Inserting a red node in the left subtree of a left child.", + "B) Inserting a red node in the right subtree of a right child.", + "C) Inserting a red node in the right subtree of a left child.", + "D) Inserting a black node.", + ], + answer: "A) Inserting a red node in the left subtree of a left child.", + }, + { + question: ( + <> + 9. What happens if a Red-Black Tree property is violated during an insertion? + + ), + options: [ + "A) The tree is deleted.", + "B) The tree is rebalanced.", + "C) The insertion is aborted.", + "D) No action is taken.", + ], + answer: "B) The tree is rebalanced.", + }, + { + question: ( + <> + 10. What is the primary advantage of using a Red-Black Tree over a regular Binary Search Tree? + + ), + options: [ + "A) It requires less memory.", + "B) It guarantees O(log n) time complexity for insertions, deletions, and searches.", + "C) It can store duplicate values.", + "D) It allows for faster traversals.", + ], + answer: "B) It guarantees O(log n) time complexity for insertions, deletions, and searches.", + }, + ]; + + const [currentQuestion, setCurrentQuestion] = useState(0); + const [score, setScore] = useState(0); + const [showResult, setShowResult] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + const [userAnswers, setUserAnswers] = useState([]); + + const handleAnswer = (selected: string) => { + setSelectedOption(selected); + setUserAnswers((prevAnswers) => [...prevAnswers, selected]); + if (selected === questions[currentQuestion].answer) { + setScore(score + 1); + } + }; + + const nextQuestion = () => { + if (currentQuestion < questions.length - 1) { + setCurrentQuestion(currentQuestion + 1); + setSelectedOption(null); // Reset selected option for the next question + } else { + setShowResult(true); + } + }; + + return ( + +
    +
    +

    Quiz on Red-Black Trees

    + {showResult ? ( +
    +
    +

    + Your Score: {score} 🎉 +

    +

    + {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} +

    +
    + + {/* Solutions Section */} +
    +

    Solutions:

    + {questions.map((q, index) => ( +
    +

    {q.question}

    +

    + Your Answer: {userAnswers[index]} +

    +

    + Correct Answer: {q.answer} +

    +

    + Explanation: {q.explanation} +

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

    + {questions[currentQuestion].question} +

    +
    + {questions[currentQuestion].options.map((option, index) => ( + + ))} +
    + +
    + )} +
    +
    +
    + ); +}; + +export default RedBlackTreeQuiz; diff --git a/src/pages/quizes/stack.tsx b/src/pages/quizes/stack.tsx new file mode 100644 index 000000000..415a3f441 --- /dev/null +++ b/src/pages/quizes/stack.tsx @@ -0,0 +1,291 @@ +import React, { useState } from "react"; +import Layout from "@theme/Layout"; + +const StackQuiz: React.FC = () => { + const questions = [ + // Easy Questions + { + question: ( + <> + Following is C like pseudo code of a function that takes a number as an argument, and uses a stack S to do processing. +
    +            {`void fun(int n)
    +{
    +    Stack S;  // Say it creates an empty stack S
    +    while (n > 0)
    +    {
    +      push(&S, n%2);
    +      n = n/2;
    +    }
    +
    +    while (!isEmpty(&S))
    +      printf("%d ", pop(&S));
    +}`}
    +          
    + What does the above function do in general? + + ), + options: [ + "A) Prints binary representation of n in reverse order", + "B) Prints binary representation of n", + "C) Prints the value of Logn", + "D) Prints the value of Logn in reverse order", + ], + answer: "A) Prints binary representation of n in reverse order", + }, + { + question: ( + <> + Consider the following pseudocode that uses a stack: +
    +            {`declare a stack of characters
    +while (there are more characters in the word to read)
    +{
    +    read a character
    +    push the character on the stack
    +}
    +while (the stack is not empty)
    +{
    +    pop a character off the stack
    +    write the character to the screen
    +}`}
    +          
    + What is output for input "geeksquiz"? + + ), + options: [ + "A) geeksquizgeeksquiz", + "B) ziuqskeeg", + "C) geeksquiz", + "D) ziuqskeegziuqskeeg", + ], + answer: "B) ziuqskeeg", + }, + { + question: ( + <> + Following is an incorrect pseudocode for the algorithm which is supposed to determine whether a sequence of parentheses is balanced: +
    +            {`declare a character stack 
    +while (more input is available)
    +{
    +    read a character
    +    if (the character is a '(' ) 
    +        push it on the stack
    +    else if (the character is a ')' and the stack is not empty)
    +        pop a character off the stack
    +    else
    +        print "unbalanced" and exit
    +}
    +print "balanced"`}
    +          
    + Which of these unbalanced sequences does the above code think is balanced? + + ), + options: [ + "A) ((())", + "B) ())(()", + "C) (()())", + "D) (()))()", + ], + answer: "D) (()))()", + }, + // Average Questions + { + question: ( + <> + The following postfix expression with single digit operands is evaluated using a stack: +
    +            {`8 2 3 ^ / 2 3 * + 5 1 * -`}
    +          
    + The top two elements of the stack after the first * is evaluated are: + + ), + options: [ + "A) 6, 1", + "B) 5, 7", + "C) 3, 2", + "D) 1, 5", + ], + answer: "A) 6, 1", + }, + { + question: ( + <> + A single array A[1..MAXSIZE] is used to implement two stacks. The two stacks grow from opposite ends of the array. If the space is to be used efficiently, the condition for “stack full” is: + + ), + options: [ + "A) (top1 = MAXSIZE/2) and (top2 = MAXSIZE/2+1)", + "B) top1 + top2 + 1 = MAXSIZE", + "C) (top1= MAXSIZE/2) or (top2 = MAXSIZE)", + "D) top1= top2 -1", + ], + answer: "B) top1 + top2 + 1 = MAXSIZE", + }, + { + question: ( + <> + Assume that the operators +, -, × are left associative and ^ is right associative. The order of precedence (from highest to lowest) is ^, x , +, -. The postfix expression corresponding to the infix expression a + b × c - d ^ e ^ f is + + ), + options: [ + "A) abc × + def ^ ^ -", + "B) abc × + de ^ f ^ -", + "C) ab + c × d - e ^ f ^", + "D) - + a × bc ^ ^ def", + ], + answer: "A) abc × + def ^ ^ -", + }, + // Difficult Questions + { + question: ( + <> + The result evaluating the postfix expression 10 5 + 60 6 / * 8 – is + + ), + options: [ + "A) 284", + "B) 213", + "C) 142", + "D) 71", + ], + answer: "C) 142", // Removed answer + }, + { + question: ( + <> + A function f defined on stacks of integers satisfies the following properties. f(∅) = 0 and f(push(S, i)) = max(f(S), 0) + i for all stacks S and integers i. + If a stack S contains the integers 2, -3, 2, -1, 2 in order from bottom to top, what is f(S)? + + ), + options: [ + "A) 6", + "B) 4", + "C) 3", + "D) 2", + ], + answer: "A) 6", + }, + { + question: ( + <> + A priority queue Q is used to implement a stack S that stores characters. PUSH(C) is implemented as INSERT(Q, C, K) where K is an appropriate integer key chosen by the implementation. For a sequence of operations, the keys chosen are in + + ), + options: [ + "A) Non-increasing order", + "B) Non-decreasing order", + "C) strictly increasing order", + "D) strictly decreasing order", + ], + answer: "C) strictly increasing order", + }, + { + question: ( + <> + If the sequence of operations - push (1), push (2), pop, push (1), push (2), pop, pop, pop, push (2), pop are performed on a stack, the sequence of popped out values + + ), + options: [ + "A) 2,2,1,1,2", + "B) 2,2,1,2,2", + "C) 2,1,2,2,1", + "D) 2,1,2,2,2", + ], + answer: "C) 2,1,2,2,1", + }, + ]; + + const [currentQuestion, setCurrentQuestion] = useState(0); + const [score, setScore] = useState(0); + const [showResult, setShowResult] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + const [userAnswers, setUserAnswers] = useState([]); + + const handleAnswer = (selected: string) => { + setSelectedOption(selected); + setUserAnswers((prevAnswers) => [...prevAnswers, selected]); + if (selected === questions[currentQuestion].answer) { + setScore(score + 1); + } + }; + + const nextQuestion = () => { + if (currentQuestion < questions.length - 1) { + setCurrentQuestion(currentQuestion + 1); + setSelectedOption(null); // Reset selected option for the next question + } else { + setShowResult(true); + } + }; + + return ( + +
    +
    +

    Quiz on Stack

    + {showResult ? ( +
    +
    +

    + Your Score: {score} 🎉 +

    +

    + {score <= 5 ? "Better luck next time!" : score <= 8 ? "Good job!" : "Excellent work!"} +

    +
    + + {/* Solutions Section */} +
    +

    Solutions:

    + {questions.map((q, index) => ( +
    +

    {q.question}

    +

    + Your Answer: {userAnswers[index]} +

    +

    + Correct Answer: {q.answer} +

    +

    + Explanation: {q.explanation} +

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

    + {questions[currentQuestion].question} +

    +
    + {questions[currentQuestion].options.map((option, index) => ( + + ))} +
    + +
    + )} +
    +
    +
    + ); +}; + +export default StackQuiz; diff --git a/src/pages/resources/index.tsx b/src/pages/resources/index.tsx new file mode 100644 index 000000000..6c7931a77 --- /dev/null +++ b/src/pages/resources/index.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import Layout from "@theme/Layout"; +import { motion } from "framer-motion"; + +const resources = [ + { id: 1, title: "Introduction to Algorithms by CLRS", type: "Book", description: "One of the most comprehensive algorithm books.", link: "https://drive.google.com/file/d/0B3RHrbxFb7PfYjk4ZG01Z3lrbnc/view?resourcekey=0-aHyhqxUeXCNvRK3_QfNurg" }, + { id: 2, title: "LeetCode", type: "Website", description: "A platform for practicing algorithms with real problems.", link: "https://leetcode.com" }, + { id: 3, title: "Coursera: Algorithmic Toolbox", type: "Course", description: "An introductory course for algorithms.", link: "https://www.coursera.org/learn/algorithms-part1" }, + // Add more resources +]; + +const Resources: React.FC = () => { + return ( + +
    + +
    + + ); +}; + +export default Resources; diff --git a/src/pages/roadmap/index.tsx b/src/pages/roadmap/index.tsx new file mode 100644 index 000000000..27e2beea5 --- /dev/null +++ b/src/pages/roadmap/index.tsx @@ -0,0 +1,121 @@ +import React from "react"; +import { motion } from "framer-motion"; +import Layout from "@theme/Layout"; + +interface Milestone { + title: string; + description: string; + status: "planned" | "in-progress" | "completed"; +} + +const milestones: Milestone[] = [ + { + title: "AI and Machine Learning Algorithms", + description: + "Integrate AI and machine learning algorithms to enhance the learning experience and provide advanced problem-solving tools.", + status: "planned", + }, + { + title: "Performance Benchmarking", + description: + "Implement performance benchmarking tools to compare different algorithm implementations across various metrics.", + status: "in-progress", + }, + { + title: "Support for Additional Languages", + description: + "Expand support for more programming languages such as Go, Rust, and Kotlin to cater to a broader developer audience.", + status: "planned", + }, + { + title: "Interactive Visualizations", + description: + "Develop interactive visualizations for algorithm performance and execution flow to aid in deeper understanding.", + status: "planned", + }, + { + title: "Mobile Application", + description: + "Launch a mobile application version of Algo to provide on-the-go access to tutorials, algorithms, and contributions.", + status: "completed", + }, +]; + +const Roadmap: React.FC = () => { + const getStatusColor = (status: string) => { + switch (status) { + case "completed": + return "text-green-500"; + case "in-progress": + return "text-yellow-500"; + case "planned": + return "text-blue-500"; + default: + return "text-gray-500"; + } + }; + + return ( + +
    + {/* Header Section */} +
    + + Our Roadmap + + + Discover the future plans and upcoming features for Algo. + +
    + + {/* Roadmap Items */} +
    + + {milestones.map((milestone, index) => ( + +
    + + • + +
    +
    +

    {milestone.title}

    +

    {milestone.description}

    + + {milestone.status.replace("-", " ")} + +
    +
    + ))} +
    +
    +
    +
    + ); +}; + +export default Roadmap; diff --git a/src/pages/terms/index.tsx b/src/pages/terms/index.tsx new file mode 100644 index 000000000..0dc86446b --- /dev/null +++ b/src/pages/terms/index.tsx @@ -0,0 +1,146 @@ +import React from "react"; +import Layout from "@theme/Layout"; +import { motion } from "framer-motion"; + +const TermsAndConditions: React.FC = () => { + return ( + +
    +
    + + Terms and Conditions + + + Please read these terms and conditions carefully before using our platform. + +
    + +
    + +
    +

    + Acceptance of Terms +

    +

    + By accessing or using our platform, you agree to be bound by these terms and conditions. If you do not agree + with any part of the terms, you must not use the platform. Continued use of the platform following any updates + to these terms will be deemed your acceptance of those changes. +

    +
    + +
    +

    + User Obligations +

    +

    + As a user, you are responsible for maintaining the confidentiality of your account information, including your + password, and for all activities that occur under your account. You agree not to use the platform for any unlawful + purpose or in violation of any applicable laws or regulations. You also agree not to interfere with the security + or performance of the platform or attempt to access unauthorized features. +

    +

    + You further agree that you will not: +

    +
      +
    • Submit false or misleading information.
    • +
    • Use the platform to infringe upon any intellectual property or other rights of third parties.
    • +
    • Engage in any activity that disrupts or interferes with the platform’s functionality.
    • +
    • Distribute viruses or any other harmful technologies.
    • +
    +
    + +
    +

    + Intellectual Property +

    +

    + All content on this platform, including but not limited to text, graphics, logos, icons, and images, is the property + of the platform or its content suppliers and is protected by copyright, trademark, and other intellectual property + laws. You agree not to reproduce, duplicate, copy, sell, or exploit any portion of the platform’s content without + express permission from the owner. +

    +
    + +
    +

    + Disclaimer of Warranties +

    +

    + The platform is provided on an "as-is" and "as-available" basis without any warranties of any kind, either express + or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose, + or non-infringement. We do not guarantee that the platform will be error-free or uninterrupted, nor do we make any + warranties about the results that may be obtained from using the platform. +

    +
    + +
    +

    + Limitation of Liability +

    +

    + In no event will we be liable for any direct, indirect, incidental, consequential, or punitive damages arising out of + or related to your use of the platform, even if we have been advised of the possibility of such damages. You agree + that your sole remedy for dissatisfaction with the platform is to discontinue its use. +

    +
    + +
    +

    + Governing Law and Jurisdiction +

    +

    + These terms and conditions are governed by and construed in accordance with the laws of [Your Jurisdiction]. You + agree to submit to the exclusive jurisdiction of the courts located in [Your Jurisdiction] for any disputes arising + out of or relating to your use of the platform. +

    +
    + +
    +

    + Termination +

    +

    + We reserve the right to terminate or suspend your access to the platform at any time, without notice, for conduct + that we believe violates these terms, is harmful to other users, or is illegal. Upon termination, your right to + use the platform will cease immediately. +

    +
    + +
    +

    + Changes to Terms and Conditions +

    +

    + We reserve the right to modify these terms at any time. Any changes will be effective immediately upon posting. It is + your responsibility to review these terms regularly. Continued use of the platform after changes are posted constitutes + your acceptance of the modified terms. +

    +
    + + +
    +
    +
    +
    + ); +}; + +export default TermsAndConditions; diff --git a/src/theme/Admonition/Icon/Danger.js b/src/theme/Admonition/Icon/Danger.js new file mode 100644 index 000000000..860625339 --- /dev/null +++ b/src/theme/Admonition/Icon/Danger.js @@ -0,0 +1,10 @@ +import React from 'react'; +import Danger from '@theme-original/Admonition/Icon/Danger'; + +export default function DangerWrapper(props) { + return ( + <> + + + ); +} diff --git a/src/theme/Admonition/Layout/index.js b/src/theme/Admonition/Layout/index.js new file mode 100644 index 000000000..161683d47 --- /dev/null +++ b/src/theme/Admonition/Layout/index.js @@ -0,0 +1,10 @@ +import React from 'react'; +import Layout from '@theme-original/Admonition/Layout'; + +export default function LayoutWrapper(props) { + return ( + <> + + + ); +} diff --git a/src/theme/CodeBlock/Line/index.js b/src/theme/CodeBlock/Line/index.js new file mode 100644 index 000000000..f36761806 --- /dev/null +++ b/src/theme/CodeBlock/Line/index.js @@ -0,0 +1,34 @@ +import React from 'react'; +import clsx from 'clsx'; +import styles from './styles.module.css'; +export default function CodeBlockLine({ + line, + classNames, + showLineNumbers, + getLineProps, + getTokenProps, +}) { + if (line.length === 1 && line[0].content === '\n') { + line[0].content = ''; + } + const lineProps = getLineProps({ + line, + className: clsx(classNames, showLineNumbers && styles.codeLine), + }); + const lineTokens = line.map((token, key) => ( + + )); + return ( + + {showLineNumbers ? ( + <> + + {lineTokens} + + ) : ( + lineTokens + )} +
    +
    + ); +} diff --git a/src/theme/CodeBlock/Line/styles.module.css b/src/theme/CodeBlock/Line/styles.module.css new file mode 100644 index 000000000..7c28ed9aa --- /dev/null +++ b/src/theme/CodeBlock/Line/styles.module.css @@ -0,0 +1,45 @@ +/* Intentionally has zero specificity, so that to be able to override +the background in custom CSS file due bug https://github.com/facebook/docusaurus/issues/3678 */ +:where(:root) { + --docusaurus-highlighted-code-line-bg: rgb(72 77 91); +} + +:where([data-theme='dark']) { + --docusaurus-highlighted-code-line-bg: rgb(100 100 100); +} + +:global(.theme-code-block-highlighted-line) { + background-color: var(--docusaurus-highlighted-code-line-bg); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); +} + +.codeLine { + display: table-row; + counter-increment: line-count; +} + +.codeLineNumber { + display: table-cell; + text-align: right; + width: 1%; + position: sticky; + left: 0; + padding: 0 var(--ifm-pre-padding); + background: var(--ifm-pre-background); + overflow-wrap: normal; +} + +.codeLineNumber::before { + content: counter(line-count); + opacity: 0.4; +} + +:global(.theme-code-block-highlighted-line) .codeLineNumber::before { + opacity: 0.8; +} + +.codeLineContent { + padding-right: var(--ifm-pre-padding); +} diff --git a/src/theme/Footer/index.tsx b/src/theme/Footer/index.tsx new file mode 100644 index 000000000..d5c2f6f7e --- /dev/null +++ b/src/theme/Footer/index.tsx @@ -0,0 +1,216 @@ +import React, { useEffect } from "react"; +import { FaGithub, FaLinkedin, FaDiscord, FaTwitter } from "react-icons/fa"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faTwitter } from "@fortawesome/free-brands-svg-icons"; + +import Link from "@docusaurus/Link"; + +const Footer = () => { + useEffect(() => { + // Create script element for GTranslate + const script = document.createElement("script"); + script.src = "https://cdn.gtranslate.net/widgets/latest/popup.js"; + script.defer = true; + document.body.appendChild(script); + + // Set GTranslate settings + window.gtranslateSettings = { + default_language: "en", + detect_browser_language: true, + wrapper_selector: ".gtranslate_wrapper", + }; + + // Cleanup script on component unmount + return () => { + document.body.removeChild(script); + }; + }, []); + + return ( +
    +
    +
    +
    +
    + + Algo Logo + + + Algo + + + +
    + {/*

    Algo

    */} +

    + A platform to learn and practice DSA with a collection of + algorithms and data structures in various languages. +

    +
    +
    + {/* Social Media Links */} +
    + + + + + + + + + + + + + + +
    +
    + + {/* Resources */} +
    +

    Resources

    +
      +
    • + + Documentation + +
    • +
    • + + Blog + +
    • +
    • + + Tutorials + +
    • +
    +
    + + {/* Community */} +
    +

    Community

    +
      +
    • + + Join Discord + +
    • +
    • + + Contributors + +
    • +
    • + + Events + +
    • +
    +
    +
    + + {/* Bottom Section */} +
    +
      +
    • + + Features + +
    • +
    • + + About Us + +
    • +
    • + + Contact + +
    • +
    • + + Privacy Policy + +
    • +
    • +
      +
    • +
    +

    + © {new Date().getFullYear()} Algo, Inc. Built with Docusaurus. +

    +
    +
    +
    + ); +}; + +export default Footer; diff --git a/src/theme/MDXComponents.js b/src/theme/MDXComponents.js new file mode 100644 index 000000000..6c255b0e0 --- /dev/null +++ b/src/theme/MDXComponents.js @@ -0,0 +1,44 @@ +import "react-lite-youtube-embed/dist/LiteYouTubeEmbed.css"; +import AdsComponent from "@site/src/components/AdsComponent"; +// import BrowserWindow from "@site/src/components/BrowserWindow"; +import ArrayVisualizations from "@site/src/components/DSA/arrays/ArrayVisualizations"; +import BubbleSortVisualization from "@site/src/components/DSA/arrays/BubbleSortVisualization"; +import InsertionSortVisualization from "@site/src/components/DSA/arrays/InsertionSortVisualization"; +import QuickSortVisualization from "@site/src/components/DSA/arrays/QuickSortVisualization"; +import HeapSortVisualization from "@site/src/components/DSA/arrays/HeapSortVisualization"; +import SelectionSortVisualization from "@site/src/components/DSA/arrays/SelectionSortVisualization"; +import DijkstraVisuzalizations from "@site/src/components/DSA/graphs/DijkstraVisualizations"; +import FloydWarshallVisualizations from "@site/src/components/DSA/graphs/FloydWarshallVisualizations"; +import Highlight from "@site/src/components/Highlight"; +import MDXComponents from "@theme-original/MDXComponents"; +// import Image from "@theme/IdealImage"; +import TabItem from "@theme/TabItem"; +import Tabs from "@theme/Tabs"; +import { FaReact } from "react-icons/fa"; +import LiteYouTubeEmbed from "react-lite-youtube-embed"; +import GiscusComponent from "../components/GiscusComponent"; +import Ads from "@site/src/components/AdsComponent/Ads"; + +export default { + // Re-use the default mapping + ...MDXComponents, + // custom + Tabs, + TabItem, + Highlight, + ArrayVisualizations, + BubbleSortVisualization, + SelectionSortVisualization, + FaReact, + DijkstraVisuzalizations, + FloydWarshallVisualizations, + InsertionSortVisualization, + QuickSortVisualization, + HeapSortVisualization, +// Image, + LiteYouTubeEmbed, +// LinearSearchVisualizer, + AdsComponent, + GiscusComponent, + Ads, +}; diff --git a/src/theme/Mermaid/index.js b/src/theme/Mermaid/index.js new file mode 100644 index 000000000..543e3848c --- /dev/null +++ b/src/theme/Mermaid/index.js @@ -0,0 +1,10 @@ +import React from 'react'; +import Mermaid from '@theme-original/Mermaid'; + +export default function MermaidWrapper(props) { + return ( + <> + + + ); +} diff --git a/src/theme/ReactLiveScope/components.js b/src/theme/ReactLiveScope/components.js new file mode 100644 index 000000000..98c4bb374 --- /dev/null +++ b/src/theme/ReactLiveScope/components.js @@ -0,0 +1,14 @@ +import React from 'react'; + +export const ButtonExample = (props) => ( +